3 * Copyright (C) 2012 BMW AG
5 * This file is part of GENIVI Project Dlt - Diagnostic Log and Trace console apps.
7 * Contributions are licensed to the GENIVI Alliance under one or more
8 * Contribution License Agreements.
11 * This Source Code Form is subject to the terms of the
12 * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with
13 * this file, You can obtain one at http://mozilla.org/MPL/2.0/.
16 * \author Alexander Wenzel <alexander.aw.wenzel@bmw.de> BMW 2011-2012
19 * For further information see http://www.genivi.org/.
24 /*******************************************************************************
26 ** SRC-MODULE: dlt_user.c **
32 ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de **
39 ** PLATFORM DEPENDANT [yes/no]: yes **
41 ** TO BE CHANGED BY USER [yes/no]: no **
43 *******************************************************************************/
45 /*******************************************************************************
47 ********************************************************************************
49 ** Initials Name Company **
50 ** -------- ------------------------- ---------------------------------- **
51 ** aw Alexander Wenzel BMW **
52 ** mk Markus Klein Fraunhofer ESK **
53 *******************************************************************************/
55 /*******************************************************************************
56 ** Revision Control History **
57 *******************************************************************************/
60 * $LastChangedRevision: 1670 $
61 * $LastChangedDate: 2011-04-08 15:12:06 +0200 (Fr, 08. Apr 2011) $
67 #include <stdlib.h> /* for getenv(), free(), atexit() */
68 #include <string.h> /* for strcmp(), strncmp(), strlen(), memset(), memcpy() */
69 #include <signal.h> /* for signal(), SIGPIPE, SIG_IGN */
71 #if !defined (__WIN32__)
72 #include <syslog.h> /* for LOG_... */
73 #include <semaphore.h>
74 #include <pthread.h> /* POSIX Threads */
81 #include <sys/uio.h> /* writev() */
84 #include "dlt_user_shared.h"
85 #include "dlt_user_shared_cfg.h"
86 #include "dlt_user_cfg.h"
88 static DltUser dlt_user;
89 static int dlt_user_initialised = 0;
91 static char str[DLT_USER_BUFFER_LENGTH];
93 static sem_t dlt_mutex;
94 static pthread_t dlt_receiverthread_handle;
95 static pthread_attr_t dlt_receiverthread_attr;
97 /* Function prototypes for internally used functions */
98 static void dlt_user_receiverthread_function(void *ptr);
99 static void dlt_user_atexit_handler(void);
100 static int dlt_user_log_init(DltContext *handle, DltContextData *log);
101 static int dlt_user_log_send_log(DltContextData *log, int mtype);
102 static int dlt_user_log_send_register_application(void);
103 static int dlt_user_log_send_unregister_application(void);
104 static int dlt_user_log_send_register_context(DltContextData *log);
105 static int dlt_user_log_send_unregister_context(DltContextData *log);
106 static int dlt_send_app_ll_ts_limit(const char *appid, DltLogLevelType loglevel, DltTraceStatusType tracestatus);
107 static int dlt_user_log_send_log_mode(DltUserLogMode mode);
108 static int dlt_user_print_msg(DltMessage *msg, DltContextData *log);
109 static int dlt_user_log_check_user_message(void);
110 static int dlt_user_log_resend_buffer(void);
111 static void dlt_user_log_reattach_to_daemon(void);
112 static int dlt_user_log_send_overflow(void);
114 int dlt_user_check_library_version(const char *user_major_version,const char *user_minor_version){
117 char lib_major_version[DLT_USER_MAX_LIB_VERSION_LENGTH];
118 char lib_minor_version[DLT_USER_MAX_LIB_VERSION_LENGTH];
120 dlt_get_major_version( lib_major_version);
121 dlt_get_minor_version( lib_minor_version);
123 if( (strcmp(lib_major_version,user_major_version)!=0) || (strcmp(lib_minor_version,user_minor_version)!=0))
125 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);
126 dlt_log(LOG_WARNING, str);
134 char filename[DLT_USER_MAX_FILENAME_LENGTH];
137 dlt_user_initialised = 1;
139 /* Initialize common part of dlt_init()/dlt_init_file() */
140 if (dlt_init_common()==-1)
142 dlt_user_initialised = 0;
146 dlt_user.dlt_is_file = 0;
147 dlt_user.overflow = 0;
148 #ifdef DLT_SHM_ENABLE
149 memset(&(dlt_user.dlt_shm),0,sizeof(DltShm));
152 /* create and open DLT user FIFO */
153 sprintf(filename,"%s/dlt%d",DLT_USER_DIR,getpid());
155 /* Try to delete existing pipe, ignore result of unlink */
158 ret=mkfifo(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH );
161 sprintf(str,"Loging disabled, FIFO user %s cannot be created!\n",filename);
162 dlt_log(LOG_WARNING, str);
163 /* return 0; */ /* removed to prevent error, when FIFO already exists */
166 dlt_user.dlt_user_handle = open(filename, O_RDWR | O_CLOEXEC);
167 if (dlt_user.dlt_user_handle == DLT_FD_INIT)
169 sprintf(str,"Loging disabled, FIFO user %s cannot be opened!\n",filename);
170 dlt_log(LOG_WARNING, str);
175 /* open DLT output FIFO */
176 dlt_user.dlt_log_handle = open(DLT_USER_FIFO, O_WRONLY | O_NONBLOCK | O_CLOEXEC );
177 if (dlt_user.dlt_log_handle==-1)
179 sprintf(str,"Loging disabled, FIFO %s cannot be opened with open()!\n",DLT_USER_FIFO);
180 dlt_log(LOG_WARNING, str);
185 #ifdef DLT_SHM_ENABLE
186 /* init shared memory */
187 if (dlt_shm_init_client(&(dlt_user.dlt_shm),DLT_SHM_KEY) < 0)
189 sprintf(str,"Loging disabled, Shared memory %d cannot be created!\n",DLT_SHM_KEY);
190 dlt_log(LOG_WARNING, str);
197 if (dlt_receiver_init(&(dlt_user.receiver),dlt_user.dlt_user_handle, DLT_USER_RCVBUF_MAX_SIZE)==-1)
199 dlt_user_initialised = 0;
203 /* Start receiver thread */
204 if (pthread_create(&(dlt_receiverthread_handle),
206 (void *) &dlt_user_receiverthread_function,
209 if (pthread_attr_destroy(&dlt_receiverthread_attr)!=0)
211 dlt_log(LOG_WARNING, "Can't destroy thread attributes!\n");
214 dlt_log(LOG_CRIT, "Can't create receiver thread!\n");
215 dlt_user_initialised = 0;
219 if (pthread_attr_destroy(&dlt_receiverthread_attr)!=0)
221 dlt_log(LOG_WARNING, "Can't destroy thread attributes!\n");
227 int dlt_init_file(const char *name)
229 dlt_user_initialised = 1;
231 /* Initialize common part of dlt_init()/dlt_init_file() */
232 if (dlt_init_common()==-1)
234 dlt_user_initialised = 0;
238 dlt_user.dlt_is_file = 1;
240 /* open DLT output file */
241 dlt_user.dlt_log_handle = open(name,O_WRONLY|O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); /* mode: wb */
242 if (dlt_user.dlt_log_handle == -1)
244 sprintf(str,"Log file %s cannot be opened!\n",name);
245 dlt_log(LOG_ERR, str);
252 int dlt_init_common(void)
254 char *env_local_print;
256 /* Binary semaphore for threads */
257 if (sem_init(&dlt_mutex, 0, 1)==-1)
259 dlt_user_initialised = 0;
263 /* set to unknown state of connected client */
264 dlt_user.log_state = -1;
266 dlt_user.dlt_log_handle=-1;
267 dlt_user.dlt_user_handle=DLT_FD_INIT;
269 dlt_set_id(dlt_user.ecuID,DLT_USER_DEFAULT_ECU_ID);
270 dlt_set_id(dlt_user.appID,"");
272 dlt_user.application_description = 0;
274 /* Verbose mode is enabled by default */
275 dlt_user.verbose_mode = 1;
277 /* Local print is disabled by default */
278 dlt_user.enable_local_print = 0;
280 dlt_user.local_print_mode = DLT_PM_UNSET;
282 env_local_print = getenv(DLT_USER_ENV_LOCAL_PRINT_MODE);
285 if (strcmp(env_local_print,"AUTOMATIC")==0)
287 dlt_user.local_print_mode = DLT_PM_AUTOMATIC;
289 else if (strcmp(env_local_print,"FORCE_ON")==0)
291 dlt_user.local_print_mode = DLT_PM_FORCE_ON;
293 else if (strcmp(env_local_print,"FORCE_OFF")==0)
295 dlt_user.local_print_mode = DLT_PM_FORCE_OFF;
299 /* Initialize LogLevel/TraceStatus field */
300 dlt_user.dlt_ll_ts = 0;
301 dlt_user.dlt_ll_ts_max_num_entries = 0;
302 dlt_user.dlt_ll_ts_num_entries = 0;
304 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)
306 dlt_user_initialised = 0;
310 signal(SIGPIPE,SIG_IGN); /* ignore pipe signals */
312 atexit(dlt_user_atexit_handler);
314 #ifdef DLT_TEST_ENABLE
315 dlt_user.corrupt_user_header = 0;
316 dlt_user.corrupt_message_size = 0;
317 dlt_user.corrupt_message_size_size = 0;
323 void dlt_user_atexit_handler(void)
326 /* Try to resend potential log messages in the user buffer */
327 int count = dlt_user_atexit_blow_out_user_buffer();
331 sprintf(tmp,"Lost log messages in user buffer when exiting: %i\n",count);
332 dlt_log(LOG_ERR, tmp);
335 /* Unregister app (this also unregisters all contexts in daemon) */
336 /* Ignore return value */
337 dlt_unregister_app();
340 /* Ignore return value */
344 int dlt_user_atexit_blow_out_user_buffer(void){
348 uint32_t exitTime = dlt_uptime() + DLT_USER_ATEXIT_RESEND_BUFFER_EXIT_TIMEOUT;
350 while(dlt_uptime() < exitTime ){
352 ret = dlt_user_log_resend_buffer();
359 usleep(DLT_USER_ATEXIT_RESEND_BUFFER_SLEEP);
363 count = dlt_buffer_get_message_count(&(dlt_user.startup_buffer));
372 char filename[DLT_USER_MAX_FILENAME_LENGTH];
374 if (dlt_user_initialised==0)
379 if (dlt_receiverthread_handle)
381 /* Ignore return value */
382 pthread_cancel(dlt_receiverthread_handle);
385 if (dlt_user.dlt_user_handle!=DLT_FD_INIT)
387 sprintf(filename,"%s/dlt%d",DLT_USER_DIR,getpid());
389 close(dlt_user.dlt_user_handle);
390 dlt_user.dlt_user_handle=DLT_FD_INIT;
395 #ifdef DLT_SHM_ENABLE
396 /* free shared memory */
397 dlt_shm_free_client(&dlt_user.dlt_shm);
400 if (dlt_user.dlt_log_handle!=-1)
402 /* close log file/output fifo to daemon */
403 close(dlt_user.dlt_log_handle);
404 dlt_user.dlt_log_handle = -1;
407 /* Ignore return value */
408 dlt_receiver_free(&(dlt_user.receiver));
410 /* Ignore return value */
411 dlt_buffer_free_dynamic(&(dlt_user.startup_buffer));
413 if (dlt_user.dlt_ll_ts)
415 for (i=0;i<dlt_user.dlt_ll_ts_max_num_entries;i++)
417 if (dlt_user.dlt_ll_ts[i].injection_table!=0)
419 free(dlt_user.dlt_ll_ts[i].injection_table);
420 dlt_user.dlt_ll_ts[i].injection_table = 0;
422 dlt_user.dlt_ll_ts[i].nrcallbacks = 0;
425 free(dlt_user.dlt_ll_ts);
426 dlt_user.dlt_ll_ts = 0;
427 dlt_user.dlt_ll_ts_max_num_entries = 0;
428 dlt_user.dlt_ll_ts_num_entries = 0;
431 dlt_user_initialised = 0;
436 int dlt_check_library_version(const char * user_major_version,const char * user_minor_version)
438 return dlt_user_check_library_version(user_major_version, user_minor_version);
441 int dlt_register_app(const char *appid, const char * description)
445 if (dlt_user_initialised==0)
453 if ((appid==0) || (appid[0]=='\0'))
460 /* Store locally application id and application description */
461 dlt_set_id(dlt_user.appID, appid);
463 if (dlt_user.application_description!=0)
465 free(dlt_user.application_description);
468 dlt_user.application_description = 0;
472 size_t desc_len = strlen(description);
473 dlt_user.application_description= malloc(desc_len+1);
474 if (dlt_user.application_description){
475 strncpy(dlt_user.application_description, description, desc_len);
477 /* Terminate transmitted string with 0 */
478 dlt_user.application_description[desc_len]='\0';
489 ret = dlt_user_log_send_register_application();
493 int dlt_register_context(DltContext *handle, const char *contextid, const char * description)
495 if (dlt_user_initialised==0)
505 if (dlt_user.appID[0]=='\0')
507 dlt_log(LOG_ERR, "no application registered!\n");
513 if ((contextid==0) || (contextid[0]=='\0'))
521 return dlt_register_context_ll_ts(handle, contextid, description, DLT_USER_LOG_LEVEL_NOT_SET, DLT_USER_TRACE_STATUS_NOT_SET);
524 int dlt_register_context_ll_ts(DltContext *handle, const char *contextid, const char * description, int loglevel, int tracestatus)
529 char ctid[DLT_ID_SIZE+1];
531 if (dlt_user_initialised==0)
541 if (dlt_user.appID[0]=='\0')
543 dlt_log(LOG_ERR, "no application registered!\n");
551 if ((contextid==0) || (contextid[0]=='\0'))
556 if ((loglevel<DLT_USER_LOG_LEVEL_NOT_SET) || (loglevel>DLT_LOG_VERBOSE) || (loglevel==DLT_LOG_DEFAULT))
561 if ((tracestatus<DLT_USER_TRACE_STATUS_NOT_SET) || (tracestatus>DLT_TRACE_STATUS_ON) || (tracestatus==DLT_TRACE_STATUS_DEFAULT))
566 if (dlt_user_log_init(handle, &log)==-1)
571 /* Reset message counter */
574 /* Store context id in log level/trace status field */
576 /* Check if already registered, else register context */
580 for (i=0;i<dlt_user.dlt_ll_ts_num_entries;i++)
582 if (dlt_user.dlt_ll_ts)
584 if (memcmp(dlt_user.dlt_ll_ts[i].contextID, contextid,DLT_ID_SIZE)==0)
588 memset(ctid,0,(DLT_ID_SIZE+1));
589 dlt_print_id(ctid, contextid);
591 sprintf(str,"context '%s' already registered!\n",ctid);
592 dlt_log(LOG_WARNING, str);
601 /* Allocate or expand context array */
602 if (dlt_user.dlt_ll_ts == 0)
604 dlt_user.dlt_ll_ts = (dlt_ll_ts_type*) malloc(sizeof(dlt_ll_ts_type)*DLT_USER_CONTEXT_ALLOC_SIZE);
605 if (dlt_user.dlt_ll_ts==0)
611 dlt_user.dlt_ll_ts_max_num_entries = DLT_USER_CONTEXT_ALLOC_SIZE;
613 /* Initialize new entries */
614 for (i=0;i<dlt_user.dlt_ll_ts_max_num_entries;i++)
616 dlt_set_id(dlt_user.dlt_ll_ts[i].contextID,"");
618 /* At startup, logging and tracing is locally enabled */
619 /* the correct log level/status is set after received from daemon */
620 dlt_user.dlt_ll_ts[i].log_level = DLT_USER_INITIAL_LOG_LEVEL;
621 dlt_user.dlt_ll_ts[i].trace_status = DLT_USER_INITIAL_TRACE_STATUS;
623 dlt_user.dlt_ll_ts[i].context_description = 0;
625 dlt_user.dlt_ll_ts[i].injection_table = 0;
626 dlt_user.dlt_ll_ts[i].nrcallbacks = 0;
631 if ((dlt_user.dlt_ll_ts_num_entries%DLT_USER_CONTEXT_ALLOC_SIZE)==0)
633 /* allocate memory in steps of DLT_USER_CONTEXT_ALLOC_SIZE, e.g. 500 */
634 dlt_ll_ts_type *old_ll_ts;
635 uint32_t old_max_entries;
637 old_ll_ts = dlt_user.dlt_ll_ts;
638 old_max_entries = dlt_user.dlt_ll_ts_max_num_entries;
640 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;
641 dlt_user.dlt_ll_ts = (dlt_ll_ts_type*) malloc(sizeof(dlt_ll_ts_type)*
642 dlt_user.dlt_ll_ts_max_num_entries);
643 if (dlt_user.dlt_ll_ts==0)
645 dlt_user.dlt_ll_ts = old_ll_ts;
646 dlt_user.dlt_ll_ts_max_num_entries = old_max_entries;
651 memcpy(dlt_user.dlt_ll_ts,old_ll_ts,sizeof(dlt_ll_ts_type)*dlt_user.dlt_ll_ts_num_entries);
654 /* Initialize new entries */
655 for (i=dlt_user.dlt_ll_ts_num_entries;i<dlt_user.dlt_ll_ts_max_num_entries;i++)
657 dlt_set_id(dlt_user.dlt_ll_ts[i].contextID,"");
659 /* At startup, logging and tracing is locally enabled */
660 /* the correct log level/status is set after received from daemon */
661 dlt_user.dlt_ll_ts[i].log_level = DLT_USER_INITIAL_LOG_LEVEL;
662 dlt_user.dlt_ll_ts[i].trace_status = DLT_USER_INITIAL_TRACE_STATUS;
664 dlt_user.dlt_ll_ts[i].context_description = 0;
666 dlt_user.dlt_ll_ts[i].injection_table = 0;
667 dlt_user.dlt_ll_ts[i].nrcallbacks = 0;
672 /* Store locally context id and context description */
673 dlt_set_id(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].contextID, contextid);
675 if (dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description!=0)
677 free(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description);
680 dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description = 0;
684 size_t desc_len = strlen(description);
685 dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description = malloc(desc_len+1);
686 if(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description == 0)
692 strncpy(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description, description, desc_len);
694 /* Terminate transmitted string with 0 */
695 dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description[desc_len]='\0';
698 if (loglevel!=DLT_USER_LOG_LEVEL_NOT_SET)
700 dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].log_level = loglevel;
703 if (tracestatus!=DLT_USER_TRACE_STATUS_NOT_SET)
705 dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].trace_status = tracestatus;
708 /* Prepare transfer struct */
709 //dlt_set_id(log->appID, dlt_user.appID);
710 dlt_set_id(handle->contextID, contextid);
711 handle->log_level_pos = dlt_user.dlt_ll_ts_num_entries;
713 log.context_description = dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description;
715 if (loglevel!=DLT_USER_LOG_LEVEL_NOT_SET)
717 log.log_level = loglevel;
721 log.log_level = DLT_USER_LOG_LEVEL_NOT_SET;
724 if (tracestatus!=DLT_USER_TRACE_STATUS_NOT_SET)
726 log.trace_status = tracestatus;
730 log.trace_status = DLT_USER_TRACE_STATUS_NOT_SET;
733 dlt_user.dlt_ll_ts_num_entries++;
737 ret=dlt_user_log_send_register_context(&log);
749 int dlt_unregister_app(void)
753 if (dlt_user_initialised==0)
758 /* Inform daemon to unregister application and all of its contexts */
759 ret = dlt_user_log_send_unregister_application();
763 /* Clear and free local stored application information */
764 dlt_set_id(dlt_user.appID, "");
766 if (dlt_user.application_description!=0)
768 free(dlt_user.application_description);
771 dlt_user.application_description = 0;
778 int dlt_unregister_context(DltContext *handle)
783 if (dlt_user_initialised==0)
788 if (dlt_user_log_init(handle, &log) == -1)
795 if (dlt_user.dlt_ll_ts)
797 /* Clear and free local stored context information */
798 dlt_set_id(dlt_user.dlt_ll_ts[handle->log_level_pos].contextID, "");
800 dlt_user.dlt_ll_ts[handle->log_level_pos].log_level = DLT_USER_INITIAL_LOG_LEVEL;
801 dlt_user.dlt_ll_ts[handle->log_level_pos].trace_status = DLT_USER_INITIAL_TRACE_STATUS;
803 if (dlt_user.dlt_ll_ts[handle->log_level_pos].context_description!=0)
805 free(dlt_user.dlt_ll_ts[handle->log_level_pos].context_description);
808 dlt_user.dlt_ll_ts[handle->log_level_pos].context_description = 0;
810 if (dlt_user.dlt_ll_ts[handle->log_level_pos].injection_table)
812 free(dlt_user.dlt_ll_ts[handle->log_level_pos].injection_table);
813 dlt_user.dlt_ll_ts[handle->log_level_pos].injection_table = 0;
816 dlt_user.dlt_ll_ts[handle->log_level_pos].nrcallbacks = 0;
821 /* Inform daemon to unregister context */
822 ret = dlt_user_log_send_unregister_context(&log);
827 int dlt_set_application_ll_ts_limit(DltLogLevelType loglevel, DltTraceStatusType tracestatus)
832 if (dlt_user_initialised==0)
840 /* Removed because of DltLogLevelType and DltTraceStatusType
842 if ((loglevel<DLT_LOG_DEFAULT) || (loglevel>DLT_LOG_VERBOSE))
847 if ((tracestatus<DLT_TRACE_STATUS_DEFAULT) || (tracestatus>DLT_TRACE_STATUS_ON))
852 if (dlt_user.dlt_ll_ts==0)
861 /* Update local structures */
862 for (i=0; i<dlt_user.dlt_ll_ts_num_entries;i++)
864 dlt_user.dlt_ll_ts[i].log_level = loglevel;
865 dlt_user.dlt_ll_ts[i].trace_status = tracestatus;
870 /* Inform DLT server about update */
871 ret = dlt_send_app_ll_ts_limit(dlt_user.appID, loglevel, tracestatus);
876 int dlt_get_log_state()
878 return dlt_user.log_state;
881 int dlt_set_log_mode(DltUserLogMode mode)
883 if (dlt_user_initialised==0)
891 return dlt_user_log_send_log_mode(mode);
894 int dlt_forward_msg(void *msgdata,size_t size)
896 DltUserHeader userheader;
899 if ((msgdata==0) || (size==0))
904 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG)==-1)
906 /* Type of internal user message; same value for Trace messages */
910 if (dlt_user.dlt_is_file)
913 ret = dlt_user_log_out2(dlt_user.dlt_log_handle, msgdata, size, 0, 0);
914 return ((ret==DLT_RETURN_OK)?0:-1);
918 /* Reattach to daemon if neccesary */
919 dlt_user_log_reattach_to_daemon();
921 if (dlt_user.overflow)
923 if (dlt_user_log_send_overflow()==0)
930 ret = dlt_user_log_out3(dlt_user.dlt_log_handle,
931 &(userheader), sizeof(DltUserHeader),
932 msgdata, size, 0, 0);
934 /* store message in ringbuffer, if an error has occured */
935 if (ret!=DLT_RETURN_OK)
939 if (dlt_buffer_push3(&(dlt_user.startup_buffer),
940 (unsigned char *)&(userheader), sizeof(DltUserHeader),
941 msgdata, size, 0, 0)==-1)
943 dlt_log(LOG_ERR,"Storing message to history buffer failed! Message discarded.\n");
951 case DLT_RETURN_PIPE_FULL:
953 /* data could not be written */
954 dlt_user.overflow = 1;
957 case DLT_RETURN_PIPE_ERROR:
959 /* handle not open or pipe error */
960 close(dlt_user.dlt_log_handle);
961 dlt_user.dlt_log_handle = -1;
965 case DLT_RETURN_ERROR:
967 /* other error condition */
976 /* This case should not occur */
985 /* ********************************************************************************************* */
987 inline int dlt_user_log_write_start(DltContext *handle, DltContextData *log,DltLogLevelType loglevel)
989 return dlt_user_log_write_start_id(handle,log,loglevel,DLT_USER_DEFAULT_MSGID);
992 int dlt_user_log_write_start_id(DltContext *handle, DltContextData *log,DltLogLevelType loglevel, uint32_t messageid)
994 if(dlt_user_initialised==0)
1006 if (dlt_user_log_init(handle, log)==-1)
1011 if (dlt_user.dlt_ll_ts==0)
1018 if ((loglevel<=(int)(dlt_user.dlt_ll_ts[handle->log_level_pos].log_level) ) && (loglevel!=0))
1022 log->log_level = loglevel;
1024 /* In non-verbose mode, insert message id */
1025 if (dlt_user.verbose_mode==0)
1027 if ((sizeof(uint32_t))>DLT_USER_BUF_MAX_SIZE)
1031 /* Write message id */
1032 memcpy(log->buffer,&(messageid),sizeof(uint32_t));
1033 log->size = sizeof(uint32_t);
1035 /* as the message id is part of each message in non-verbose mode,
1036 it doesn't increment the argument counter in extended header (if used) */
1050 int dlt_user_log_write_finish(DltContextData *log)
1057 return dlt_user_log_send_log(log, DLT_TYPE_LOG);
1060 int dlt_user_log_write_raw(DltContextData *log,void *data,uint16_t length)
1070 if ((log->size+length+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1075 if (dlt_user.verbose_mode)
1077 if ((log->size+length+sizeof(uint32_t)+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1082 /* Transmit type information */
1083 type_info = DLT_TYPE_INFO_RAWD;
1085 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1086 log->size += sizeof(uint32_t);
1090 /* First transmit length of raw data, then the raw data itself */
1091 arg_size = (uint16_t)length;
1093 memcpy((log->buffer)+log->size,&(arg_size),sizeof(uint16_t));
1094 log->size += sizeof(uint16_t);
1096 memcpy((log->buffer)+log->size,data,arg_size);
1097 log->size += arg_size;
1104 int dlt_user_log_write_float32(DltContextData *log, float32_t data)
1113 if (sizeof(float32_t)!=4)
1118 if ((log->size+sizeof(float32_t))>DLT_USER_BUF_MAX_SIZE)
1123 if (dlt_user.verbose_mode)
1125 if ((log->size+sizeof(uint32_t)+sizeof(float32_t))>DLT_USER_BUF_MAX_SIZE)
1130 type_info = DLT_TYPE_INFO_FLOA | DLT_TYLE_32BIT;
1132 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1133 log->size += sizeof(uint32_t);
1136 memcpy((log->buffer)+log->size,&data, sizeof(float32_t));
1137 log->size += sizeof(float32_t);
1144 int dlt_user_log_write_float64(DltContextData *log, float64_t data)
1153 if (sizeof(float64_t)!=8)
1158 if ((log->size+sizeof(float64_t))>DLT_USER_BUF_MAX_SIZE)
1163 if (dlt_user.verbose_mode)
1165 if ((log->size+sizeof(uint32_t)+sizeof(float64_t))>DLT_USER_BUF_MAX_SIZE)
1170 type_info = DLT_TYPE_INFO_FLOA | DLT_TYLE_64BIT;
1172 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1173 log->size += sizeof(uint32_t);
1176 memcpy((log->buffer)+log->size,&data, sizeof(float64_t));
1177 log->size += sizeof(float64_t);
1184 int dlt_user_log_write_uint( DltContextData *log, unsigned int data)
1191 switch (sizeof(unsigned int))
1195 return dlt_user_log_write_uint8(log, (uint8_t)data);
1200 return dlt_user_log_write_uint16(log, (uint16_t)data);
1205 return dlt_user_log_write_uint32(log, (uint32_t)data);
1210 return dlt_user_log_write_uint64(log, (uint64_t)data);
1223 int dlt_user_log_write_uint8(DltContextData *log, uint8_t data)
1232 if ((log->size+sizeof(uint8_t))>DLT_USER_BUF_MAX_SIZE)
1237 if (dlt_user.verbose_mode)
1239 if ((log->size+sizeof(uint32_t)+sizeof(uint8_t))>DLT_USER_BUF_MAX_SIZE)
1244 type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_8BIT;
1246 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1247 log->size += sizeof(uint32_t);
1250 memcpy((log->buffer)+log->size,&data,sizeof(uint8_t));
1251 log->size += sizeof(uint8_t);
1258 int dlt_user_log_write_uint16(DltContextData *log, uint16_t data)
1267 if ((log->size+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1272 if (dlt_user.verbose_mode)
1274 if ((log->size+sizeof(uint32_t)+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1279 type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_16BIT;
1281 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1282 log->size += sizeof(uint32_t);
1285 memcpy((log->buffer)+log->size,&data,sizeof(uint16_t));
1286 log->size += sizeof(uint16_t);
1293 int dlt_user_log_write_uint32(DltContextData *log, uint32_t data)
1302 if ((log->size+sizeof(uint32_t))>DLT_USER_BUF_MAX_SIZE)
1307 if (dlt_user.verbose_mode)
1309 if ((log->size+sizeof(uint32_t)+sizeof(uint32_t))>DLT_USER_BUF_MAX_SIZE)
1314 type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_32BIT;
1316 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1317 log->size += sizeof(uint32_t);
1320 memcpy((log->buffer)+log->size,&data, sizeof(uint32_t));
1321 log->size += sizeof(uint32_t);
1328 int dlt_user_log_write_uint64(DltContextData *log, uint64_t data)
1337 if ((log->size+sizeof(uint64_t))>DLT_USER_BUF_MAX_SIZE)
1342 if (dlt_user.verbose_mode)
1344 if ((log->size+sizeof(uint32_t)+sizeof(uint64_t))>DLT_USER_BUF_MAX_SIZE)
1349 type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_64BIT;
1351 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1352 log->size +=sizeof(uint32_t);
1355 memcpy((log->buffer)+log->size,&data,sizeof(uint64_t));
1356 log->size += sizeof(uint64_t);
1363 int dlt_user_log_write_int(DltContextData *log, int data)
1370 switch (sizeof(int))
1374 return dlt_user_log_write_int8(log, (int8_t)data);
1379 return dlt_user_log_write_int16(log, (int16_t)data);
1384 return dlt_user_log_write_int32(log, (int32_t)data);
1389 return dlt_user_log_write_int64(log, (int64_t)data);
1402 int dlt_user_log_write_int8(DltContextData *log, int8_t data)
1411 if ((log->size+sizeof(int8_t))>DLT_USER_BUF_MAX_SIZE)
1416 if (dlt_user.verbose_mode)
1418 if ((log->size+sizeof(uint32_t)+sizeof(int8_t))>DLT_USER_BUF_MAX_SIZE)
1423 type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_8BIT;
1425 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1426 log->size += sizeof(uint32_t);
1429 memcpy((log->buffer)+log->size,&data,sizeof(int8_t));
1430 log->size += sizeof(int8_t);
1437 int dlt_user_log_write_int16(DltContextData *log, int16_t data)
1446 if ((log->size+sizeof(int16_t))>DLT_USER_BUF_MAX_SIZE)
1451 if (dlt_user.verbose_mode)
1453 if ((log->size+sizeof(uint32_t)+sizeof(int16_t))>DLT_USER_BUF_MAX_SIZE)
1458 type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_16BIT;
1460 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1461 log->size += sizeof(uint32_t);
1464 memcpy((log->buffer)+log->size,&data,sizeof(int16_t));
1465 log->size += sizeof(int16_t);
1472 int dlt_user_log_write_int32(DltContextData *log, int32_t data)
1481 if ((log->size+sizeof(int32_t))>DLT_USER_BUF_MAX_SIZE)
1486 if (dlt_user.verbose_mode)
1488 if ((log->size+sizeof(uint32_t)+sizeof(int32_t))>DLT_USER_BUF_MAX_SIZE)
1493 type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_32BIT;
1495 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1496 log->size += sizeof(uint32_t);
1499 memcpy((log->buffer)+log->size,&data, sizeof(int32_t));
1500 log->size += sizeof(int32_t);
1507 int dlt_user_log_write_int64(DltContextData *log, int64_t data)
1516 if ((log->size+sizeof(int64_t))>DLT_USER_BUF_MAX_SIZE)
1521 if (dlt_user.verbose_mode)
1523 if ((log->size+sizeof(uint32_t)+sizeof(int64_t))>DLT_USER_BUF_MAX_SIZE)
1528 type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_64BIT;
1530 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1531 log->size += sizeof(uint32_t);
1534 memcpy((log->buffer)+log->size,&data,sizeof(int64_t));
1535 log->size += sizeof(int64_t);
1542 int dlt_user_log_write_bool(DltContextData *log, uint8_t data)
1551 if ((log->size+sizeof(uint8_t))>DLT_USER_BUF_MAX_SIZE)
1556 if (dlt_user.verbose_mode)
1558 if ((log->size+sizeof(uint32_t)+sizeof(uint8_t))>DLT_USER_BUF_MAX_SIZE)
1563 type_info = DLT_TYPE_INFO_BOOL;
1565 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1566 log->size += sizeof(uint32_t);
1569 memcpy((log->buffer)+log->size,&data,sizeof(uint8_t));
1570 log->size += sizeof(uint8_t);
1577 int dlt_user_log_write_string(DltContextData *log, const char *text)
1582 if ((log==0) || (text==0))
1587 if ((log->size+(strlen(text)+1)+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1592 if (dlt_user.verbose_mode)
1594 if ((log->size+(strlen(text)+1)+sizeof(uint32_t)+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1599 type_info = DLT_TYPE_INFO_STRG;
1601 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1602 log->size += sizeof(uint32_t);
1605 arg_size = strlen(text) + 1;
1607 memcpy((log->buffer)+log->size,&(arg_size),sizeof(uint16_t));
1608 log->size += sizeof(uint16_t);
1610 memcpy((log->buffer)+log->size,text,arg_size);
1611 log->size += arg_size;
1618 int dlt_register_injection_callback(DltContext *handle, uint32_t service_id,
1619 int (*dlt_injection_callback)(uint32_t service_id, void *data, uint32_t length))
1625 DltUserInjectionCallback *old;
1632 if (dlt_user_log_init(handle, &log)==-1)
1637 if (service_id<DLT_USER_INJECTION_MIN)
1641 /* This function doesn't make sense storing to local file is choosen;
1642 so terminate this function */
1643 if (dlt_user.dlt_is_file)
1650 if (dlt_user.dlt_ll_ts==0)
1656 /* Insert callback in corresponding table */
1657 i=handle->log_level_pos;
1659 /* Insert each service_id only once */
1660 for (k=0;k<dlt_user.dlt_ll_ts[i].nrcallbacks;k++)
1662 if ((dlt_user.dlt_ll_ts[i].injection_table) &&
1663 (dlt_user.dlt_ll_ts[i].injection_table[k].service_id == service_id))
1676 j=dlt_user.dlt_ll_ts[i].nrcallbacks;
1678 /* Allocate or expand injection table */
1679 if (dlt_user.dlt_ll_ts[i].injection_table == 0)
1681 dlt_user.dlt_ll_ts[i].injection_table = (DltUserInjectionCallback*) malloc(sizeof(DltUserInjectionCallback));
1682 if(dlt_user.dlt_ll_ts[i].injection_table == 0)
1690 old = dlt_user.dlt_ll_ts[i].injection_table;
1691 dlt_user.dlt_ll_ts[i].injection_table = (DltUserInjectionCallback*) malloc(sizeof(DltUserInjectionCallback)*(j+1));
1692 if(dlt_user.dlt_ll_ts[i].injection_table == 0)
1694 dlt_user.dlt_ll_ts[i].injection_table = old;
1698 memcpy(dlt_user.dlt_ll_ts[i].injection_table,old,sizeof(DltUserInjectionCallback)*j);
1702 dlt_user.dlt_ll_ts[i].nrcallbacks++;
1705 /* Store service_id and corresponding function pointer for callback function */
1706 dlt_user.dlt_ll_ts[i].injection_table[j].service_id = service_id;
1707 dlt_user.dlt_ll_ts[i].injection_table[j].injection_callback = dlt_injection_callback;
1713 int dlt_user_trace_network(DltContext *handle, DltNetworkTraceType nw_trace_type, uint16_t header_len, void *header, uint16_t payload_len, void *payload)
1717 if (dlt_user_initialised==0)
1725 if (dlt_user_log_init(handle, &log)==-1)
1735 /* Commented out because of DltNetworkTraceType:
1737 if ((nw_trace_type<=0) || (nw_trace_type>0x15))
1746 if (dlt_user.dlt_ll_ts==0)
1752 if (dlt_user.dlt_ll_ts[handle->log_level_pos].trace_status==DLT_TRACE_STATUS_ON)
1757 log.trace_status = nw_trace_type;
1765 /* Write header and its length */
1766 if (dlt_user_log_write_raw(&log, header, header_len)==-1)
1776 /* Write payload and its length */
1777 if (dlt_user_log_write_raw(&log, payload, payload_len)==-1)
1783 return dlt_user_log_send_log(&log, DLT_TYPE_NW_TRACE);
1793 int dlt_log_string(DltContext *handle,DltLogLevelType loglevel, const char *text)
1797 if (dlt_user.verbose_mode==0)
1802 if ((handle==0) || (text==0))
1807 if (dlt_user_log_write_start(handle,&log,loglevel)>0)
1809 if (dlt_user_log_write_string(&log,text)==-1)
1813 if (dlt_user_log_write_finish(&log)==-1)
1822 int dlt_log_string_int(DltContext *handle,DltLogLevelType loglevel, const char *text, int data)
1826 if (dlt_user.verbose_mode==0)
1831 if ((handle==0) || (text==0))
1836 if (dlt_user_log_write_start(handle,&log,loglevel)>0)
1838 if (dlt_user_log_write_string(&log,text)==-1)
1842 if (dlt_user_log_write_int(&log,data)==-1)
1846 if (dlt_user_log_write_finish(&log)==-1)
1855 int dlt_log_string_uint(DltContext *handle,DltLogLevelType loglevel, const char *text, unsigned int data)
1859 if (dlt_user.verbose_mode==0)
1864 if ((handle==0) || (text==0))
1869 if (dlt_user_log_write_start(handle,&log,loglevel)>0)
1871 if (dlt_user_log_write_string(&log,text)==-1)
1875 if (dlt_user_log_write_uint(&log,data)==-1)
1879 if (dlt_user_log_write_finish(&log)==-1)
1888 int dlt_log_int(DltContext *handle,DltLogLevelType loglevel, int data)
1892 if (dlt_user.verbose_mode==0)
1902 if (dlt_user_log_write_start(handle,&log,loglevel)>0)
1904 if (dlt_user_log_write_int(&log,data)==-1)
1908 if (dlt_user_log_write_finish(&log)==-1)
1917 int dlt_log_uint(DltContext *handle,DltLogLevelType loglevel, unsigned int data)
1921 if (dlt_user.verbose_mode==0)
1931 if (dlt_user_log_write_start(handle,&log,loglevel)>0)
1933 if (dlt_user_log_write_uint(&log,data)==-1)
1937 if (dlt_user_log_write_finish(&log)==-1)
1946 int dlt_log_raw(DltContext *handle,DltLogLevelType loglevel, void *data,uint16_t length)
1950 if (dlt_user.verbose_mode==0)
1960 if (dlt_user_log_write_start(handle,&log,loglevel)>0)
1962 if (dlt_user_log_write_raw(&log,data,length)==-1)
1966 if (dlt_user_log_write_finish(&log)==-1)
1975 int dlt_verbose_mode(void)
1977 if (dlt_user_initialised==0)
1985 /* Switch to verbose mode */
1986 dlt_user.verbose_mode = 1;
1991 int dlt_nonverbose_mode(void)
1993 if (dlt_user_initialised==0)
2001 /* Switch to non-verbose mode */
2002 dlt_user.verbose_mode = 0;
2007 int dlt_enable_local_print(void)
2009 if (dlt_user_initialised==0)
2017 dlt_user.enable_local_print = 1;
2022 int dlt_disable_local_print(void)
2024 if (dlt_user_initialised==0)
2032 dlt_user.enable_local_print = 0;
2037 void dlt_user_receiverthread_function(void *ptr)
2041 /* Check for new messages from DLT daemon */
2042 if (dlt_user_log_check_user_message()==-1)
2044 /* Critical error */
2045 dlt_log(LOG_CRIT,"Receiver thread encountered error condition\n");
2048 usleep(DLT_USER_RECEIVE_DELAY); /* delay */
2052 /* Private functions of user library */
2054 int dlt_user_log_init(DltContext *handle, DltContextData *log)
2056 if (dlt_user_initialised==0)
2064 log->handle = handle;
2069 int dlt_user_log_send_log(DltContextData *log, int mtype)
2072 DltUserHeader userheader;
2075 DltReturnValue ret = 0;
2087 if (dlt_user.appID[0]=='\0')
2092 if (log->handle->contextID[0]=='\0')
2097 if ((mtype<DLT_TYPE_LOG) || (mtype>DLT_TYPE_CONTROL))
2102 /* also for Trace messages */
2103 #ifdef DLT_SHM_ENABLE
2104 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG_SHM)==-1)
2106 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG)==-1)
2112 if (dlt_message_init(&msg,0)==-1)
2117 msg.storageheader = (DltStorageHeader*)msg.headerbuffer;
2119 if (dlt_set_storageheader(msg.storageheader,dlt_user.ecuID)==-1)
2124 msg.standardheader = (DltStandardHeader*)(msg.headerbuffer + sizeof(DltStorageHeader));
2125 msg.standardheader->htyp = DLT_HTYP_WEID | DLT_HTYP_WTMS | DLT_HTYP_PROTOCOL_VERSION1 ;
2127 if (dlt_user.verbose_mode)
2129 /* In verbose mode, send extended header */
2130 msg.standardheader->htyp = (msg.standardheader->htyp | DLT_HTYP_UEH );
2134 /* In non-verbose, send extended header if desired */
2135 #if (DLT_USER_USE_EXTENDED_HEADER_FOR_NONVERBOSE==1)
2136 msg.standardheader->htyp = (msg.standardheader->htyp | DLT_HTYP_UEH );
2140 #if (BYTE_ORDER==BIG_ENDIAN)
2141 msg.standardheader->htyp = (msg.standardheader->htyp | DLT_HTYP_MSBF);
2144 msg.standardheader->mcnt = log->handle->mcnt++;
2146 /* Set header extra parameters */
2147 dlt_set_id(msg.headerextra.ecu,dlt_user.ecuID);
2148 //msg.headerextra.seid = 0;
2149 msg.headerextra.tmsp = dlt_uptime();
2151 if (dlt_message_set_extraparameters(&msg,0)==-1)
2156 /* Fill out extended header, if extended header should be provided */
2157 if (DLT_IS_HTYP_UEH(msg.standardheader->htyp))
2159 /* with extended header */
2160 msg.extendedheader = (DltExtendedHeader*)(msg.headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp) );
2166 msg.extendedheader->msin = (DLT_TYPE_LOG << DLT_MSIN_MSTP_SHIFT) | ((log->log_level << DLT_MSIN_MTIN_SHIFT) & DLT_MSIN_MTIN) ; /* messsage info */
2169 case DLT_TYPE_NW_TRACE:
2171 msg.extendedheader->msin = (DLT_TYPE_NW_TRACE << DLT_MSIN_MSTP_SHIFT) | ((log->trace_status << DLT_MSIN_MTIN_SHIFT) & DLT_MSIN_MTIN) ; /* messsage info */
2176 /* This case should not occur */
2182 /* If in verbose mode, set flag in header for verbose mode */
2183 if (dlt_user.verbose_mode)
2185 msg.extendedheader->msin |= DLT_MSIN_VERB;
2188 msg.extendedheader->noar = log->args_num; /* number of arguments */
2189 dlt_set_id(msg.extendedheader->apid,dlt_user.appID); /* application id */
2190 dlt_set_id(msg.extendedheader->ctid,log->handle->contextID); /* context id */
2192 msg.headersize = sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + sizeof(DltExtendedHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp);
2196 /* without extended header */
2197 msg.headersize = sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp);
2200 len=msg.headersize - sizeof(DltStorageHeader) +log->size;
2203 dlt_log(LOG_CRIT,"Huge message discarded!\n");
2207 msg.standardheader->len = DLT_HTOBE_16(len);
2209 /* print to std out, if enabled */
2210 if ((dlt_user.local_print_mode != DLT_PM_FORCE_OFF) &&
2211 (dlt_user.local_print_mode != DLT_PM_AUTOMATIC))
2213 if ((dlt_user.enable_local_print) || (dlt_user.local_print_mode == DLT_PM_FORCE_ON))
2215 if (dlt_user_print_msg(&msg, log)==-1)
2222 if (dlt_user.dlt_is_file)
2225 ret=dlt_user_log_out2(dlt_user.dlt_log_handle, msg.headerbuffer, msg.headersize, log->buffer, log->size);
2226 return ((ret==DLT_RETURN_OK)?0:-1);
2230 /* Reattach to daemon if neccesary */
2231 dlt_user_log_reattach_to_daemon();
2233 if (dlt_user.overflow)
2235 if (dlt_user_log_send_overflow()==0)
2237 dlt_user.overflow=0;
2241 /* try to resent old data first */
2243 if(dlt_user.dlt_log_handle!=-1)
2244 ret = dlt_user_log_resend_buffer();
2247 /* resend ok or nothing to resent */
2248 #ifdef DLT_SHM_ENABLE
2249 if(dlt_user.dlt_log_handle!=-1)
2250 dlt_shm_push(&dlt_user.dlt_shm,msg.headerbuffer+sizeof(DltStorageHeader), msg.headersize-sizeof(DltStorageHeader),
2251 log->buffer, log->size,0,0);
2254 ret = dlt_user_log_out3(dlt_user.dlt_log_handle,
2255 &(userheader), sizeof(DltUserHeader),
2260 #ifdef DLT_TEST_ENABLE
2261 if(dlt_user.corrupt_user_header) {
2262 userheader.pattern[0]=0xff;
2263 userheader.pattern[1]=0xff;
2264 userheader.pattern[2]=0xff;
2265 userheader.pattern[3]=0xff;
2267 if(dlt_user.corrupt_message_size) {
2268 msg.standardheader->len = DLT_HTOBE_16(dlt_user.corrupt_message_size_size);
2271 ret = dlt_user_log_out3(dlt_user.dlt_log_handle,
2272 &(userheader), sizeof(DltUserHeader),
2273 msg.headerbuffer+sizeof(DltStorageHeader), msg.headersize-sizeof(DltStorageHeader),
2274 log->buffer, log->size);
2278 /* store message in ringbuffer, if an error has occured */
2279 if (ret!=DLT_RETURN_OK)
2283 if (dlt_buffer_push3(&(dlt_user.startup_buffer),
2284 (unsigned char *)&(userheader), sizeof(DltUserHeader),
2285 msg.headerbuffer+sizeof(DltStorageHeader), msg.headersize-sizeof(DltStorageHeader),
2286 log->buffer, log->size)==-1)
2288 dlt_log(LOG_ERR,"Storing message to history buffer failed! Message discarded.\n");
2296 case DLT_RETURN_PIPE_FULL:
2298 /* data could not be written */
2299 dlt_user.overflow = 1;
2302 case DLT_RETURN_PIPE_ERROR:
2304 /* handle not open or pipe error */
2305 close(dlt_user.dlt_log_handle);
2306 dlt_user.dlt_log_handle = -1;
2308 #ifdef DLT_SHM_ENABLE
2309 /* free shared memory */
2310 dlt_shm_free_client(&dlt_user.dlt_shm);
2313 if (dlt_user.local_print_mode == DLT_PM_AUTOMATIC)
2315 dlt_user_print_msg(&msg, log);
2320 case DLT_RETURN_ERROR:
2322 /* other error condition */
2331 /* This case should never occur. */
2340 int dlt_user_log_send_register_application(void)
2342 DltUserHeader userheader;
2343 DltUserControlMsgRegisterApplication usercontext;
2347 if (dlt_user.appID[0]=='\0')
2352 /* set userheader */
2353 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_REGISTER_APPLICATION)==-1)
2358 /* set usercontext */
2359 dlt_set_id(usercontext.apid,dlt_user.appID); /* application id */
2360 usercontext.pid = getpid();
2362 if (dlt_user.application_description!=0)
2364 usercontext.description_length = strlen(dlt_user.application_description);
2368 usercontext.description_length = 0;
2371 if (dlt_user.dlt_is_file)
2377 ret=dlt_user_log_out3(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgRegisterApplication),dlt_user.application_description,usercontext.description_length);
2378 return ((ret==DLT_RETURN_OK)?0:-1);
2381 int dlt_user_log_send_unregister_application(void)
2383 DltUserHeader userheader;
2384 DltUserControlMsgUnregisterApplication usercontext;
2388 if (dlt_user.appID[0]=='\0')
2393 /* set userheader */
2394 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_UNREGISTER_APPLICATION)==-1)
2399 /* set usercontext */
2400 dlt_set_id(usercontext.apid,dlt_user.appID); /* application id */
2401 usercontext.pid = getpid();
2403 if (dlt_user.dlt_is_file)
2409 ret=dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgUnregisterApplication));
2410 return ((ret==DLT_RETURN_OK)?0:-1);
2413 int dlt_user_log_send_register_context(DltContextData *log)
2415 DltUserHeader userheader;
2416 DltUserControlMsgRegisterContext usercontext;
2429 if ((dlt_user.appID[0]=='\0') || (log->handle->contextID=='\0'))
2434 /* set userheader */
2435 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_REGISTER_CONTEXT)==-1)
2440 /* set usercontext */
2441 dlt_set_id(usercontext.apid,dlt_user.appID); /* application id */
2442 dlt_set_id(usercontext.ctid,log->handle->contextID); /* context id */
2443 usercontext.log_level_pos = log->handle->log_level_pos;
2444 usercontext.pid = getpid();
2446 usercontext.log_level = (int8_t)log->log_level;
2447 usercontext.trace_status = (int8_t)log->trace_status;
2449 if (log->context_description!=0)
2451 usercontext.description_length = strlen(log->context_description);
2455 usercontext.description_length = 0;
2458 if (dlt_user.dlt_is_file)
2464 ret=dlt_user_log_out3(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgRegisterContext),log->context_description,usercontext.description_length);
2465 return ((ret==DLT_RETURN_OK)?0:-1);
2468 int dlt_user_log_send_unregister_context(DltContextData *log)
2470 DltUserHeader userheader;
2471 DltUserControlMsgUnregisterContext usercontext;
2484 if ((dlt_user.appID[0]=='\0') || (log->handle->contextID=='\0'))
2489 /* set userheader */
2490 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_UNREGISTER_CONTEXT)==-1)
2495 /* set usercontext */
2496 dlt_set_id(usercontext.apid,dlt_user.appID); /* application id */
2497 dlt_set_id(usercontext.ctid,log->handle->contextID); /* context id */
2498 usercontext.pid = getpid();
2500 if (dlt_user.dlt_is_file)
2506 ret=dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgUnregisterContext));
2507 return ((ret==DLT_RETURN_OK)?0:-1);
2510 int dlt_send_app_ll_ts_limit(const char *appid, DltLogLevelType loglevel, DltTraceStatusType tracestatus)
2512 DltUserHeader userheader;
2513 DltUserControlMsgAppLogLevelTraceStatus usercontext;
2516 if ((appid==0) || (appid[0]=='\0'))
2521 /* Removed because of DltLogLevelType and DltTraceStatusType
2523 if ((loglevel<DLT_LOG_DEFAULT) || (loglevel>DLT_LOG_VERBOSE))
2528 if ((tracestatus<DLT_TRACE_STATUS_DEFAULT) || (tracestatus>DLT_TRACE_STATUS_ON))
2535 /* set userheader */
2536 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_APP_LL_TS)==-1)
2541 /* set usercontext */
2542 dlt_set_id(usercontext.apid,appid); /* application id */
2543 usercontext.log_level = loglevel;
2544 usercontext.trace_status = tracestatus;
2546 if (dlt_user.dlt_is_file)
2552 ret=dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgAppLogLevelTraceStatus));
2553 return ((ret==DLT_RETURN_OK)?0:-1);
2556 int dlt_user_log_send_log_mode(DltUserLogMode mode)
2558 DltUserHeader userheader;
2559 DltUserControlMsgLogMode logmode;
2563 /* set userheader */
2564 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG_MODE)==-1)
2570 logmode.log_mode = (unsigned char) mode;
2572 if (dlt_user.dlt_is_file)
2578 ret=dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(logmode), sizeof(DltUserControlMsgLogMode));
2579 return ((ret==DLT_RETURN_OK)?0:-1);
2582 int dlt_user_print_msg(DltMessage *msg, DltContextData *log)
2584 uint8_t *databuffer_tmp;
2585 int32_t datasize_tmp;
2586 int32_t databuffersize_tmp;
2587 static char text[DLT_USER_TEXT_LENGTH];
2589 if ((msg==0) || (log==0))
2594 /* Save variables before print */
2595 databuffer_tmp = msg->databuffer;
2596 datasize_tmp = msg->datasize;
2597 databuffersize_tmp = msg->databuffersize;
2599 /* Act like a receiver, convert header back to host format */
2600 msg->standardheader->len = DLT_BETOH_16(msg->standardheader->len);
2601 dlt_message_get_extraparameters(msg,0);
2603 msg->databuffer = log->buffer;
2604 msg->datasize = log->size;
2605 msg->databuffersize = log->size;
2607 /* Print message as ASCII */
2608 if (dlt_message_print_ascii(msg,text,DLT_USER_TEXT_LENGTH,0)==-1)
2613 /* Restore variables and set len to BE*/
2614 msg->databuffer = databuffer_tmp;
2615 msg->databuffersize = databuffersize_tmp;
2616 msg->datasize = datasize_tmp;
2618 msg->standardheader->len = DLT_HTOBE_16(msg->standardheader->len);
2623 int dlt_user_log_check_user_message(void)
2630 DltUserHeader *userheader;
2631 DltReceiver *receiver = &(dlt_user.receiver);
2633 DltUserControlMsgLogLevel *usercontextll;
2634 DltUserControlMsgInjection *usercontextinj;
2635 DltUserControlMsgLogState *userlogstate;
2636 unsigned char *userbuffer;
2638 /* For delayed calling of injection callback, to avoid deadlock */
2639 DltUserInjectionCallback delayed_injection_callback;
2640 unsigned char *delayed_inject_buffer = 0;
2641 uint32_t delayed_inject_data_length = 0;
2643 /* Ensure that callback is null before searching for it */
2644 delayed_injection_callback.injection_callback = 0;
2645 delayed_injection_callback.service_id = 0;
2647 if (dlt_user.dlt_user_handle!=DLT_FD_INIT)
2651 if (dlt_receiver_receive_fd(receiver)<=0)
2653 /* No new message available */
2657 /* look through buffer as long as data is in there */
2660 if (receiver->bytesRcvd < (int32_t)sizeof(DltUserHeader))
2665 /* resync if necessary */
2669 userheader = (DltUserHeader*) (receiver->buf+offset);
2671 /* Check for user header pattern */
2672 if (dlt_user_check_userheader(userheader))
2679 while ((int32_t)(sizeof(DltUserHeader)+offset)<=receiver->bytesRcvd);
2681 /* Check for user header pattern */
2682 if (dlt_user_check_userheader(userheader)==0)
2687 /* Set new start offset */
2690 receiver->buf+=offset;
2691 receiver->bytesRcvd-=offset;
2694 switch (userheader->message)
2696 case DLT_USER_MESSAGE_LOG_LEVEL:
2698 if (receiver->bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogLevel)))
2704 usercontextll = (DltUserControlMsgLogLevel*) (receiver->buf+sizeof(DltUserHeader));
2706 /* Update log level and trace status */
2707 if (usercontextll!=0)
2711 if ((usercontextll->log_level_pos >= 0) && (usercontextll->log_level_pos < (int32_t)dlt_user.dlt_ll_ts_num_entries))
2713 // printf("Store ll, ts\n");
2714 if (dlt_user.dlt_ll_ts)
2716 dlt_user.dlt_ll_ts[usercontextll->log_level_pos].log_level = usercontextll->log_level;
2717 dlt_user.dlt_ll_ts[usercontextll->log_level_pos].trace_status = usercontextll->trace_status;
2724 /* keep not read data in buffer */
2725 if (dlt_receiver_remove(receiver,sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogLevel))==-1)
2731 case DLT_USER_MESSAGE_INJECTION:
2733 /* At least, user header, user context, and service id and data_length of injected message is available */
2734 if (receiver->bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgInjection)))
2740 usercontextinj = (DltUserControlMsgInjection*) (receiver->buf+sizeof(DltUserHeader));
2741 userbuffer = (unsigned char*) (receiver->buf+sizeof(DltUserHeader)+sizeof(DltUserControlMsgInjection));
2746 if (receiver->bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgInjection)+usercontextinj->data_length_inject))
2754 if ((usercontextinj->data_length_inject>0) && (dlt_user.dlt_ll_ts))
2756 /* Check if injection callback is registered for this context */
2757 for (i=0; i<dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].nrcallbacks;i++)
2759 if ((dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table) &&
2760 (dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table[i].service_id == usercontextinj->service_id))
2762 /* Prepare delayed injection callback call */
2763 if (dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table[i].injection_callback!=0)
2765 delayed_injection_callback.injection_callback = dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table[i].injection_callback;
2766 delayed_injection_callback.service_id = usercontextinj->service_id;
2767 delayed_inject_data_length = usercontextinj->data_length_inject;
2768 delayed_inject_buffer = malloc(delayed_inject_data_length);
2769 if(delayed_inject_buffer != 0) {
2770 memcpy(delayed_inject_buffer, userbuffer, delayed_inject_data_length);
2781 /* Delayed injection callback call */
2782 if(delayed_inject_buffer != 0 && delayed_injection_callback.injection_callback != 0) {
2783 delayed_injection_callback.injection_callback(delayed_injection_callback.service_id, delayed_inject_buffer, delayed_inject_data_length);
2784 free(delayed_inject_buffer);
2787 /* keep not read data in buffer */
2788 if (dlt_receiver_remove(receiver,(sizeof(DltUserHeader)+sizeof(DltUserControlMsgInjection)+usercontextinj->data_length_inject))==-1)
2795 case DLT_USER_MESSAGE_LOG_STATE:
2797 /* At least, user header, user context, and service id and data_length of injected message is available */
2798 if (receiver->bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogState)))
2804 userlogstate = (DltUserControlMsgLogState*) (receiver->buf+sizeof(DltUserHeader));
2805 dlt_user.log_state = userlogstate->log_state;
2807 /* keep not read data in buffer */
2808 if (dlt_receiver_remove(receiver,(sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogState)))==-1)
2816 dlt_log(LOG_ERR,"Invalid user message type received!\n");
2818 dlt_receiver_remove(receiver,sizeof(DltUserHeader));
2819 /* In next invocation of while loop, a resync will be triggered if additional data was received */
2832 if (dlt_receiver_move_to_begin(receiver)==-1)
2836 } /* while receive */
2839 return DLT_RETURN_OK;
2842 int dlt_user_log_resend_buffer(void)
2845 uint8_t buf[DLT_USER_RCVBUF_MAX_SIZE];
2849 /* Send content of ringbuffer */
2851 count = dlt_buffer_get_message_count(&(dlt_user.startup_buffer));
2854 for (num=0;num<count;num++)
2858 size = dlt_buffer_copy(&(dlt_user.startup_buffer),buf,sizeof(buf));
2862 #ifdef DLT_SHM_ENABLE
2863 dlt_shm_push(&dlt_user.dlt_shm,buf+sizeof(DltUserHeader),size-sizeof(DltUserHeader),0,0,0,0);
2866 ret = dlt_user_log_out3(dlt_user.dlt_log_handle, buf,sizeof(DltUserHeader),0,0,0,0);
2869 ret = dlt_user_log_out3(dlt_user.dlt_log_handle, buf,size,0,0,0,0);
2872 /* in case of error, keep message in ringbuffer */
2873 if (ret==DLT_RETURN_OK)
2875 dlt_buffer_remove(&(dlt_user.startup_buffer));
2878 if (dlt_buffer_push(&(dlt_user.startup_buffer), buf, size)==-1)
2880 dlt_log(LOG_ERR,"Error pushing back message to history buffer. Message discarded.\n");
2884 // In case of: data could not be written, set overflow flag
2885 if (ret==DLT_RETURN_PIPE_FULL)
2887 dlt_user.overflow = 1;
2893 /* keep message in ringbuffer */
2904 void dlt_user_log_reattach_to_daemon(void)
2906 uint32_t num,reregistered=0;
2909 DltContextData log_new;
2911 if (dlt_user.dlt_log_handle<0)
2913 dlt_user.dlt_log_handle=-1;
2915 /* try to open pipe to dlt daemon */
2916 dlt_user.dlt_log_handle = open(DLT_USER_FIFO, O_WRONLY | O_NONBLOCK);
2917 if (dlt_user.dlt_log_handle > 0)
2919 if (dlt_user_log_init(&handle,&log_new)==-1)
2924 #ifdef DLT_SHM_ENABLE
2925 /* init shared memory */
2926 if (dlt_shm_init_client(&dlt_user.dlt_shm,DLT_SHM_KEY) < 0)
2928 sprintf(str,"Loging disabled, Shared memory %d cannot be created!\n",DLT_SHM_KEY);
2929 dlt_log(LOG_WARNING, str);
2934 dlt_log(LOG_NOTICE, "Logging re-enabled!\n");
2936 /* Re-register application */
2937 if (dlt_user_log_send_register_application()==-1)
2944 /* Re-register all stored contexts */
2945 for (num=0; num<dlt_user.dlt_ll_ts_num_entries; num++)
2947 /* Re-register stored context */
2948 if ((dlt_user.appID[0]!='\0') && (dlt_user.dlt_ll_ts[num].contextID[0]!='\0') && (dlt_user.dlt_ll_ts))
2950 //dlt_set_id(log_new.appID, dlt_user.appID);
2951 dlt_set_id(handle.contextID, dlt_user.dlt_ll_ts[num].contextID);
2952 handle.log_level_pos = num;
2953 log_new.context_description = dlt_user.dlt_ll_ts[num].context_description;
2955 log_new.log_level = DLT_USER_LOG_LEVEL_NOT_SET;
2956 log_new.trace_status = DLT_USER_TRACE_STATUS_NOT_SET;
2958 if (dlt_user_log_send_register_context(&log_new)==-1)
2970 if (reregistered==1)
2972 dlt_user_log_resend_buffer();
2978 int dlt_user_log_send_overflow(void)
2980 DltUserHeader userheader;
2983 /* set userheader */
2984 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_OVERFLOW)==-1)
2989 if (dlt_user.dlt_is_file)
2995 ret=dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), 0, 0);
2996 return ((ret==DLT_RETURN_OK)?0:-1);
2999 int dlt_user_check_buffer(int *total_size, int *used_size)
3001 #ifdef DLT_SHM_ENABLE
3002 *total_size = dlt_shm_get_total_size(&(dlt_user.dlt_shm));
3003 *used_size = dlt_shm_get_used_size(&(dlt_user.dlt_shm));
3005 *total_size = dlt_buffer_get_total_size(&(dlt_user.startup_buffer));
3006 *used_size = dlt_buffer_get_used_size(&(dlt_user.startup_buffer));
3012 #ifdef DLT_TEST_ENABLE
3013 void dlt_user_test_corrupt_user_header(int enable)
3015 dlt_user.corrupt_user_header = enable;
3017 void dlt_user_test_corrupt_message_size(int enable,int16_t size)
3019 dlt_user.corrupt_message_size = enable;
3020 dlt_user.corrupt_message_size_size = size;