3 * Copyright (C) 2012 BMW AG
5 * This file is part of GENIVI Project Dlt - Diagnostic Log and Trace console apps.
7 * Contributions are licensed to the GENIVI Alliance under one or more
8 * Contribution License Agreements.
11 * This Source Code Form is subject to the terms of the
12 * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with
13 * this file, You can obtain one at http://mozilla.org/MPL/2.0/.
16 * \author Alexander Wenzel <alexander.aw.wenzel@bmw.de> BMW 2011-2012
19 * For further information see http://www.genivi.org/.
24 /*******************************************************************************
26 ** SRC-MODULE: dlt_user.c **
32 ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de **
39 ** PLATFORM DEPENDANT [yes/no]: yes **
41 ** TO BE CHANGED BY USER [yes/no]: no **
43 *******************************************************************************/
45 /*******************************************************************************
47 ********************************************************************************
49 ** Initials Name Company **
50 ** -------- ------------------------- ---------------------------------- **
51 ** aw Alexander Wenzel BMW **
52 ** mk Markus Klein Fraunhofer ESK **
53 *******************************************************************************/
55 /*******************************************************************************
56 ** Revision Control History **
57 *******************************************************************************/
60 * $LastChangedRevision: 1670 $
61 * $LastChangedDate: 2011-04-08 15:12:06 +0200 (Fr, 08. Apr 2011) $
66 #include <stdlib.h> /* for getenv(), free(), atexit() */
67 #include <string.h> /* for strcmp(), strncmp(), strlen(), memset(), memcpy() */
68 #include <signal.h> /* for signal(), SIGPIPE, SIG_IGN */
70 #if !defined (__WIN32__)
71 #include <syslog.h> /* for LOG_... */
72 #include <semaphore.h>
73 #include <pthread.h> /* POSIX Threads */
83 #include <sys/uio.h> /* writev() */
88 #include "dlt_user_shared.h"
89 #include "dlt_user_shared_cfg.h"
90 #include "dlt_user_cfg.h"
92 static DltUser dlt_user;
93 static int dlt_user_initialised = 0;
95 static char str[DLT_USER_BUFFER_LENGTH];
97 static sem_t dlt_mutex;
98 static pthread_t dlt_receiverthread_handle;
99 static pthread_attr_t dlt_receiverthread_attr;
101 /* Segmented Network Trace */
102 #define DLT_MAX_TRACE_SEGMENT_SIZE 1024
103 #define DLT_MESSAGE_QUEUE_NAME "/dlt_message_queue"
104 #define DLT_DELAYED_RESEND_INDICATOR_PATTERN 0xFFFF
106 /* Mutex to wait on while message queue is not initialized */
107 pthread_mutex_t mq_mutex;
108 pthread_cond_t mq_init_condition;
110 /* Structure to pass data to segmented thread */
114 DltNetworkTraceType nw_trace_type;
117 uint16_t payload_len;
121 /* Function prototypes for internally used functions */
122 static void dlt_user_receiverthread_function(void *ptr);
123 static void dlt_user_atexit_handler(void);
124 static int dlt_user_log_init(DltContext *handle, DltContextData *log);
125 static DltReturnValue dlt_user_log_send_log(DltContextData *log, int mtype);
126 static int dlt_user_log_send_register_application(void);
127 static int dlt_user_log_send_unregister_application(void);
128 static int dlt_user_log_send_register_context(DltContextData *log);
129 static int dlt_user_log_send_unregister_context(DltContextData *log);
130 static int dlt_send_app_ll_ts_limit(const char *appid, DltLogLevelType loglevel, DltTraceStatusType tracestatus);
131 static int dlt_user_log_send_log_mode(DltUserLogMode mode);
132 static int dlt_user_print_msg(DltMessage *msg, DltContextData *log);
133 static int dlt_user_log_check_user_message(void);
134 static void dlt_user_log_reattach_to_daemon(void);
135 static int dlt_user_log_send_overflow(void);
136 static void dlt_user_trace_network_segmented_thread(void *unused);
137 static int dlt_user_queue_resend(void);
139 int dlt_user_check_library_version(const char *user_major_version,const char *user_minor_version){
142 char lib_major_version[DLT_USER_MAX_LIB_VERSION_LENGTH];
143 char lib_minor_version[DLT_USER_MAX_LIB_VERSION_LENGTH];
145 dlt_get_major_version( lib_major_version);
146 dlt_get_minor_version( lib_minor_version);
148 if( (strcmp(lib_major_version,user_major_version)!=0) || (strcmp(lib_minor_version,user_minor_version)!=0))
150 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);
151 dlt_log(LOG_WARNING, str);
159 char filename[DLT_USER_MAX_FILENAME_LENGTH];
162 dlt_user_initialised = 1;
164 /* Initialize common part of dlt_init()/dlt_init_file() */
165 if (dlt_init_common()==-1)
167 dlt_user_initialised = 0;
171 dlt_user.dlt_is_file = 0;
172 dlt_user.overflow = 0;
173 #ifdef DLT_SHM_ENABLE
174 memset(&(dlt_user.dlt_shm),0,sizeof(DltShm));
177 /* create and open DLT user FIFO */
178 sprintf(filename,"%s/dlt%d",DLT_USER_DIR,getpid());
180 /* Try to delete existing pipe, ignore result of unlink */
183 ret=mkfifo(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH );
186 sprintf(str,"Loging disabled, FIFO user %s cannot be created!\n",filename);
187 dlt_log(LOG_WARNING, str);
188 /* return 0; */ /* removed to prevent error, when FIFO already exists */
191 dlt_user.dlt_user_handle = open(filename, O_RDWR | O_CLOEXEC);
192 if (dlt_user.dlt_user_handle == DLT_FD_INIT)
194 sprintf(str,"Loging disabled, FIFO user %s cannot be opened!\n",filename);
195 dlt_log(LOG_WARNING, str);
200 /* open DLT output FIFO */
201 dlt_user.dlt_log_handle = open(DLT_USER_FIFO, O_WRONLY | O_NONBLOCK | O_CLOEXEC );
202 if (dlt_user.dlt_log_handle==-1)
204 sprintf(str,"Loging disabled, FIFO %s cannot be opened with open()!\n",DLT_USER_FIFO);
205 dlt_log(LOG_WARNING, str);
210 #ifdef DLT_SHM_ENABLE
211 /* init shared memory */
212 if (dlt_shm_init_client(&(dlt_user.dlt_shm),DLT_SHM_KEY) < 0)
214 sprintf(str,"Loging disabled, Shared memory %d cannot be created!\n",DLT_SHM_KEY);
215 dlt_log(LOG_WARNING, str);
222 if (dlt_receiver_init(&(dlt_user.receiver),dlt_user.dlt_user_handle, DLT_USER_RCVBUF_MAX_SIZE)==-1)
224 dlt_user_initialised = 0;
228 /* Start receiver thread */
229 if (pthread_create(&(dlt_receiverthread_handle),
231 (void *) &dlt_user_receiverthread_function,
234 if (pthread_attr_destroy(&dlt_receiverthread_attr)!=0)
236 dlt_log(LOG_WARNING, "Can't destroy thread attributes!\n");
239 dlt_log(LOG_CRIT, "Can't create receiver thread!\n");
240 dlt_user_initialised = 0;
244 if (pthread_attr_destroy(&dlt_receiverthread_attr)!=0)
246 dlt_log(LOG_WARNING, "Can't destroy thread attributes!\n");
249 /* These will be lazy initialized only when needed */
250 dlt_user.dlt_segmented_queue_read_handle = -1;
251 dlt_user.dlt_segmented_queue_write_handle = -1;
253 /* Wait mutext for segmented thread */
254 pthread_mutex_init(&mq_mutex, NULL);
255 pthread_cond_init(&mq_init_condition, NULL);
257 /* Start the segmented thread */
258 if(pthread_create(&(dlt_user.dlt_segmented_nwt_handle), NULL,
259 (void *)dlt_user_trace_network_segmented_thread, NULL))
261 dlt_log(LOG_CRIT, "Can't start segmented thread!\n");
268 int dlt_init_file(const char *name)
270 dlt_user_initialised = 1;
272 /* Initialize common part of dlt_init()/dlt_init_file() */
273 if (dlt_init_common()==-1)
275 dlt_user_initialised = 0;
279 dlt_user.dlt_is_file = 1;
281 /* open DLT output file */
282 dlt_user.dlt_log_handle = open(name,O_WRONLY|O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); /* mode: wb */
283 if (dlt_user.dlt_log_handle == -1)
285 sprintf(str,"Log file %s cannot be opened!\n",name);
286 dlt_log(LOG_ERR, str);
293 int dlt_init_message_queue(void)
295 pthread_mutex_lock(&mq_mutex);
296 if(dlt_user.dlt_segmented_queue_read_handle >= 0 &&
297 dlt_user.dlt_segmented_queue_write_handle >= 0)
299 // Already intialized
300 pthread_mutex_unlock(&mq_mutex);
304 /* Generate per process name for queue */
305 char queue_name[NAME_MAX];
306 sprintf(queue_name, "%s.%d", DLT_MESSAGE_QUEUE_NAME, getpid());
308 /* Maximum queue size is 10, limit to size of pointers */
309 struct mq_attr mqatr;
311 mqatr.mq_maxmsg = 10;
312 mqatr.mq_msgsize = sizeof(s_segmented_data *);
313 mqatr.mq_curmsgs = 0;
316 * Create the message queue. It must be newly created
317 * if old one was left by a crashing process.
319 dlt_user.dlt_segmented_queue_read_handle = mq_open(queue_name, O_CREAT| O_RDONLY | O_EXCL,
320 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, &mqatr);
321 if(dlt_user.dlt_segmented_queue_read_handle < 0)
325 dlt_log(LOG_WARNING, "Old message queue exists, trying to delete.\n");
326 if(mq_unlink(queue_name) < 0)
328 dlt_log(LOG_CRIT, "Could not delete existing message queue!\n");
329 dlt_log(LOG_CRIT, strerror(errno));
333 dlt_user.dlt_segmented_queue_read_handle = mq_open(queue_name, O_CREAT| O_RDONLY | O_EXCL,
334 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, &mqatr);
337 if(dlt_user.dlt_segmented_queue_read_handle < 0)
339 dlt_log(LOG_CRIT, "Can't create message queue read handle!\n");
340 dlt_log(LOG_CRIT, strerror(errno));
341 pthread_mutex_unlock(&mq_mutex);
346 dlt_user.dlt_segmented_queue_write_handle = mq_open(queue_name, O_WRONLY|O_NONBLOCK);
347 if(dlt_user.dlt_segmented_queue_write_handle < 0)
349 dlt_log(LOG_CRIT, "Can't open message queue write handle!\n");
350 dlt_log(LOG_CRIT, strerror(errno));
351 pthread_mutex_unlock(&mq_mutex);
355 pthread_cond_signal(&mq_init_condition);
356 pthread_mutex_unlock(&mq_mutex);
360 int dlt_init_common(void)
362 char *env_local_print;
364 /* Binary semaphore for threads */
365 if (sem_init(&dlt_mutex, 0, 1)==-1)
367 dlt_user_initialised = 0;
371 /* set to unknown state of connected client */
372 dlt_user.log_state = -1;
374 dlt_user.dlt_log_handle=-1;
375 dlt_user.dlt_user_handle=DLT_FD_INIT;
377 dlt_set_id(dlt_user.ecuID,DLT_USER_DEFAULT_ECU_ID);
378 dlt_set_id(dlt_user.appID,"");
380 dlt_user.application_description = 0;
382 /* Verbose mode is enabled by default */
383 dlt_user.verbose_mode = 1;
385 /* Local print is disabled by default */
386 dlt_user.enable_local_print = 0;
388 dlt_user.local_print_mode = DLT_PM_UNSET;
390 env_local_print = getenv(DLT_USER_ENV_LOCAL_PRINT_MODE);
393 if (strcmp(env_local_print,"AUTOMATIC")==0)
395 dlt_user.local_print_mode = DLT_PM_AUTOMATIC;
397 else if (strcmp(env_local_print,"FORCE_ON")==0)
399 dlt_user.local_print_mode = DLT_PM_FORCE_ON;
401 else if (strcmp(env_local_print,"FORCE_OFF")==0)
403 dlt_user.local_print_mode = DLT_PM_FORCE_OFF;
407 /* Initialize LogLevel/TraceStatus field */
408 dlt_user.dlt_ll_ts = 0;
409 dlt_user.dlt_ll_ts_max_num_entries = 0;
410 dlt_user.dlt_ll_ts_num_entries = 0;
412 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)
414 dlt_user_initialised = 0;
418 signal(SIGPIPE,SIG_IGN); /* ignore pipe signals */
420 atexit(dlt_user_atexit_handler);
422 #ifdef DLT_TEST_ENABLE
423 dlt_user.corrupt_user_header = 0;
424 dlt_user.corrupt_message_size = 0;
425 dlt_user.corrupt_message_size_size = 0;
431 void dlt_user_atexit_handler(void)
434 /* Try to resend potential log messages in the user buffer */
435 int count = dlt_user_atexit_blow_out_user_buffer();
439 sprintf(tmp,"Lost log messages in user buffer when exiting: %i\n",count);
440 dlt_log(LOG_ERR, tmp);
443 /* Unregister app (this also unregisters all contexts in daemon) */
444 /* Ignore return value */
445 dlt_unregister_app();
448 /* Ignore return value */
452 int dlt_user_atexit_blow_out_user_buffer(void){
456 uint32_t exitTime = dlt_uptime() + DLT_USER_ATEXIT_RESEND_BUFFER_EXIT_TIMEOUT;
458 while(dlt_uptime() < exitTime ){
460 ret = dlt_user_log_resend_buffer();
467 usleep(DLT_USER_ATEXIT_RESEND_BUFFER_SLEEP);
471 count = dlt_buffer_get_message_count(&(dlt_user.startup_buffer));
480 char filename[DLT_USER_MAX_FILENAME_LENGTH];
482 if (dlt_user_initialised==0)
487 if (dlt_receiverthread_handle)
489 /* Ignore return value */
490 pthread_cancel(dlt_receiverthread_handle);
493 if (dlt_user.dlt_user_handle!=DLT_FD_INIT)
495 sprintf(filename,"%s/dlt%d",DLT_USER_DIR,getpid());
497 close(dlt_user.dlt_user_handle);
498 dlt_user.dlt_user_handle=DLT_FD_INIT;
503 #ifdef DLT_SHM_ENABLE
504 /* free shared memory */
505 dlt_shm_free_client(&dlt_user.dlt_shm);
508 if (dlt_user.dlt_log_handle!=-1)
510 /* close log file/output fifo to daemon */
511 close(dlt_user.dlt_log_handle);
512 dlt_user.dlt_log_handle = -1;
515 /* Ignore return value */
516 dlt_receiver_free(&(dlt_user.receiver));
518 /* Ignore return value */
519 dlt_buffer_free_dynamic(&(dlt_user.startup_buffer));
521 if (dlt_user.dlt_ll_ts)
523 for (i=0;i<dlt_user.dlt_ll_ts_max_num_entries;i++)
525 if (dlt_user.dlt_ll_ts[i].injection_table!=0)
527 free(dlt_user.dlt_ll_ts[i].injection_table);
528 dlt_user.dlt_ll_ts[i].injection_table = 0;
530 dlt_user.dlt_ll_ts[i].nrcallbacks = 0;
533 free(dlt_user.dlt_ll_ts);
534 dlt_user.dlt_ll_ts = 0;
535 dlt_user.dlt_ll_ts_max_num_entries = 0;
536 dlt_user.dlt_ll_ts_num_entries = 0;
539 if (dlt_user.dlt_segmented_nwt_handle)
541 pthread_cancel(dlt_user.dlt_segmented_nwt_handle);
544 char queue_name[NAME_MAX];
545 sprintf(queue_name, "%s.%d", DLT_MESSAGE_QUEUE_NAME, getpid());
548 * Ignore errors from these, to not to spam user if dlt_free
549 * is accidentally called multiple times.
551 mq_close(dlt_user.dlt_segmented_queue_write_handle);
552 mq_close(dlt_user.dlt_segmented_queue_read_handle);
553 mq_unlink(queue_name);
555 dlt_user_initialised = 0;
560 int dlt_check_library_version(const char * user_major_version,const char * user_minor_version)
562 return dlt_user_check_library_version(user_major_version, user_minor_version);
565 int dlt_register_app(const char *appid, const char * description)
569 if (dlt_user_initialised==0)
577 if ((appid==0) || (appid[0]=='\0'))
582 /* check if application already registered */
583 /* if yes do not register again */
586 if(appid[0]==dlt_user.appID[0])
591 if(appid[0]==dlt_user.appID[0] &&
592 appid[1]==dlt_user.appID[1])
597 if(appid[0]==dlt_user.appID[0] &&
598 appid[1]==dlt_user.appID[1] &&
599 appid[2]==dlt_user.appID[2])
604 if(appid[0]==dlt_user.appID[0] &&
605 appid[1]==dlt_user.appID[1] &&
606 appid[2]==dlt_user.appID[2] &&
607 appid[3]==dlt_user.appID[3])
613 /* Store locally application id and application description */
614 dlt_set_id(dlt_user.appID, appid);
616 if (dlt_user.application_description!=0)
618 free(dlt_user.application_description);
621 dlt_user.application_description = 0;
625 size_t desc_len = strlen(description);
626 dlt_user.application_description= malloc(desc_len+1);
627 if (dlt_user.application_description){
628 strncpy(dlt_user.application_description, description, desc_len);
630 /* Terminate transmitted string with 0 */
631 dlt_user.application_description[desc_len]='\0';
642 ret = dlt_user_log_send_register_application();
646 int dlt_register_context(DltContext *handle, const char *contextid, const char * description)
648 if (dlt_user_initialised==0)
658 if (dlt_user.appID[0]=='\0')
660 dlt_log(LOG_ERR, "no application registered!\n");
666 if ((contextid==0) || (contextid[0]=='\0'))
674 return dlt_register_context_ll_ts(handle, contextid, description, DLT_USER_LOG_LEVEL_NOT_SET, DLT_USER_TRACE_STATUS_NOT_SET);
677 int dlt_register_context_ll_ts(DltContext *handle, const char *contextid, const char * description, int loglevel, int tracestatus)
682 char ctid[DLT_ID_SIZE+1];
684 if (dlt_user_initialised==0)
694 if (dlt_user.appID[0]=='\0')
696 dlt_log(LOG_ERR, "no application registered!\n");
704 if ((contextid==0) || (contextid[0]=='\0'))
709 if ((loglevel<DLT_USER_LOG_LEVEL_NOT_SET) || (loglevel>DLT_LOG_VERBOSE) || (loglevel==DLT_LOG_DEFAULT))
714 if ((tracestatus<DLT_USER_TRACE_STATUS_NOT_SET) || (tracestatus>DLT_TRACE_STATUS_ON) || (tracestatus==DLT_TRACE_STATUS_DEFAULT))
719 if (dlt_user_log_init(handle, &log)==-1)
724 /* Reset message counter */
727 /* Store context id in log level/trace status field */
729 /* Check if already registered, else register context */
733 for (i=0;i<dlt_user.dlt_ll_ts_num_entries;i++)
735 if (dlt_user.dlt_ll_ts)
737 if (memcmp(dlt_user.dlt_ll_ts[i].contextID, contextid,DLT_ID_SIZE)==0)
741 memset(ctid,0,(DLT_ID_SIZE+1));
742 dlt_print_id(ctid, contextid);
744 sprintf(str,"context '%s' already registered!\n",ctid);
745 dlt_log(LOG_WARNING, str);
754 /* Allocate or expand context array */
755 if (dlt_user.dlt_ll_ts == 0)
757 dlt_user.dlt_ll_ts = (dlt_ll_ts_type*) malloc(sizeof(dlt_ll_ts_type)*DLT_USER_CONTEXT_ALLOC_SIZE);
758 if (dlt_user.dlt_ll_ts==0)
764 dlt_user.dlt_ll_ts_max_num_entries = DLT_USER_CONTEXT_ALLOC_SIZE;
766 /* Initialize new entries */
767 for (i=0;i<dlt_user.dlt_ll_ts_max_num_entries;i++)
769 dlt_set_id(dlt_user.dlt_ll_ts[i].contextID,"");
771 /* At startup, logging and tracing is locally enabled */
772 /* the correct log level/status is set after received from daemon */
773 dlt_user.dlt_ll_ts[i].log_level = DLT_USER_INITIAL_LOG_LEVEL;
774 dlt_user.dlt_ll_ts[i].trace_status = DLT_USER_INITIAL_TRACE_STATUS;
776 dlt_user.dlt_ll_ts[i].context_description = 0;
778 dlt_user.dlt_ll_ts[i].injection_table = 0;
779 dlt_user.dlt_ll_ts[i].nrcallbacks = 0;
784 if ((dlt_user.dlt_ll_ts_num_entries%DLT_USER_CONTEXT_ALLOC_SIZE)==0)
786 /* allocate memory in steps of DLT_USER_CONTEXT_ALLOC_SIZE, e.g. 500 */
787 dlt_ll_ts_type *old_ll_ts;
788 uint32_t old_max_entries;
790 old_ll_ts = dlt_user.dlt_ll_ts;
791 old_max_entries = dlt_user.dlt_ll_ts_max_num_entries;
793 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;
794 dlt_user.dlt_ll_ts = (dlt_ll_ts_type*) malloc(sizeof(dlt_ll_ts_type)*
795 dlt_user.dlt_ll_ts_max_num_entries);
796 if (dlt_user.dlt_ll_ts==0)
798 dlt_user.dlt_ll_ts = old_ll_ts;
799 dlt_user.dlt_ll_ts_max_num_entries = old_max_entries;
804 memcpy(dlt_user.dlt_ll_ts,old_ll_ts,sizeof(dlt_ll_ts_type)*dlt_user.dlt_ll_ts_num_entries);
807 /* Initialize new entries */
808 for (i=dlt_user.dlt_ll_ts_num_entries;i<dlt_user.dlt_ll_ts_max_num_entries;i++)
810 dlt_set_id(dlt_user.dlt_ll_ts[i].contextID,"");
812 /* At startup, logging and tracing is locally enabled */
813 /* the correct log level/status is set after received from daemon */
814 dlt_user.dlt_ll_ts[i].log_level = DLT_USER_INITIAL_LOG_LEVEL;
815 dlt_user.dlt_ll_ts[i].trace_status = DLT_USER_INITIAL_TRACE_STATUS;
817 dlt_user.dlt_ll_ts[i].context_description = 0;
819 dlt_user.dlt_ll_ts[i].injection_table = 0;
820 dlt_user.dlt_ll_ts[i].nrcallbacks = 0;
825 /* Store locally context id and context description */
826 dlt_set_id(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].contextID, contextid);
828 if (dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description!=0)
830 free(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description);
833 dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description = 0;
837 size_t desc_len = strlen(description);
838 dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description = malloc(desc_len+1);
839 if(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description == 0)
845 strncpy(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description, description, desc_len);
847 /* Terminate transmitted string with 0 */
848 dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description[desc_len]='\0';
851 if (loglevel!=DLT_USER_LOG_LEVEL_NOT_SET)
853 dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].log_level = loglevel;
856 if (tracestatus!=DLT_USER_TRACE_STATUS_NOT_SET)
858 dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].trace_status = tracestatus;
861 /* Prepare transfer struct */
862 //dlt_set_id(log->appID, dlt_user.appID);
863 dlt_set_id(handle->contextID, contextid);
864 handle->log_level_pos = dlt_user.dlt_ll_ts_num_entries;
866 log.context_description = dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description;
868 if (loglevel!=DLT_USER_LOG_LEVEL_NOT_SET)
870 log.log_level = loglevel;
874 log.log_level = DLT_USER_LOG_LEVEL_NOT_SET;
877 if (tracestatus!=DLT_USER_TRACE_STATUS_NOT_SET)
879 log.trace_status = tracestatus;
883 log.trace_status = DLT_USER_TRACE_STATUS_NOT_SET;
886 dlt_user.dlt_ll_ts_num_entries++;
890 ret=dlt_user_log_send_register_context(&log);
902 int dlt_unregister_app(void)
906 if (dlt_user_initialised==0)
911 /* Inform daemon to unregister application and all of its contexts */
912 ret = dlt_user_log_send_unregister_application();
916 /* Clear and free local stored application information */
917 dlt_set_id(dlt_user.appID, "");
919 if (dlt_user.application_description!=0)
921 free(dlt_user.application_description);
924 dlt_user.application_description = 0;
931 int dlt_unregister_context(DltContext *handle)
936 if (dlt_user_initialised==0)
941 if (dlt_user_log_init(handle, &log) == -1)
948 if (dlt_user.dlt_ll_ts)
950 /* Clear and free local stored context information */
951 dlt_set_id(dlt_user.dlt_ll_ts[handle->log_level_pos].contextID, "");
953 dlt_user.dlt_ll_ts[handle->log_level_pos].log_level = DLT_USER_INITIAL_LOG_LEVEL;
954 dlt_user.dlt_ll_ts[handle->log_level_pos].trace_status = DLT_USER_INITIAL_TRACE_STATUS;
956 if (dlt_user.dlt_ll_ts[handle->log_level_pos].context_description!=0)
958 free(dlt_user.dlt_ll_ts[handle->log_level_pos].context_description);
961 dlt_user.dlt_ll_ts[handle->log_level_pos].context_description = 0;
963 if (dlt_user.dlt_ll_ts[handle->log_level_pos].injection_table)
965 free(dlt_user.dlt_ll_ts[handle->log_level_pos].injection_table);
966 dlt_user.dlt_ll_ts[handle->log_level_pos].injection_table = 0;
969 dlt_user.dlt_ll_ts[handle->log_level_pos].nrcallbacks = 0;
974 /* Inform daemon to unregister context */
975 ret = dlt_user_log_send_unregister_context(&log);
980 int dlt_set_application_ll_ts_limit(DltLogLevelType loglevel, DltTraceStatusType tracestatus)
985 if (dlt_user_initialised==0)
993 /* Removed because of DltLogLevelType and DltTraceStatusType
995 if ((loglevel<DLT_LOG_DEFAULT) || (loglevel>DLT_LOG_VERBOSE))
1000 if ((tracestatus<DLT_TRACE_STATUS_DEFAULT) || (tracestatus>DLT_TRACE_STATUS_ON))
1005 if (dlt_user.dlt_ll_ts==0)
1014 /* Update local structures */
1015 for (i=0; i<dlt_user.dlt_ll_ts_num_entries;i++)
1017 dlt_user.dlt_ll_ts[i].log_level = loglevel;
1018 dlt_user.dlt_ll_ts[i].trace_status = tracestatus;
1023 /* Inform DLT server about update */
1024 ret = dlt_send_app_ll_ts_limit(dlt_user.appID, loglevel, tracestatus);
1029 int dlt_get_log_state()
1031 return dlt_user.log_state;
1034 int dlt_set_log_mode(DltUserLogMode mode)
1036 if (dlt_user_initialised==0)
1044 return dlt_user_log_send_log_mode(mode);
1047 int dlt_forward_msg(void *msgdata,size_t size)
1049 DltUserHeader userheader;
1052 if ((msgdata==0) || (size==0))
1057 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG)==-1)
1059 /* Type of internal user message; same value for Trace messages */
1063 if (dlt_user.dlt_is_file)
1066 ret = dlt_user_log_out2(dlt_user.dlt_log_handle, msgdata, size, 0, 0);
1067 return ((ret==DLT_RETURN_OK)?0:-1);
1071 /* Reattach to daemon if neccesary */
1072 dlt_user_log_reattach_to_daemon();
1074 if (dlt_user.overflow)
1076 if (dlt_user_log_send_overflow()==0)
1078 dlt_user.overflow=0;
1083 ret = dlt_user_log_out3(dlt_user.dlt_log_handle,
1084 &(userheader), sizeof(DltUserHeader),
1085 msgdata, size, 0, 0);
1087 /* store message in ringbuffer, if an error has occured */
1088 if (ret!=DLT_RETURN_OK)
1092 if (dlt_buffer_push3(&(dlt_user.startup_buffer),
1093 (unsigned char *)&(userheader), sizeof(DltUserHeader),
1094 msgdata, size, 0, 0)==-1)
1096 dlt_log(LOG_ERR,"Storing message to history buffer failed! Message discarded.\n");
1101 if(dlt_user_queue_resend() < 0 && dlt_user.dlt_log_handle >= 0)
1103 dlt_log(LOG_WARNING, "Failed to queue resending.\n");
1109 case DLT_RETURN_PIPE_FULL:
1111 /* data could not be written */
1112 dlt_user.overflow = 1;
1115 case DLT_RETURN_PIPE_ERROR:
1117 /* handle not open or pipe error */
1118 close(dlt_user.dlt_log_handle);
1119 dlt_user.dlt_log_handle = -1;
1123 case DLT_RETURN_ERROR:
1125 /* other error condition */
1134 /* This case should not occur */
1143 /* ********************************************************************************************* */
1145 inline int dlt_user_log_write_start(DltContext *handle, DltContextData *log,DltLogLevelType loglevel)
1147 return dlt_user_log_write_start_id(handle,log,loglevel,DLT_USER_DEFAULT_MSGID);
1150 int dlt_user_log_write_start_id(DltContext *handle, DltContextData *log,DltLogLevelType loglevel, uint32_t messageid)
1152 if(dlt_user_initialised==0)
1164 if (dlt_user_log_init(handle, log)==-1)
1169 if (dlt_user.dlt_ll_ts==0)
1176 if ((loglevel<=(int)(dlt_user.dlt_ll_ts[handle->log_level_pos].log_level) ) && (loglevel!=0))
1180 log->log_level = loglevel;
1182 /* In non-verbose mode, insert message id */
1183 if (dlt_user.verbose_mode==0)
1185 if ((sizeof(uint32_t))>DLT_USER_BUF_MAX_SIZE)
1189 /* Write message id */
1190 memcpy(log->buffer,&(messageid),sizeof(uint32_t));
1191 log->size = sizeof(uint32_t);
1193 /* as the message id is part of each message in non-verbose mode,
1194 it doesn't increment the argument counter in extended header (if used) */
1208 int dlt_user_log_write_finish(DltContextData *log)
1215 return dlt_user_log_send_log(log, DLT_TYPE_LOG) < 0 ? -1 : 0;
1218 int dlt_user_log_write_raw(DltContextData *log,void *data,uint16_t length)
1228 if ((log->size+length+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1233 if (dlt_user.verbose_mode)
1235 if ((log->size+length+sizeof(uint32_t)+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1240 /* Transmit type information */
1241 type_info = DLT_TYPE_INFO_RAWD;
1243 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1244 log->size += sizeof(uint32_t);
1248 /* First transmit length of raw data, then the raw data itself */
1249 arg_size = (uint16_t)length;
1251 memcpy((log->buffer)+log->size,&(arg_size),sizeof(uint16_t));
1252 log->size += sizeof(uint16_t);
1254 memcpy((log->buffer)+log->size,data,arg_size);
1255 log->size += arg_size;
1262 int dlt_user_log_write_float32(DltContextData *log, float32_t data)
1271 if (sizeof(float32_t)!=4)
1276 if ((log->size+sizeof(float32_t))>DLT_USER_BUF_MAX_SIZE)
1281 if (dlt_user.verbose_mode)
1283 if ((log->size+sizeof(uint32_t)+sizeof(float32_t))>DLT_USER_BUF_MAX_SIZE)
1288 type_info = DLT_TYPE_INFO_FLOA | DLT_TYLE_32BIT;
1290 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1291 log->size += sizeof(uint32_t);
1294 memcpy((log->buffer)+log->size,&data, sizeof(float32_t));
1295 log->size += sizeof(float32_t);
1302 int dlt_user_log_write_float64(DltContextData *log, float64_t data)
1311 if (sizeof(float64_t)!=8)
1316 if ((log->size+sizeof(float64_t))>DLT_USER_BUF_MAX_SIZE)
1321 if (dlt_user.verbose_mode)
1323 if ((log->size+sizeof(uint32_t)+sizeof(float64_t))>DLT_USER_BUF_MAX_SIZE)
1328 type_info = DLT_TYPE_INFO_FLOA | DLT_TYLE_64BIT;
1330 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1331 log->size += sizeof(uint32_t);
1334 memcpy((log->buffer)+log->size,&data, sizeof(float64_t));
1335 log->size += sizeof(float64_t);
1342 int dlt_user_log_write_uint( DltContextData *log, unsigned int data)
1349 switch (sizeof(unsigned int))
1353 return dlt_user_log_write_uint8(log, (uint8_t)data);
1358 return dlt_user_log_write_uint16(log, (uint16_t)data);
1363 return dlt_user_log_write_uint32(log, (uint32_t)data);
1368 return dlt_user_log_write_uint64(log, (uint64_t)data);
1381 int dlt_user_log_write_uint8(DltContextData *log, uint8_t data)
1390 if ((log->size+sizeof(uint8_t))>DLT_USER_BUF_MAX_SIZE)
1395 if (dlt_user.verbose_mode)
1397 if ((log->size+sizeof(uint32_t)+sizeof(uint8_t))>DLT_USER_BUF_MAX_SIZE)
1402 type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_8BIT;
1404 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1405 log->size += sizeof(uint32_t);
1408 memcpy((log->buffer)+log->size,&data,sizeof(uint8_t));
1409 log->size += sizeof(uint8_t);
1416 int dlt_user_log_write_uint16(DltContextData *log, uint16_t data)
1425 if ((log->size+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1430 if (dlt_user.verbose_mode)
1432 if ((log->size+sizeof(uint32_t)+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1437 type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_16BIT;
1439 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1440 log->size += sizeof(uint32_t);
1443 memcpy((log->buffer)+log->size,&data,sizeof(uint16_t));
1444 log->size += sizeof(uint16_t);
1451 int dlt_user_log_write_uint32(DltContextData *log, uint32_t data)
1460 if ((log->size+sizeof(uint32_t))>DLT_USER_BUF_MAX_SIZE)
1465 if (dlt_user.verbose_mode)
1467 if ((log->size+sizeof(uint32_t)+sizeof(uint32_t))>DLT_USER_BUF_MAX_SIZE)
1472 type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_32BIT;
1474 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1475 log->size += sizeof(uint32_t);
1478 memcpy((log->buffer)+log->size,&data, sizeof(uint32_t));
1479 log->size += sizeof(uint32_t);
1486 int dlt_user_log_write_uint64(DltContextData *log, uint64_t data)
1495 if ((log->size+sizeof(uint64_t))>DLT_USER_BUF_MAX_SIZE)
1500 if (dlt_user.verbose_mode)
1502 if ((log->size+sizeof(uint32_t)+sizeof(uint64_t))>DLT_USER_BUF_MAX_SIZE)
1507 type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_64BIT;
1509 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1510 log->size +=sizeof(uint32_t);
1513 memcpy((log->buffer)+log->size,&data,sizeof(uint64_t));
1514 log->size += sizeof(uint64_t);
1521 int dlt_user_log_write_int(DltContextData *log, int data)
1528 switch (sizeof(int))
1532 return dlt_user_log_write_int8(log, (int8_t)data);
1537 return dlt_user_log_write_int16(log, (int16_t)data);
1542 return dlt_user_log_write_int32(log, (int32_t)data);
1547 return dlt_user_log_write_int64(log, (int64_t)data);
1560 int dlt_user_log_write_int8(DltContextData *log, int8_t data)
1569 if ((log->size+sizeof(int8_t))>DLT_USER_BUF_MAX_SIZE)
1574 if (dlt_user.verbose_mode)
1576 if ((log->size+sizeof(uint32_t)+sizeof(int8_t))>DLT_USER_BUF_MAX_SIZE)
1581 type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_8BIT;
1583 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1584 log->size += sizeof(uint32_t);
1587 memcpy((log->buffer)+log->size,&data,sizeof(int8_t));
1588 log->size += sizeof(int8_t);
1595 int dlt_user_log_write_int16(DltContextData *log, int16_t data)
1604 if ((log->size+sizeof(int16_t))>DLT_USER_BUF_MAX_SIZE)
1609 if (dlt_user.verbose_mode)
1611 if ((log->size+sizeof(uint32_t)+sizeof(int16_t))>DLT_USER_BUF_MAX_SIZE)
1616 type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_16BIT;
1618 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1619 log->size += sizeof(uint32_t);
1622 memcpy((log->buffer)+log->size,&data,sizeof(int16_t));
1623 log->size += sizeof(int16_t);
1630 int dlt_user_log_write_int32(DltContextData *log, int32_t data)
1639 if ((log->size+sizeof(int32_t))>DLT_USER_BUF_MAX_SIZE)
1644 if (dlt_user.verbose_mode)
1646 if ((log->size+sizeof(uint32_t)+sizeof(int32_t))>DLT_USER_BUF_MAX_SIZE)
1651 type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_32BIT;
1653 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1654 log->size += sizeof(uint32_t);
1657 memcpy((log->buffer)+log->size,&data, sizeof(int32_t));
1658 log->size += sizeof(int32_t);
1665 int dlt_user_log_write_int64(DltContextData *log, int64_t data)
1674 if ((log->size+sizeof(int64_t))>DLT_USER_BUF_MAX_SIZE)
1679 if (dlt_user.verbose_mode)
1681 if ((log->size+sizeof(uint32_t)+sizeof(int64_t))>DLT_USER_BUF_MAX_SIZE)
1686 type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_64BIT;
1688 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1689 log->size += sizeof(uint32_t);
1692 memcpy((log->buffer)+log->size,&data,sizeof(int64_t));
1693 log->size += sizeof(int64_t);
1700 int dlt_user_log_write_bool(DltContextData *log, uint8_t data)
1709 if ((log->size+sizeof(uint8_t))>DLT_USER_BUF_MAX_SIZE)
1714 if (dlt_user.verbose_mode)
1716 if ((log->size+sizeof(uint32_t)+sizeof(uint8_t))>DLT_USER_BUF_MAX_SIZE)
1721 type_info = DLT_TYPE_INFO_BOOL;
1723 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1724 log->size += sizeof(uint32_t);
1727 memcpy((log->buffer)+log->size,&data,sizeof(uint8_t));
1728 log->size += sizeof(uint8_t);
1735 int dlt_user_log_write_string(DltContextData *log, const char *text)
1740 if ((log==0) || (text==0))
1745 if ((log->size+(strlen(text)+1)+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1750 if (dlt_user.verbose_mode)
1752 if ((log->size+(strlen(text)+1)+sizeof(uint32_t)+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1757 type_info = DLT_TYPE_INFO_STRG;
1759 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1760 log->size += sizeof(uint32_t);
1763 arg_size = strlen(text) + 1;
1765 memcpy((log->buffer)+log->size,&(arg_size),sizeof(uint16_t));
1766 log->size += sizeof(uint16_t);
1768 memcpy((log->buffer)+log->size,text,arg_size);
1769 log->size += arg_size;
1776 int dlt_register_injection_callback(DltContext *handle, uint32_t service_id,
1777 int (*dlt_injection_callback)(uint32_t service_id, void *data, uint32_t length))
1783 DltUserInjectionCallback *old;
1790 if (dlt_user_log_init(handle, &log)==-1)
1795 if (service_id<DLT_USER_INJECTION_MIN)
1799 /* This function doesn't make sense storing to local file is choosen;
1800 so terminate this function */
1801 if (dlt_user.dlt_is_file)
1808 if (dlt_user.dlt_ll_ts==0)
1814 /* Insert callback in corresponding table */
1815 i=handle->log_level_pos;
1817 /* Insert each service_id only once */
1818 for (k=0;k<dlt_user.dlt_ll_ts[i].nrcallbacks;k++)
1820 if ((dlt_user.dlt_ll_ts[i].injection_table) &&
1821 (dlt_user.dlt_ll_ts[i].injection_table[k].service_id == service_id))
1834 j=dlt_user.dlt_ll_ts[i].nrcallbacks;
1836 /* Allocate or expand injection table */
1837 if (dlt_user.dlt_ll_ts[i].injection_table == 0)
1839 dlt_user.dlt_ll_ts[i].injection_table = (DltUserInjectionCallback*) malloc(sizeof(DltUserInjectionCallback));
1840 if(dlt_user.dlt_ll_ts[i].injection_table == 0)
1848 old = dlt_user.dlt_ll_ts[i].injection_table;
1849 dlt_user.dlt_ll_ts[i].injection_table = (DltUserInjectionCallback*) malloc(sizeof(DltUserInjectionCallback)*(j+1));
1850 if(dlt_user.dlt_ll_ts[i].injection_table == 0)
1852 dlt_user.dlt_ll_ts[i].injection_table = old;
1856 memcpy(dlt_user.dlt_ll_ts[i].injection_table,old,sizeof(DltUserInjectionCallback)*j);
1860 dlt_user.dlt_ll_ts[i].nrcallbacks++;
1863 /* Store service_id and corresponding function pointer for callback function */
1864 dlt_user.dlt_ll_ts[i].injection_table[j].service_id = service_id;
1865 dlt_user.dlt_ll_ts[i].injection_table[j].injection_callback = dlt_injection_callback;
1878 int total_size, used_size;
1879 dlt_user_check_buffer(&total_size, &used_size);
1881 if((total_size - used_size) < (total_size/2))
1889 * Send the start of a segment chain.
1890 * Returns -1 on failure
1892 int dlt_user_trace_network_segmented_start(uint16_t *id, DltContext *handle, DltNetworkTraceType nw_trace_type, uint16_t header_len, void *header, uint16_t payload_len)
1903 if (dlt_user_log_init(handle, &log)==-1)
1910 if (dlt_user.dlt_ll_ts==0)
1916 if (dlt_user.dlt_ll_ts[handle->log_level_pos].trace_status==DLT_TRACE_STATUS_ON)
1921 log.trace_status = nw_trace_type;
1924 gettimeofday(&tv, NULL);
1927 /* Write identifier */
1928 if(dlt_user_log_write_string(&log, "NWST") < 0)
1933 /* Write stream handle */
1934 if(dlt_user_log_write_uint16(&log, *id) < 0)
1940 if(dlt_user_log_write_raw(&log, header, header_len) < 0)
1945 /* Write size of payload */
1946 if(dlt_user_log_write_uint16(&log, payload_len) < 0)
1951 /* Write expected segment count */
1952 uint16_t segment_count = payload_len/DLT_MAX_TRACE_SEGMENT_SIZE+1;
1954 /* If segments align perfectly with segment size, avoid sending empty segment */
1955 if((payload_len % DLT_MAX_TRACE_SEGMENT_SIZE) == 0)
1960 if(dlt_user_log_write_uint16(&log, segment_count) < 0)
1965 /* Write length of one segment */
1966 if(dlt_user_log_write_uint16(&log, DLT_MAX_TRACE_SEGMENT_SIZE) < 0)
1972 return dlt_user_log_send_log(&log, DLT_TYPE_NW_TRACE);
1981 int dlt_user_trace_network_segmented_segment(uint16_t id, DltContext *handle, DltNetworkTraceType nw_trace_type, int sequence, uint16_t payload_len, void *payload)
1983 while(check_buffer() < 0)
1985 usleep(1000*50); // Wait 50ms
1986 dlt_user_log_resend_buffer();
1996 if (dlt_user_log_init(handle, &log)==-1)
2003 if (dlt_user.dlt_ll_ts==0)
2009 if (dlt_user.dlt_ll_ts[handle->log_level_pos].trace_status==DLT_TRACE_STATUS_ON)
2014 log.trace_status = nw_trace_type;
2017 /* Write identifier */
2018 if(dlt_user_log_write_string(&log, "NWCH") < 0)
2023 /* Write stream handle */
2024 if(dlt_user_log_write_uint16(&log, id) < 0)
2029 /* Write segment sequence number */
2030 if(dlt_user_log_write_uint16(&log, sequence) < 0)
2036 if(dlt_user_log_write_raw(&log, payload, payload_len) < 0)
2042 return dlt_user_log_send_log(&log, DLT_TYPE_NW_TRACE);
2049 /* Allow other threads to log between chunks */
2054 int dlt_user_trace_network_segmented_end(uint16_t id, DltContext *handle, DltNetworkTraceType nw_trace_type)
2063 if (dlt_user_log_init(handle, &log)==-1)
2072 if (dlt_user.dlt_ll_ts==0)
2078 if (dlt_user.dlt_ll_ts[handle->log_level_pos].trace_status==DLT_TRACE_STATUS_ON)
2083 log.trace_status = nw_trace_type;
2086 /* Write identifier */
2087 if(dlt_user_log_write_string(&log, "NWEN") < 0)
2092 /* Write stream handle */
2093 if(dlt_user_log_write_uint(&log, id) < 0)
2099 return dlt_user_log_send_log(&log, DLT_TYPE_NW_TRACE);
2108 void dlt_user_trace_network_segmented_thread(void *unused)
2110 /* Unused on purpose. */
2113 s_segmented_data *data;
2117 // Wait untill message queue is initialized
2118 pthread_mutex_lock(&mq_mutex);
2119 if(dlt_user.dlt_segmented_queue_read_handle < 0)
2121 pthread_cond_wait(&mq_init_condition, &mq_mutex);
2123 pthread_mutex_unlock(&mq_mutex);
2125 ssize_t read = mq_receive(dlt_user.dlt_segmented_queue_read_handle, (char *)&data,
2126 sizeof(s_segmented_data * ), NULL);
2128 if(read != sizeof(s_segmented_data *))
2130 dlt_log(LOG_ERR, "NWTSegmented: Error while reading queue.\n");
2131 dlt_log(LOG_ERR, strerror(errno));
2135 /* Indicator just to try to flush the buffer */
2136 if(data->payload_len == DLT_DELAYED_RESEND_INDICATOR_PATTERN)
2138 // Sleep 100ms, to allow other process to read FIFO
2140 if(dlt_user_log_resend_buffer() < 0)
2142 // Requeue if still not empty
2143 dlt_user_queue_resend();
2149 /* Segment the data and send the chunks */
2151 uint16_t offset = 0;
2152 uint16_t sequence = 0;
2156 if(offset + DLT_MAX_TRACE_SEGMENT_SIZE > data->payload_len)
2158 len = data->payload_len - offset;
2162 len = DLT_MAX_TRACE_SEGMENT_SIZE;
2164 /* If payload size aligns perfectly with segment size, avoid sendind empty segment */
2170 ptr = data->payload + offset;
2171 DltReturnValue err = dlt_user_trace_network_segmented_segment(data->id, data->handle, data->nw_trace_type, sequence++, len, ptr);
2172 if(err == DLT_RETURN_BUFFER_FULL || err == DLT_RETURN_ERROR)
2174 dlt_log(LOG_ERR,"NWTSegmented: Could not send segment. Aborting.\n");
2175 break; // Inner loop
2178 }while(ptr < data->payload + data->payload_len);
2180 /* Send the end message */
2181 DltReturnValue err = dlt_user_trace_network_segmented_end(data->id, data->handle, data->nw_trace_type);
2182 if(err == DLT_RETURN_BUFFER_FULL || err == DLT_RETURN_ERROR)
2184 dlt_log(LOG_ERR,"NWTSegmented: Could not send end segment.\n");
2187 /* Free resources */
2189 free(data->payload);
2194 int dlt_user_trace_network_segmented(DltContext *handle, DltNetworkTraceType nw_trace_type, uint16_t header_len, void *header, uint16_t payload_len, void *payload)
2196 /* Send as normal trace if possible */
2197 if(header_len+payload_len+sizeof(uint16_t) < DLT_USER_BUF_MAX_SIZE) {
2198 return dlt_user_trace_network(handle, nw_trace_type, header_len, header, payload_len, payload);
2201 /* Allocate Memory */
2202 s_segmented_data *thread_data = malloc(sizeof(s_segmented_data));
2203 if(thread_data == NULL)
2207 thread_data->header = malloc(header_len);
2208 if(thread_data->header == NULL)
2213 thread_data->payload = malloc(payload_len);
2214 if(thread_data->payload == NULL)
2216 free(thread_data->header);
2222 thread_data->handle = handle;
2223 thread_data->nw_trace_type = nw_trace_type;
2224 thread_data->header_len = header_len;
2225 memcpy(thread_data->header, header, header_len);
2226 thread_data->payload_len = payload_len;
2227 memcpy(thread_data->payload, payload, payload_len);
2229 /* Send start message */
2230 DltReturnValue err = dlt_user_trace_network_segmented_start(&(thread_data->id),
2231 thread_data->handle, thread_data->nw_trace_type,
2232 thread_data->header_len, thread_data->header,
2233 thread_data->payload_len);
2234 if(err == DLT_RETURN_BUFFER_FULL || err == DLT_RETURN_ERROR)
2236 dlt_log(LOG_ERR,"NWTSegmented: Could not send start segment. Aborting.\n");
2237 free(thread_data->header);
2238 free(thread_data->payload);
2243 /* Open queue if it is not open */
2244 if(dlt_init_message_queue() < 0)
2246 dlt_log(LOG_ERR, "NWTSegmented: Could not open queue.\n");
2247 free(thread_data->header);
2248 free(thread_data->payload);
2255 if(mq_send(dlt_user.dlt_segmented_queue_write_handle,
2256 (char *)&thread_data, sizeof(s_segmented_data *), 1) < 0)
2260 dlt_log(LOG_ERR, "NWTSegmented: Queue full. Message discarded.\n");
2262 free(thread_data->header);
2263 free(thread_data->payload);
2265 dlt_log(LOG_ERR, "NWTSegmented: Could not write into queue.\n");
2266 dlt_log(LOG_ERR, strerror(errno));
2272 int dlt_user_trace_network(DltContext *handle, DltNetworkTraceType nw_trace_type, uint16_t header_len, void *header, uint16_t payload_len, void *payload)
2274 return dlt_user_trace_network_truncated(handle, nw_trace_type, header_len, header, payload_len, payload, 1);
2277 int dlt_user_trace_network_truncated(DltContext *handle, DltNetworkTraceType nw_trace_type, uint16_t header_len, void *header, uint16_t payload_len, void *payload, int allow_truncate)
2281 if (dlt_user_initialised==0)
2289 if (dlt_user_log_init(handle, &log)==-1)
2299 /* Commented out because of DltNetworkTraceType:
2301 if ((nw_trace_type<=0) || (nw_trace_type>0x15))
2310 if (dlt_user.dlt_ll_ts==0)
2316 if (dlt_user.dlt_ll_ts[handle->log_level_pos].trace_status==DLT_TRACE_STATUS_ON)
2321 log.trace_status = nw_trace_type;
2329 /* If truncation is allowed, check if we must do it */
2330 if(allow_truncate > 0 && (header_len+payload_len+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
2332 /* Identify as truncated */
2333 if(dlt_user_log_write_string(&log, "NWTR") < 0)
2338 /* Write header and its length */
2339 if (dlt_user_log_write_raw(&log, header, header_len) < 0)
2344 /* Write original size of payload */
2345 if(dlt_user_log_write_uint16(&log, payload_len) < 0)
2351 * Calculate maximum avaialble space in sending buffer after headers.
2354 int truncated_payload_len = DLT_USER_BUF_MAX_SIZE -
2355 log.size - sizeof(uint16_t) - sizeof(uint32_t);
2357 /* Write truncated payload */
2358 if (dlt_user_log_write_raw(&log, payload, truncated_payload_len) < 0)
2363 else /* Truncation not allowed or data short enough */
2365 /* Write header and its length */
2366 if (dlt_user_log_write_raw(&log, header, header_len)==-1)
2376 /* Write payload and its length */
2377 if (dlt_user_log_write_raw(&log, payload, payload_len)==-1)
2384 return dlt_user_log_send_log(&log, DLT_TYPE_NW_TRACE);
2394 int dlt_log_string(DltContext *handle,DltLogLevelType loglevel, const char *text)
2398 if (dlt_user.verbose_mode==0)
2403 if ((handle==0) || (text==0))
2408 if (dlt_user_log_write_start(handle,&log,loglevel)>0)
2410 if (dlt_user_log_write_string(&log,text)==-1)
2414 if (dlt_user_log_write_finish(&log)==-1)
2423 int dlt_log_string_int(DltContext *handle,DltLogLevelType loglevel, const char *text, int data)
2427 if (dlt_user.verbose_mode==0)
2432 if ((handle==0) || (text==0))
2437 if (dlt_user_log_write_start(handle,&log,loglevel)>0)
2439 if (dlt_user_log_write_string(&log,text)==-1)
2443 if (dlt_user_log_write_int(&log,data)==-1)
2447 if (dlt_user_log_write_finish(&log)==-1)
2456 int dlt_log_string_uint(DltContext *handle,DltLogLevelType loglevel, const char *text, unsigned int data)
2460 if (dlt_user.verbose_mode==0)
2465 if ((handle==0) || (text==0))
2470 if (dlt_user_log_write_start(handle,&log,loglevel)>0)
2472 if (dlt_user_log_write_string(&log,text)==-1)
2476 if (dlt_user_log_write_uint(&log,data)==-1)
2480 if (dlt_user_log_write_finish(&log)==-1)
2489 int dlt_log_int(DltContext *handle,DltLogLevelType loglevel, int data)
2493 if (dlt_user.verbose_mode==0)
2503 if (dlt_user_log_write_start(handle,&log,loglevel)>0)
2505 if (dlt_user_log_write_int(&log,data)==-1)
2509 if (dlt_user_log_write_finish(&log)==-1)
2518 int dlt_log_uint(DltContext *handle,DltLogLevelType loglevel, unsigned int data)
2522 if (dlt_user.verbose_mode==0)
2532 if (dlt_user_log_write_start(handle,&log,loglevel)>0)
2534 if (dlt_user_log_write_uint(&log,data)==-1)
2538 if (dlt_user_log_write_finish(&log)==-1)
2547 int dlt_log_raw(DltContext *handle,DltLogLevelType loglevel, void *data,uint16_t length)
2551 if (dlt_user.verbose_mode==0)
2561 if (dlt_user_log_write_start(handle,&log,loglevel)>0)
2563 if (dlt_user_log_write_raw(&log,data,length)==-1)
2567 if (dlt_user_log_write_finish(&log)==-1)
2576 int dlt_verbose_mode(void)
2578 if (dlt_user_initialised==0)
2586 /* Switch to verbose mode */
2587 dlt_user.verbose_mode = 1;
2592 int dlt_nonverbose_mode(void)
2594 if (dlt_user_initialised==0)
2602 /* Switch to non-verbose mode */
2603 dlt_user.verbose_mode = 0;
2608 int dlt_enable_local_print(void)
2610 if (dlt_user_initialised==0)
2618 dlt_user.enable_local_print = 1;
2623 int dlt_disable_local_print(void)
2625 if (dlt_user_initialised==0)
2633 dlt_user.enable_local_print = 0;
2638 void dlt_user_receiverthread_function(__attribute__((unused)) void *ptr)
2642 /* Check for new messages from DLT daemon */
2643 if (dlt_user_log_check_user_message()==-1)
2645 /* Critical error */
2646 dlt_log(LOG_CRIT,"Receiver thread encountered error condition\n");
2649 usleep(DLT_USER_RECEIVE_DELAY); /* delay */
2653 /* Private functions of user library */
2655 int dlt_user_log_init(DltContext *handle, DltContextData *log)
2657 if (dlt_user_initialised==0)
2665 log->handle = handle;
2670 int dlt_user_queue_resend(void)
2672 if(dlt_user.dlt_log_handle < 0)
2674 // Fail silenty. FIFO is not open yet
2678 * Ask segmented thread to try emptying the buffer soon.
2679 * This will be freed in dlt_user_trace_network_segmented_thread
2681 s_segmented_data *resend_data = malloc(sizeof(s_segmented_data));
2683 if (NULL == resend_data)
2688 resend_data->payload_len = DLT_DELAYED_RESEND_INDICATOR_PATTERN;
2692 /* Open queue if it is not open */
2693 if(dlt_init_message_queue() < 0)
2695 dlt_log(LOG_ERR, "NWTSegmented: Could not open queue.\n");
2700 if(mq_send(dlt_user.dlt_segmented_queue_write_handle, (char *)&resend_data, sizeof(s_segmented_data *), 1) < 0)
2702 dlt_log(LOG_ERR,"Could not request resending.\n");
2703 dlt_log(LOG_ERR, strerror(errno));
2711 DltReturnValue dlt_user_log_send_log(DltContextData *log, int mtype)
2714 DltUserHeader userheader;
2717 DltReturnValue ret = DLT_RETURN_OK;
2721 return DLT_RETURN_ERROR;
2726 return DLT_RETURN_ERROR;
2729 if (dlt_user.appID[0]=='\0')
2731 return DLT_RETURN_ERROR;
2734 if (log->handle->contextID[0]=='\0')
2736 return DLT_RETURN_ERROR;
2739 if ((mtype<DLT_TYPE_LOG) || (mtype>DLT_TYPE_CONTROL))
2741 return DLT_RETURN_ERROR;
2744 /* also for Trace messages */
2745 #ifdef DLT_SHM_ENABLE
2746 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG_SHM)==-1)
2748 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG)==-1)
2751 return DLT_RETURN_ERROR;
2754 if (dlt_message_init(&msg,0)==-1)
2756 return DLT_RETURN_ERROR;
2759 msg.storageheader = (DltStorageHeader*)msg.headerbuffer;
2761 if (dlt_set_storageheader(msg.storageheader,dlt_user.ecuID)==-1)
2763 return DLT_RETURN_ERROR;
2766 msg.standardheader = (DltStandardHeader*)(msg.headerbuffer + sizeof(DltStorageHeader));
2767 msg.standardheader->htyp = DLT_HTYP_WEID | DLT_HTYP_WTMS | DLT_HTYP_PROTOCOL_VERSION1 ;
2769 if (dlt_user.verbose_mode)
2771 /* In verbose mode, send extended header */
2772 msg.standardheader->htyp = (msg.standardheader->htyp | DLT_HTYP_UEH );
2776 /* In non-verbose, send extended header if desired */
2777 #if (DLT_USER_USE_EXTENDED_HEADER_FOR_NONVERBOSE==1)
2778 msg.standardheader->htyp = (msg.standardheader->htyp | DLT_HTYP_UEH );
2782 #if (BYTE_ORDER==BIG_ENDIAN)
2783 msg.standardheader->htyp = (msg.standardheader->htyp | DLT_HTYP_MSBF);
2786 msg.standardheader->mcnt = log->handle->mcnt++;
2788 /* Set header extra parameters */
2789 dlt_set_id(msg.headerextra.ecu,dlt_user.ecuID);
2790 //msg.headerextra.seid = 0;
2791 msg.headerextra.tmsp = dlt_uptime();
2793 if (dlt_message_set_extraparameters(&msg,0)==-1)
2795 return DLT_RETURN_ERROR;
2798 /* Fill out extended header, if extended header should be provided */
2799 if (DLT_IS_HTYP_UEH(msg.standardheader->htyp))
2801 /* with extended header */
2802 msg.extendedheader = (DltExtendedHeader*)(msg.headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp) );
2808 msg.extendedheader->msin = (DLT_TYPE_LOG << DLT_MSIN_MSTP_SHIFT) | ((log->log_level << DLT_MSIN_MTIN_SHIFT) & DLT_MSIN_MTIN) ; /* messsage info */
2811 case DLT_TYPE_NW_TRACE:
2813 msg.extendedheader->msin = (DLT_TYPE_NW_TRACE << DLT_MSIN_MSTP_SHIFT) | ((log->trace_status << DLT_MSIN_MTIN_SHIFT) & DLT_MSIN_MTIN) ; /* messsage info */
2818 /* This case should not occur */
2819 return DLT_RETURN_ERROR;
2824 /* If in verbose mode, set flag in header for verbose mode */
2825 if (dlt_user.verbose_mode)
2827 msg.extendedheader->msin |= DLT_MSIN_VERB;
2830 msg.extendedheader->noar = log->args_num; /* number of arguments */
2831 dlt_set_id(msg.extendedheader->apid,dlt_user.appID); /* application id */
2832 dlt_set_id(msg.extendedheader->ctid,log->handle->contextID); /* context id */
2834 msg.headersize = sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + sizeof(DltExtendedHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp);
2838 /* without extended header */
2839 msg.headersize = sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp);
2842 len=msg.headersize - sizeof(DltStorageHeader) +log->size;
2845 dlt_log(LOG_CRIT,"Huge message discarded!\n");
2846 return DLT_RETURN_ERROR;
2849 msg.standardheader->len = DLT_HTOBE_16(len);
2851 /* print to std out, if enabled */
2852 if ((dlt_user.local_print_mode != DLT_PM_FORCE_OFF) &&
2853 (dlt_user.local_print_mode != DLT_PM_AUTOMATIC))
2855 if ((dlt_user.enable_local_print) || (dlt_user.local_print_mode == DLT_PM_FORCE_ON))
2857 if (dlt_user_print_msg(&msg, log)==-1)
2859 return DLT_RETURN_ERROR;
2864 if (dlt_user.dlt_is_file)
2867 ret=dlt_user_log_out2(dlt_user.dlt_log_handle, msg.headerbuffer, msg.headersize, log->buffer, log->size);
2872 /* Reattach to daemon if neccesary */
2873 dlt_user_log_reattach_to_daemon();
2875 if (dlt_user.overflow)
2877 if (dlt_user_log_send_overflow()==0)
2879 dlt_user.overflow=0;
2883 /* try to resent old data first */
2884 ret = DLT_RETURN_OK;
2885 if(dlt_user.dlt_log_handle!=-1)
2886 ret = dlt_user_log_resend_buffer();
2887 if(ret==DLT_RETURN_OK)
2889 /* resend ok or nothing to resent */
2890 #ifdef DLT_SHM_ENABLE
2891 if(dlt_user.dlt_log_handle!=-1)
2892 dlt_shm_push(&dlt_user.dlt_shm,msg.headerbuffer+sizeof(DltStorageHeader), msg.headersize-sizeof(DltStorageHeader),
2893 log->buffer, log->size,0,0);
2896 ret = dlt_user_log_out3(dlt_user.dlt_log_handle,
2897 &(userheader), sizeof(DltUserHeader),
2902 #ifdef DLT_TEST_ENABLE
2903 if(dlt_user.corrupt_user_header) {
2904 userheader.pattern[0]=0xff;
2905 userheader.pattern[1]=0xff;
2906 userheader.pattern[2]=0xff;
2907 userheader.pattern[3]=0xff;
2909 if(dlt_user.corrupt_message_size) {
2910 msg.standardheader->len = DLT_HTOBE_16(dlt_user.corrupt_message_size_size);
2913 ret = dlt_user_log_out3(dlt_user.dlt_log_handle,
2914 &(userheader), sizeof(DltUserHeader),
2915 msg.headerbuffer+sizeof(DltStorageHeader), msg.headersize-sizeof(DltStorageHeader),
2916 log->buffer, log->size);
2920 /* store message in ringbuffer, if an error has occured */
2921 if (ret!=DLT_RETURN_OK)
2925 if (dlt_buffer_push3(&(dlt_user.startup_buffer),
2926 (unsigned char *)&(userheader), sizeof(DltUserHeader),
2927 msg.headerbuffer+sizeof(DltStorageHeader), msg.headersize-sizeof(DltStorageHeader),
2928 log->buffer, log->size)==-1)
2930 dlt_log(LOG_ERR,"Storing message to history buffer failed! Message discarded.\n");
2931 ret = DLT_RETURN_BUFFER_FULL;
2936 // Fail silenty if FIFO is not open
2937 if(dlt_user_queue_resend() < 0 && dlt_user.dlt_log_handle >= 0)
2939 dlt_log(LOG_WARNING, "Failed to queue resending.\n");
2945 case DLT_RETURN_BUFFER_FULL:
2948 return DLT_RETURN_BUFFER_FULL;
2950 case DLT_RETURN_PIPE_FULL:
2952 /* data could not be written */
2953 dlt_user.overflow = 1;
2954 return DLT_RETURN_PIPE_FULL;
2956 case DLT_RETURN_PIPE_ERROR:
2958 /* handle not open or pipe error */
2959 close(dlt_user.dlt_log_handle);
2960 dlt_user.dlt_log_handle = -1;
2962 #ifdef DLT_SHM_ENABLE
2963 /* free shared memory */
2964 dlt_shm_free_client(&dlt_user.dlt_shm);
2967 if (dlt_user.local_print_mode == DLT_PM_AUTOMATIC)
2969 dlt_user_print_msg(&msg, log);
2972 return DLT_RETURN_PIPE_ERROR;
2974 case DLT_RETURN_ERROR:
2976 /* other error condition */
2977 return DLT_RETURN_ERROR;
2981 return DLT_RETURN_OK;
2985 /* This case should never occur. */
2986 return DLT_RETURN_ERROR;
2991 return DLT_RETURN_OK;
2994 int dlt_user_log_send_register_application(void)
2996 DltUserHeader userheader;
2997 DltUserControlMsgRegisterApplication usercontext;
3001 if (dlt_user.appID[0]=='\0')
3006 /* set userheader */
3007 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_REGISTER_APPLICATION)==-1)
3012 /* set usercontext */
3013 dlt_set_id(usercontext.apid,dlt_user.appID); /* application id */
3014 usercontext.pid = getpid();
3016 if (dlt_user.application_description!=0)
3018 usercontext.description_length = strlen(dlt_user.application_description);
3022 usercontext.description_length = 0;
3025 if (dlt_user.dlt_is_file)
3031 ret=dlt_user_log_out3(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgRegisterApplication),dlt_user.application_description,usercontext.description_length);
3033 /* store message in ringbuffer, if an error has occured */
3034 if (ret!=DLT_RETURN_OK)
3038 if (dlt_buffer_push3(&(dlt_user.startup_buffer),
3039 (unsigned char *)&(userheader), sizeof(DltUserHeader),
3040 (const unsigned char*)&(usercontext), sizeof(DltUserControlMsgRegisterApplication),
3041 (const unsigned char*)dlt_user.application_description, usercontext.description_length)==-1)
3043 dlt_log(LOG_ERR,"Storing message to history buffer failed! Message discarded.\n");
3050 if(dlt_user_queue_resend() < 0 && dlt_user.dlt_log_handle >= 0)
3052 dlt_log(LOG_WARNING, "Failed to queue resending.\n");
3059 int dlt_user_log_send_unregister_application(void)
3061 DltUserHeader userheader;
3062 DltUserControlMsgUnregisterApplication usercontext;
3066 if (dlt_user.appID[0]=='\0')
3071 /* set userheader */
3072 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_UNREGISTER_APPLICATION)==-1)
3077 /* set usercontext */
3078 dlt_set_id(usercontext.apid,dlt_user.appID); /* application id */
3079 usercontext.pid = getpid();
3081 if (dlt_user.dlt_is_file)
3087 ret=dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgUnregisterApplication));
3088 return ((ret==DLT_RETURN_OK)?0:-1);
3091 int dlt_user_log_send_register_context(DltContextData *log)
3093 DltUserHeader userheader;
3094 DltUserControlMsgRegisterContext usercontext;
3107 if ((dlt_user.appID[0]=='\0') || (log->handle->contextID=='\0'))
3112 /* set userheader */
3113 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_REGISTER_CONTEXT)==-1)
3118 /* set usercontext */
3119 dlt_set_id(usercontext.apid,dlt_user.appID); /* application id */
3120 dlt_set_id(usercontext.ctid,log->handle->contextID); /* context id */
3121 usercontext.log_level_pos = log->handle->log_level_pos;
3122 usercontext.pid = getpid();
3124 usercontext.log_level = (int8_t)log->log_level;
3125 usercontext.trace_status = (int8_t)log->trace_status;
3127 if (log->context_description!=0)
3129 usercontext.description_length = strlen(log->context_description);
3133 usercontext.description_length = 0;
3136 if (dlt_user.dlt_is_file)
3142 ret=dlt_user_log_out3(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgRegisterContext),log->context_description,usercontext.description_length);
3144 /* store message in ringbuffer, if an error has occured */
3145 if (ret!=DLT_RETURN_OK)
3149 if (dlt_buffer_push3(&(dlt_user.startup_buffer),
3150 (unsigned char *)&(userheader), sizeof(DltUserHeader),
3151 (const unsigned char*)&(usercontext), sizeof(DltUserControlMsgRegisterContext),
3152 (const unsigned char*)log->context_description, usercontext.description_length)==-1)
3154 dlt_log(LOG_ERR,"Storing message to history buffer failed! Message discarded.\n");
3161 if(dlt_user_queue_resend() < 0 && dlt_user.dlt_log_handle >= 0)
3163 dlt_log(LOG_WARNING, "Failed to queue resending.\n");
3171 int dlt_user_log_send_unregister_context(DltContextData *log)
3173 DltUserHeader userheader;
3174 DltUserControlMsgUnregisterContext usercontext;
3187 if ((dlt_user.appID[0]=='\0') || (log->handle->contextID=='\0'))
3192 /* set userheader */
3193 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_UNREGISTER_CONTEXT)==-1)
3198 /* set usercontext */
3199 dlt_set_id(usercontext.apid,dlt_user.appID); /* application id */
3200 dlt_set_id(usercontext.ctid,log->handle->contextID); /* context id */
3201 usercontext.pid = getpid();
3203 if (dlt_user.dlt_is_file)
3209 ret=dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgUnregisterContext));
3210 return ((ret==DLT_RETURN_OK)?0:-1);
3213 int dlt_send_app_ll_ts_limit(const char *appid, DltLogLevelType loglevel, DltTraceStatusType tracestatus)
3215 DltUserHeader userheader;
3216 DltUserControlMsgAppLogLevelTraceStatus usercontext;
3219 if ((appid==0) || (appid[0]=='\0'))
3224 /* Removed because of DltLogLevelType and DltTraceStatusType
3226 if ((loglevel<DLT_LOG_DEFAULT) || (loglevel>DLT_LOG_VERBOSE))
3231 if ((tracestatus<DLT_TRACE_STATUS_DEFAULT) || (tracestatus>DLT_TRACE_STATUS_ON))
3238 /* set userheader */
3239 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_APP_LL_TS)==-1)
3244 /* set usercontext */
3245 dlt_set_id(usercontext.apid,appid); /* application id */
3246 usercontext.log_level = loglevel;
3247 usercontext.trace_status = tracestatus;
3249 if (dlt_user.dlt_is_file)
3255 ret=dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgAppLogLevelTraceStatus));
3256 return ((ret==DLT_RETURN_OK)?0:-1);
3259 int dlt_user_log_send_log_mode(DltUserLogMode mode)
3261 DltUserHeader userheader;
3262 DltUserControlMsgLogMode logmode;
3266 /* set userheader */
3267 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG_MODE)==-1)
3273 logmode.log_mode = (unsigned char) mode;
3275 if (dlt_user.dlt_is_file)
3281 ret=dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(logmode), sizeof(DltUserControlMsgLogMode));
3282 return ((ret==DLT_RETURN_OK)?0:-1);
3285 int dlt_user_print_msg(DltMessage *msg, DltContextData *log)
3287 uint8_t *databuffer_tmp;
3288 int32_t datasize_tmp;
3289 int32_t databuffersize_tmp;
3290 static char text[DLT_USER_TEXT_LENGTH];
3292 if ((msg==0) || (log==0))
3297 /* Save variables before print */
3298 databuffer_tmp = msg->databuffer;
3299 datasize_tmp = msg->datasize;
3300 databuffersize_tmp = msg->databuffersize;
3302 /* Act like a receiver, convert header back to host format */
3303 msg->standardheader->len = DLT_BETOH_16(msg->standardheader->len);
3304 dlt_message_get_extraparameters(msg,0);
3306 msg->databuffer = log->buffer;
3307 msg->datasize = log->size;
3308 msg->databuffersize = log->size;
3310 /* Print message as ASCII */
3311 if (dlt_message_print_ascii(msg,text,DLT_USER_TEXT_LENGTH,0)==-1)
3316 /* Restore variables and set len to BE*/
3317 msg->databuffer = databuffer_tmp;
3318 msg->databuffersize = databuffersize_tmp;
3319 msg->datasize = datasize_tmp;
3321 msg->standardheader->len = DLT_HTOBE_16(msg->standardheader->len);
3326 int dlt_user_log_check_user_message(void)
3333 DltUserHeader *userheader;
3334 DltReceiver *receiver = &(dlt_user.receiver);
3336 DltUserControlMsgLogLevel *usercontextll;
3337 DltUserControlMsgInjection *usercontextinj;
3338 DltUserControlMsgLogState *userlogstate;
3339 unsigned char *userbuffer;
3341 /* For delayed calling of injection callback, to avoid deadlock */
3342 DltUserInjectionCallback delayed_injection_callback;
3343 unsigned char *delayed_inject_buffer = 0;
3344 uint32_t delayed_inject_data_length = 0;
3346 /* Ensure that callback is null before searching for it */
3347 delayed_injection_callback.injection_callback = 0;
3348 delayed_injection_callback.service_id = 0;
3350 if (dlt_user.dlt_user_handle!=DLT_FD_INIT)
3354 if (dlt_receiver_receive_fd(receiver)<=0)
3356 /* No new message available */
3360 /* look through buffer as long as data is in there */
3363 if (receiver->bytesRcvd < (int32_t)sizeof(DltUserHeader))
3368 /* resync if necessary */
3372 userheader = (DltUserHeader*) (receiver->buf+offset);
3374 /* Check for user header pattern */
3375 if (dlt_user_check_userheader(userheader))
3382 while ((int32_t)(sizeof(DltUserHeader)+offset)<=receiver->bytesRcvd);
3384 /* Check for user header pattern */
3385 if (dlt_user_check_userheader(userheader)==0)
3390 /* Set new start offset */
3393 receiver->buf+=offset;
3394 receiver->bytesRcvd-=offset;
3397 switch (userheader->message)
3399 case DLT_USER_MESSAGE_LOG_LEVEL:
3401 if (receiver->bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogLevel)))
3407 usercontextll = (DltUserControlMsgLogLevel*) (receiver->buf+sizeof(DltUserHeader));
3409 /* Update log level and trace status */
3410 if (usercontextll!=0)
3414 if ((usercontextll->log_level_pos >= 0) && (usercontextll->log_level_pos < (int32_t)dlt_user.dlt_ll_ts_num_entries))
3416 // printf("Store ll, ts\n");
3417 if (dlt_user.dlt_ll_ts)
3419 dlt_user.dlt_ll_ts[usercontextll->log_level_pos].log_level = usercontextll->log_level;
3420 dlt_user.dlt_ll_ts[usercontextll->log_level_pos].trace_status = usercontextll->trace_status;
3427 /* keep not read data in buffer */
3428 if (dlt_receiver_remove(receiver,sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogLevel))==-1)
3434 case DLT_USER_MESSAGE_INJECTION:
3436 /* At least, user header, user context, and service id and data_length of injected message is available */
3437 if (receiver->bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgInjection)))
3443 usercontextinj = (DltUserControlMsgInjection*) (receiver->buf+sizeof(DltUserHeader));
3444 userbuffer = (unsigned char*) (receiver->buf+sizeof(DltUserHeader)+sizeof(DltUserControlMsgInjection));
3449 if (receiver->bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgInjection)+usercontextinj->data_length_inject))
3457 if ((usercontextinj->data_length_inject>0) && (dlt_user.dlt_ll_ts))
3459 /* Check if injection callback is registered for this context */
3460 for (i=0; i<dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].nrcallbacks;i++)
3462 if ((dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table) &&
3463 (dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table[i].service_id == usercontextinj->service_id))
3465 /* Prepare delayed injection callback call */
3466 if (dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table[i].injection_callback!=0)
3468 delayed_injection_callback.injection_callback = dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table[i].injection_callback;
3469 delayed_injection_callback.service_id = usercontextinj->service_id;
3470 delayed_inject_data_length = usercontextinj->data_length_inject;
3471 delayed_inject_buffer = malloc(delayed_inject_data_length);
3472 if(delayed_inject_buffer != 0) {
3473 memcpy(delayed_inject_buffer, userbuffer, delayed_inject_data_length);
3484 /* Delayed injection callback call */
3485 if(delayed_inject_buffer != 0 && delayed_injection_callback.injection_callback != 0) {
3486 delayed_injection_callback.injection_callback(delayed_injection_callback.service_id, delayed_inject_buffer, delayed_inject_data_length);
3487 free(delayed_inject_buffer);
3490 /* keep not read data in buffer */
3491 if (dlt_receiver_remove(receiver,(sizeof(DltUserHeader)+sizeof(DltUserControlMsgInjection)+usercontextinj->data_length_inject))==-1)
3498 case DLT_USER_MESSAGE_LOG_STATE:
3500 /* At least, user header, user context, and service id and data_length of injected message is available */
3501 if (receiver->bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogState)))
3507 userlogstate = (DltUserControlMsgLogState*) (receiver->buf+sizeof(DltUserHeader));
3508 dlt_user.log_state = userlogstate->log_state;
3510 /* keep not read data in buffer */
3511 if (dlt_receiver_remove(receiver,(sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogState)))==-1)
3519 dlt_log(LOG_ERR,"Invalid user message type received!\n");
3521 dlt_receiver_remove(receiver,sizeof(DltUserHeader));
3522 /* In next invocation of while loop, a resync will be triggered if additional data was received */
3535 if (dlt_receiver_move_to_begin(receiver)==-1)
3539 } /* while receive */
3542 return DLT_RETURN_OK;
3545 int dlt_user_log_resend_buffer(void)
3551 /* Send content of ringbuffer */
3553 count = dlt_buffer_get_message_count(&(dlt_user.startup_buffer));
3556 for (num=0;num<count;num++)
3560 size = dlt_buffer_copy(&(dlt_user.startup_buffer),dlt_user.resend_buffer,sizeof(dlt_user.resend_buffer));
3564 #ifdef DLT_SHM_ENABLE
3565 dlt_shm_push(&dlt_user.dlt_shm,dlt_user.resend_buffer+sizeof(DltUserHeader),size-sizeof(DltUserHeader),0,0,0,0);
3568 ret = dlt_user_log_out3(dlt_user.dlt_log_handle, dlt_user.resend_buffer,sizeof(DltUserHeader),0,0,0,0);
3571 ret = dlt_user_log_out3(dlt_user.dlt_log_handle, dlt_user.resend_buffer,size,0,0,0,0);
3574 /* in case of error, keep message in ringbuffer */
3575 if (ret==DLT_RETURN_OK)
3577 dlt_buffer_remove(&(dlt_user.startup_buffer));
3581 /* keep message in ringbuffer */
3592 void dlt_user_log_reattach_to_daemon(void)
3594 uint32_t num,reregistered=0;
3597 DltContextData log_new;
3599 if (dlt_user.dlt_log_handle<0)
3601 dlt_user.dlt_log_handle=-1;
3603 /* try to open pipe to dlt daemon */
3604 dlt_user.dlt_log_handle = open(DLT_USER_FIFO, O_WRONLY | O_NONBLOCK);
3605 if (dlt_user.dlt_log_handle > 0)
3607 if (dlt_user_log_init(&handle,&log_new)==-1)
3612 #ifdef DLT_SHM_ENABLE
3613 /* init shared memory */
3614 if (dlt_shm_init_client(&dlt_user.dlt_shm,DLT_SHM_KEY) < 0)
3616 sprintf(str,"Loging disabled, Shared memory %d cannot be created!\n",DLT_SHM_KEY);
3617 dlt_log(LOG_WARNING, str);
3622 dlt_log(LOG_NOTICE, "Logging re-enabled!\n");
3624 /* Re-register application */
3625 if (dlt_user_log_send_register_application()==-1)
3632 /* Re-register all stored contexts */
3633 for (num=0; num<dlt_user.dlt_ll_ts_num_entries; num++)
3635 /* Re-register stored context */
3636 if ((dlt_user.appID[0]!='\0') && (dlt_user.dlt_ll_ts) && (dlt_user.dlt_ll_ts[num].contextID[0]!='\0'))
3638 //dlt_set_id(log_new.appID, dlt_user.appID);
3639 dlt_set_id(handle.contextID, dlt_user.dlt_ll_ts[num].contextID);
3640 handle.log_level_pos = num;
3641 log_new.context_description = dlt_user.dlt_ll_ts[num].context_description;
3643 log_new.log_level = DLT_USER_LOG_LEVEL_NOT_SET;
3644 log_new.trace_status = DLT_USER_TRACE_STATUS_NOT_SET;
3646 if (dlt_user_log_send_register_context(&log_new)==-1)
3658 if (reregistered==1)
3660 dlt_user_log_resend_buffer();
3666 int dlt_user_log_send_overflow(void)
3668 DltUserHeader userheader;
3671 /* set userheader */
3672 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_OVERFLOW)==-1)
3677 if (dlt_user.dlt_is_file)
3683 ret=dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), 0, 0);
3684 return ((ret==DLT_RETURN_OK)?0:-1);
3687 int dlt_user_check_buffer(int *total_size, int *used_size)
3689 #ifdef DLT_SHM_ENABLE
3690 *total_size = dlt_shm_get_total_size(&(dlt_user.dlt_shm));
3691 *used_size = dlt_shm_get_used_size(&(dlt_user.dlt_shm));
3693 *total_size = dlt_buffer_get_total_size(&(dlt_user.startup_buffer));
3694 *used_size = dlt_buffer_get_used_size(&(dlt_user.startup_buffer));
3700 #ifdef DLT_TEST_ENABLE
3701 void dlt_user_test_corrupt_user_header(int enable)
3703 dlt_user.corrupt_user_header = enable;
3705 void dlt_user_test_corrupt_message_size(int enable,int16_t size)
3707 dlt_user.corrupt_message_size = enable;
3708 dlt_user.corrupt_message_size_size = size;