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 0xFFFFFFFF
109 DltNetworkTraceType nw_trace_type;
112 uint16_t payload_len;
116 /* Function prototypes for internally used functions */
117 static void dlt_user_receiverthread_function(void *ptr);
118 static void dlt_user_atexit_handler(void);
119 static int dlt_user_log_init(DltContext *handle, DltContextData *log);
120 static DltReturnValue dlt_user_log_send_log(DltContextData *log, int mtype);
121 static int dlt_user_log_send_register_application(void);
122 static int dlt_user_log_send_unregister_application(void);
123 static int dlt_user_log_send_register_context(DltContextData *log);
124 static int dlt_user_log_send_unregister_context(DltContextData *log);
125 static int dlt_send_app_ll_ts_limit(const char *appid, DltLogLevelType loglevel, DltTraceStatusType tracestatus);
126 static int dlt_user_log_send_log_mode(DltUserLogMode mode);
127 static int dlt_user_print_msg(DltMessage *msg, DltContextData *log);
128 static int dlt_user_log_check_user_message(void);
129 static void dlt_user_log_reattach_to_daemon(void);
130 static int dlt_user_log_send_overflow(void);
131 static void dlt_user_trace_network_segmented_thread(void *unused);
133 int dlt_user_check_library_version(const char *user_major_version,const char *user_minor_version){
136 char lib_major_version[DLT_USER_MAX_LIB_VERSION_LENGTH];
137 char lib_minor_version[DLT_USER_MAX_LIB_VERSION_LENGTH];
139 dlt_get_major_version( lib_major_version);
140 dlt_get_minor_version( lib_minor_version);
142 if( (strcmp(lib_major_version,user_major_version)!=0) || (strcmp(lib_minor_version,user_minor_version)!=0))
144 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);
145 dlt_log(LOG_WARNING, str);
153 char filename[DLT_USER_MAX_FILENAME_LENGTH];
156 dlt_user_initialised = 1;
158 /* Initialize common part of dlt_init()/dlt_init_file() */
159 if (dlt_init_common()==-1)
161 dlt_user_initialised = 0;
165 dlt_user.dlt_is_file = 0;
166 dlt_user.overflow = 0;
167 #ifdef DLT_SHM_ENABLE
168 memset(&(dlt_user.dlt_shm),0,sizeof(DltShm));
171 /* create and open DLT user FIFO */
172 sprintf(filename,"%s/dlt%d",DLT_USER_DIR,getpid());
174 /* Try to delete existing pipe, ignore result of unlink */
177 ret=mkfifo(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH );
180 sprintf(str,"Loging disabled, FIFO user %s cannot be created!\n",filename);
181 dlt_log(LOG_WARNING, str);
182 /* return 0; */ /* removed to prevent error, when FIFO already exists */
185 dlt_user.dlt_user_handle = open(filename, O_RDWR | O_CLOEXEC);
186 if (dlt_user.dlt_user_handle == DLT_FD_INIT)
188 sprintf(str,"Loging disabled, FIFO user %s cannot be opened!\n",filename);
189 dlt_log(LOG_WARNING, str);
194 /* open DLT output FIFO */
195 dlt_user.dlt_log_handle = open(DLT_USER_FIFO, O_WRONLY | O_NONBLOCK | O_CLOEXEC );
196 if (dlt_user.dlt_log_handle==-1)
198 sprintf(str,"Loging disabled, FIFO %s cannot be opened with open()!\n",DLT_USER_FIFO);
199 dlt_log(LOG_WARNING, str);
204 #ifdef DLT_SHM_ENABLE
205 /* init shared memory */
206 if (dlt_shm_init_client(&(dlt_user.dlt_shm),DLT_SHM_KEY) < 0)
208 sprintf(str,"Loging disabled, Shared memory %d cannot be created!\n",DLT_SHM_KEY);
209 dlt_log(LOG_WARNING, str);
216 if (dlt_receiver_init(&(dlt_user.receiver),dlt_user.dlt_user_handle, DLT_USER_RCVBUF_MAX_SIZE)==-1)
218 dlt_user_initialised = 0;
222 /* Start receiver thread */
223 if (pthread_create(&(dlt_receiverthread_handle),
225 (void *) &dlt_user_receiverthread_function,
228 if (pthread_attr_destroy(&dlt_receiverthread_attr)!=0)
230 dlt_log(LOG_WARNING, "Can't destroy thread attributes!\n");
233 dlt_log(LOG_CRIT, "Can't create receiver thread!\n");
234 dlt_user_initialised = 0;
238 if (pthread_attr_destroy(&dlt_receiverthread_attr)!=0)
240 dlt_log(LOG_WARNING, "Can't destroy thread attributes!\n");
243 /* Generate per process name for queue */
244 char queue_name[NAME_MAX];
245 sprintf(queue_name, "%s.%d", DLT_MESSAGE_QUEUE_NAME, getpid());
247 /* Maximum queue size is 10, limit to size of pointers */
248 struct mq_attr mqatr;
250 mqatr.mq_maxmsg = 10;
251 mqatr.mq_msgsize = sizeof(s_segmented_data *);
252 mqatr.mq_curmsgs = 0;
254 /* Separate handles for reading and writing */
255 dlt_user.dlt_segmented_queue_read_handle = mq_open(queue_name, O_CREAT| O_RDONLY,
256 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, &mqatr);
257 if(dlt_user.dlt_segmented_queue_read_handle < 0)
259 dlt_log(LOG_CRIT, "Can't create message queue read handle!\n");
260 dlt_log(LOG_CRIT, strerror(errno));
264 dlt_user.dlt_segmented_queue_write_handle = mq_open(queue_name, O_WRONLY);
265 if(dlt_user.dlt_segmented_queue_write_handle < 0)
267 dlt_log(LOG_CRIT, "Can't open message queue write handle!\n");
268 dlt_log(LOG_CRIT, strerror(errno));
272 if(pthread_create(&(dlt_user.dlt_segmented_nwt_handle), NULL,
273 (void *)dlt_user_trace_network_segmented_thread, NULL))
275 dlt_log(LOG_CRIT, "Can't start segmented thread!\n");
282 int dlt_init_file(const char *name)
284 dlt_user_initialised = 1;
286 /* Initialize common part of dlt_init()/dlt_init_file() */
287 if (dlt_init_common()==-1)
289 dlt_user_initialised = 0;
293 dlt_user.dlt_is_file = 1;
295 /* open DLT output file */
296 dlt_user.dlt_log_handle = open(name,O_WRONLY|O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); /* mode: wb */
297 if (dlt_user.dlt_log_handle == -1)
299 sprintf(str,"Log file %s cannot be opened!\n",name);
300 dlt_log(LOG_ERR, str);
307 int dlt_init_common(void)
309 char *env_local_print;
311 /* Binary semaphore for threads */
312 if (sem_init(&dlt_mutex, 0, 1)==-1)
314 dlt_user_initialised = 0;
318 /* set to unknown state of connected client */
319 dlt_user.log_state = -1;
321 dlt_user.dlt_log_handle=-1;
322 dlt_user.dlt_user_handle=DLT_FD_INIT;
324 dlt_set_id(dlt_user.ecuID,DLT_USER_DEFAULT_ECU_ID);
325 dlt_set_id(dlt_user.appID,"");
327 dlt_user.application_description = 0;
329 /* Verbose mode is enabled by default */
330 dlt_user.verbose_mode = 1;
332 /* Local print is disabled by default */
333 dlt_user.enable_local_print = 0;
335 dlt_user.local_print_mode = DLT_PM_UNSET;
337 env_local_print = getenv(DLT_USER_ENV_LOCAL_PRINT_MODE);
340 if (strcmp(env_local_print,"AUTOMATIC")==0)
342 dlt_user.local_print_mode = DLT_PM_AUTOMATIC;
344 else if (strcmp(env_local_print,"FORCE_ON")==0)
346 dlt_user.local_print_mode = DLT_PM_FORCE_ON;
348 else if (strcmp(env_local_print,"FORCE_OFF")==0)
350 dlt_user.local_print_mode = DLT_PM_FORCE_OFF;
354 /* Initialize LogLevel/TraceStatus field */
355 dlt_user.dlt_ll_ts = 0;
356 dlt_user.dlt_ll_ts_max_num_entries = 0;
357 dlt_user.dlt_ll_ts_num_entries = 0;
359 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)
361 dlt_user_initialised = 0;
365 signal(SIGPIPE,SIG_IGN); /* ignore pipe signals */
367 atexit(dlt_user_atexit_handler);
369 #ifdef DLT_TEST_ENABLE
370 dlt_user.corrupt_user_header = 0;
371 dlt_user.corrupt_message_size = 0;
372 dlt_user.corrupt_message_size_size = 0;
378 void dlt_user_atexit_handler(void)
381 /* Try to resend potential log messages in the user buffer */
382 int count = dlt_user_atexit_blow_out_user_buffer();
386 sprintf(tmp,"Lost log messages in user buffer when exiting: %i\n",count);
387 dlt_log(LOG_ERR, tmp);
390 /* Unregister app (this also unregisters all contexts in daemon) */
391 /* Ignore return value */
392 dlt_unregister_app();
395 /* Ignore return value */
399 int dlt_user_atexit_blow_out_user_buffer(void){
403 uint32_t exitTime = dlt_uptime() + DLT_USER_ATEXIT_RESEND_BUFFER_EXIT_TIMEOUT;
405 while(dlt_uptime() < exitTime ){
407 ret = dlt_user_log_resend_buffer();
414 usleep(DLT_USER_ATEXIT_RESEND_BUFFER_SLEEP);
418 count = dlt_buffer_get_message_count(&(dlt_user.startup_buffer));
427 char filename[DLT_USER_MAX_FILENAME_LENGTH];
429 if (dlt_user_initialised==0)
434 if (dlt_receiverthread_handle)
436 /* Ignore return value */
437 pthread_cancel(dlt_receiverthread_handle);
440 if (dlt_user.dlt_user_handle!=DLT_FD_INIT)
442 sprintf(filename,"%s/dlt%d",DLT_USER_DIR,getpid());
444 close(dlt_user.dlt_user_handle);
445 dlt_user.dlt_user_handle=DLT_FD_INIT;
450 #ifdef DLT_SHM_ENABLE
451 /* free shared memory */
452 dlt_shm_free_client(&dlt_user.dlt_shm);
455 if (dlt_user.dlt_log_handle!=-1)
457 /* close log file/output fifo to daemon */
458 close(dlt_user.dlt_log_handle);
459 dlt_user.dlt_log_handle = -1;
462 /* Ignore return value */
463 dlt_receiver_free(&(dlt_user.receiver));
465 /* Ignore return value */
466 dlt_buffer_free_dynamic(&(dlt_user.startup_buffer));
468 if (dlt_user.dlt_ll_ts)
470 for (i=0;i<dlt_user.dlt_ll_ts_max_num_entries;i++)
472 if (dlt_user.dlt_ll_ts[i].injection_table!=0)
474 free(dlt_user.dlt_ll_ts[i].injection_table);
475 dlt_user.dlt_ll_ts[i].injection_table = 0;
477 dlt_user.dlt_ll_ts[i].nrcallbacks = 0;
480 free(dlt_user.dlt_ll_ts);
481 dlt_user.dlt_ll_ts = 0;
482 dlt_user.dlt_ll_ts_max_num_entries = 0;
483 dlt_user.dlt_ll_ts_num_entries = 0;
486 if (dlt_user.dlt_segmented_nwt_handle)
488 pthread_cancel(dlt_user.dlt_segmented_nwt_handle);
491 char queue_name[NAME_MAX];
492 sprintf(queue_name, "%s.%d", DLT_MESSAGE_QUEUE_NAME, getpid());
494 if(mq_close(dlt_user.dlt_segmented_queue_write_handle) < 0)
496 dlt_log(LOG_ERR, "Failed to unlink message queue write handle!\n");
497 dlt_log(LOG_ERR, strerror(errno));
500 if(mq_close(dlt_user.dlt_segmented_queue_read_handle) < 0 ||
501 mq_unlink(queue_name))
503 dlt_log(LOG_ERR, "Failed to unlink message queue read handle!\n");
504 dlt_log(LOG_ERR, strerror(errno));
507 dlt_user_initialised = 0;
512 int dlt_check_library_version(const char * user_major_version,const char * user_minor_version)
514 return dlt_user_check_library_version(user_major_version, user_minor_version);
517 int dlt_register_app(const char *appid, const char * description)
521 if (dlt_user_initialised==0)
529 if ((appid==0) || (appid[0]=='\0'))
534 /* check if application already registered */
535 /* if yes do not register again */
538 if(appid[0]==dlt_user.appID[0])
543 if(appid[0]==dlt_user.appID[0] &&
544 appid[1]==dlt_user.appID[1])
549 if(appid[0]==dlt_user.appID[0] &&
550 appid[1]==dlt_user.appID[1] &&
551 appid[2]==dlt_user.appID[2])
556 if(appid[0]==dlt_user.appID[0] &&
557 appid[1]==dlt_user.appID[1] &&
558 appid[2]==dlt_user.appID[2] &&
559 appid[3]==dlt_user.appID[3])
565 /* Store locally application id and application description */
566 dlt_set_id(dlt_user.appID, appid);
568 if (dlt_user.application_description!=0)
570 free(dlt_user.application_description);
573 dlt_user.application_description = 0;
577 size_t desc_len = strlen(description);
578 dlt_user.application_description= malloc(desc_len+1);
579 if (dlt_user.application_description){
580 strncpy(dlt_user.application_description, description, desc_len);
582 /* Terminate transmitted string with 0 */
583 dlt_user.application_description[desc_len]='\0';
594 ret = dlt_user_log_send_register_application();
598 int dlt_register_context(DltContext *handle, const char *contextid, const char * description)
600 if (dlt_user_initialised==0)
610 if (dlt_user.appID[0]=='\0')
612 dlt_log(LOG_ERR, "no application registered!\n");
618 if ((contextid==0) || (contextid[0]=='\0'))
626 return dlt_register_context_ll_ts(handle, contextid, description, DLT_USER_LOG_LEVEL_NOT_SET, DLT_USER_TRACE_STATUS_NOT_SET);
629 int dlt_register_context_ll_ts(DltContext *handle, const char *contextid, const char * description, int loglevel, int tracestatus)
634 char ctid[DLT_ID_SIZE+1];
636 if (dlt_user_initialised==0)
646 if (dlt_user.appID[0]=='\0')
648 dlt_log(LOG_ERR, "no application registered!\n");
656 if ((contextid==0) || (contextid[0]=='\0'))
661 if ((loglevel<DLT_USER_LOG_LEVEL_NOT_SET) || (loglevel>DLT_LOG_VERBOSE) || (loglevel==DLT_LOG_DEFAULT))
666 if ((tracestatus<DLT_USER_TRACE_STATUS_NOT_SET) || (tracestatus>DLT_TRACE_STATUS_ON) || (tracestatus==DLT_TRACE_STATUS_DEFAULT))
671 if (dlt_user_log_init(handle, &log)==-1)
676 /* Reset message counter */
679 /* Store context id in log level/trace status field */
681 /* Check if already registered, else register context */
685 for (i=0;i<dlt_user.dlt_ll_ts_num_entries;i++)
687 if (dlt_user.dlt_ll_ts)
689 if (memcmp(dlt_user.dlt_ll_ts[i].contextID, contextid,DLT_ID_SIZE)==0)
693 memset(ctid,0,(DLT_ID_SIZE+1));
694 dlt_print_id(ctid, contextid);
696 sprintf(str,"context '%s' already registered!\n",ctid);
697 dlt_log(LOG_WARNING, str);
706 /* Allocate or expand context array */
707 if (dlt_user.dlt_ll_ts == 0)
709 dlt_user.dlt_ll_ts = (dlt_ll_ts_type*) malloc(sizeof(dlt_ll_ts_type)*DLT_USER_CONTEXT_ALLOC_SIZE);
710 if (dlt_user.dlt_ll_ts==0)
716 dlt_user.dlt_ll_ts_max_num_entries = DLT_USER_CONTEXT_ALLOC_SIZE;
718 /* Initialize new entries */
719 for (i=0;i<dlt_user.dlt_ll_ts_max_num_entries;i++)
721 dlt_set_id(dlt_user.dlt_ll_ts[i].contextID,"");
723 /* At startup, logging and tracing is locally enabled */
724 /* the correct log level/status is set after received from daemon */
725 dlt_user.dlt_ll_ts[i].log_level = DLT_USER_INITIAL_LOG_LEVEL;
726 dlt_user.dlt_ll_ts[i].trace_status = DLT_USER_INITIAL_TRACE_STATUS;
728 dlt_user.dlt_ll_ts[i].context_description = 0;
730 dlt_user.dlt_ll_ts[i].injection_table = 0;
731 dlt_user.dlt_ll_ts[i].nrcallbacks = 0;
736 if ((dlt_user.dlt_ll_ts_num_entries%DLT_USER_CONTEXT_ALLOC_SIZE)==0)
738 /* allocate memory in steps of DLT_USER_CONTEXT_ALLOC_SIZE, e.g. 500 */
739 dlt_ll_ts_type *old_ll_ts;
740 uint32_t old_max_entries;
742 old_ll_ts = dlt_user.dlt_ll_ts;
743 old_max_entries = dlt_user.dlt_ll_ts_max_num_entries;
745 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;
746 dlt_user.dlt_ll_ts = (dlt_ll_ts_type*) malloc(sizeof(dlt_ll_ts_type)*
747 dlt_user.dlt_ll_ts_max_num_entries);
748 if (dlt_user.dlt_ll_ts==0)
750 dlt_user.dlt_ll_ts = old_ll_ts;
751 dlt_user.dlt_ll_ts_max_num_entries = old_max_entries;
756 memcpy(dlt_user.dlt_ll_ts,old_ll_ts,sizeof(dlt_ll_ts_type)*dlt_user.dlt_ll_ts_num_entries);
759 /* Initialize new entries */
760 for (i=dlt_user.dlt_ll_ts_num_entries;i<dlt_user.dlt_ll_ts_max_num_entries;i++)
762 dlt_set_id(dlt_user.dlt_ll_ts[i].contextID,"");
764 /* At startup, logging and tracing is locally enabled */
765 /* the correct log level/status is set after received from daemon */
766 dlt_user.dlt_ll_ts[i].log_level = DLT_USER_INITIAL_LOG_LEVEL;
767 dlt_user.dlt_ll_ts[i].trace_status = DLT_USER_INITIAL_TRACE_STATUS;
769 dlt_user.dlt_ll_ts[i].context_description = 0;
771 dlt_user.dlt_ll_ts[i].injection_table = 0;
772 dlt_user.dlt_ll_ts[i].nrcallbacks = 0;
777 /* Store locally context id and context description */
778 dlt_set_id(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].contextID, contextid);
780 if (dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description!=0)
782 free(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description);
785 dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description = 0;
789 size_t desc_len = strlen(description);
790 dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description = malloc(desc_len+1);
791 if(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description == 0)
797 strncpy(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description, description, desc_len);
799 /* Terminate transmitted string with 0 */
800 dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description[desc_len]='\0';
803 if (loglevel!=DLT_USER_LOG_LEVEL_NOT_SET)
805 dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].log_level = loglevel;
808 if (tracestatus!=DLT_USER_TRACE_STATUS_NOT_SET)
810 dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].trace_status = tracestatus;
813 /* Prepare transfer struct */
814 //dlt_set_id(log->appID, dlt_user.appID);
815 dlt_set_id(handle->contextID, contextid);
816 handle->log_level_pos = dlt_user.dlt_ll_ts_num_entries;
818 log.context_description = dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description;
820 if (loglevel!=DLT_USER_LOG_LEVEL_NOT_SET)
822 log.log_level = loglevel;
826 log.log_level = DLT_USER_LOG_LEVEL_NOT_SET;
829 if (tracestatus!=DLT_USER_TRACE_STATUS_NOT_SET)
831 log.trace_status = tracestatus;
835 log.trace_status = DLT_USER_TRACE_STATUS_NOT_SET;
838 dlt_user.dlt_ll_ts_num_entries++;
842 ret=dlt_user_log_send_register_context(&log);
854 int dlt_unregister_app(void)
858 if (dlt_user_initialised==0)
863 /* Inform daemon to unregister application and all of its contexts */
864 ret = dlt_user_log_send_unregister_application();
868 /* Clear and free local stored application information */
869 dlt_set_id(dlt_user.appID, "");
871 if (dlt_user.application_description!=0)
873 free(dlt_user.application_description);
876 dlt_user.application_description = 0;
883 int dlt_unregister_context(DltContext *handle)
888 if (dlt_user_initialised==0)
893 if (dlt_user_log_init(handle, &log) == -1)
900 if (dlt_user.dlt_ll_ts)
902 /* Clear and free local stored context information */
903 dlt_set_id(dlt_user.dlt_ll_ts[handle->log_level_pos].contextID, "");
905 dlt_user.dlt_ll_ts[handle->log_level_pos].log_level = DLT_USER_INITIAL_LOG_LEVEL;
906 dlt_user.dlt_ll_ts[handle->log_level_pos].trace_status = DLT_USER_INITIAL_TRACE_STATUS;
908 if (dlt_user.dlt_ll_ts[handle->log_level_pos].context_description!=0)
910 free(dlt_user.dlt_ll_ts[handle->log_level_pos].context_description);
913 dlt_user.dlt_ll_ts[handle->log_level_pos].context_description = 0;
915 if (dlt_user.dlt_ll_ts[handle->log_level_pos].injection_table)
917 free(dlt_user.dlt_ll_ts[handle->log_level_pos].injection_table);
918 dlt_user.dlt_ll_ts[handle->log_level_pos].injection_table = 0;
921 dlt_user.dlt_ll_ts[handle->log_level_pos].nrcallbacks = 0;
926 /* Inform daemon to unregister context */
927 ret = dlt_user_log_send_unregister_context(&log);
932 int dlt_set_application_ll_ts_limit(DltLogLevelType loglevel, DltTraceStatusType tracestatus)
937 if (dlt_user_initialised==0)
945 /* Removed because of DltLogLevelType and DltTraceStatusType
947 if ((loglevel<DLT_LOG_DEFAULT) || (loglevel>DLT_LOG_VERBOSE))
952 if ((tracestatus<DLT_TRACE_STATUS_DEFAULT) || (tracestatus>DLT_TRACE_STATUS_ON))
957 if (dlt_user.dlt_ll_ts==0)
966 /* Update local structures */
967 for (i=0; i<dlt_user.dlt_ll_ts_num_entries;i++)
969 dlt_user.dlt_ll_ts[i].log_level = loglevel;
970 dlt_user.dlt_ll_ts[i].trace_status = tracestatus;
975 /* Inform DLT server about update */
976 ret = dlt_send_app_ll_ts_limit(dlt_user.appID, loglevel, tracestatus);
981 int dlt_get_log_state()
983 return dlt_user.log_state;
986 int dlt_set_log_mode(DltUserLogMode mode)
988 if (dlt_user_initialised==0)
996 return dlt_user_log_send_log_mode(mode);
999 int dlt_forward_msg(void *msgdata,size_t size)
1001 DltUserHeader userheader;
1004 if ((msgdata==0) || (size==0))
1009 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG)==-1)
1011 /* Type of internal user message; same value for Trace messages */
1015 if (dlt_user.dlt_is_file)
1018 ret = dlt_user_log_out2(dlt_user.dlt_log_handle, msgdata, size, 0, 0);
1019 return ((ret==DLT_RETURN_OK)?0:-1);
1023 /* Reattach to daemon if neccesary */
1024 dlt_user_log_reattach_to_daemon();
1026 if (dlt_user.overflow)
1028 if (dlt_user_log_send_overflow()==0)
1030 dlt_user.overflow=0;
1035 ret = dlt_user_log_out3(dlt_user.dlt_log_handle,
1036 &(userheader), sizeof(DltUserHeader),
1037 msgdata, size, 0, 0);
1039 /* store message in ringbuffer, if an error has occured */
1040 if (ret!=DLT_RETURN_OK)
1044 if (dlt_buffer_push3(&(dlt_user.startup_buffer),
1045 (unsigned char *)&(userheader), sizeof(DltUserHeader),
1046 msgdata, size, 0, 0)==-1)
1048 dlt_log(LOG_ERR,"Storing message to history buffer failed! Message discarded.\n");
1056 case DLT_RETURN_PIPE_FULL:
1058 /* data could not be written */
1059 dlt_user.overflow = 1;
1062 case DLT_RETURN_PIPE_ERROR:
1064 /* handle not open or pipe error */
1065 close(dlt_user.dlt_log_handle);
1066 dlt_user.dlt_log_handle = -1;
1070 case DLT_RETURN_ERROR:
1072 /* other error condition */
1081 /* This case should not occur */
1090 /* ********************************************************************************************* */
1092 inline int dlt_user_log_write_start(DltContext *handle, DltContextData *log,DltLogLevelType loglevel)
1094 return dlt_user_log_write_start_id(handle,log,loglevel,DLT_USER_DEFAULT_MSGID);
1097 int dlt_user_log_write_start_id(DltContext *handle, DltContextData *log,DltLogLevelType loglevel, uint32_t messageid)
1099 if(dlt_user_initialised==0)
1111 if (dlt_user_log_init(handle, log)==-1)
1116 if (dlt_user.dlt_ll_ts==0)
1123 if ((loglevel<=(int)(dlt_user.dlt_ll_ts[handle->log_level_pos].log_level) ) && (loglevel!=0))
1127 log->log_level = loglevel;
1129 /* In non-verbose mode, insert message id */
1130 if (dlt_user.verbose_mode==0)
1132 if ((sizeof(uint32_t))>DLT_USER_BUF_MAX_SIZE)
1136 /* Write message id */
1137 memcpy(log->buffer,&(messageid),sizeof(uint32_t));
1138 log->size = sizeof(uint32_t);
1140 /* as the message id is part of each message in non-verbose mode,
1141 it doesn't increment the argument counter in extended header (if used) */
1155 int dlt_user_log_write_finish(DltContextData *log)
1162 return dlt_user_log_send_log(log, DLT_TYPE_LOG) < 0 ? -1 : 0;
1165 int dlt_user_log_write_raw(DltContextData *log,void *data,uint16_t length)
1175 if ((log->size+length+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1180 if (dlt_user.verbose_mode)
1182 if ((log->size+length+sizeof(uint32_t)+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1187 /* Transmit type information */
1188 type_info = DLT_TYPE_INFO_RAWD;
1190 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1191 log->size += sizeof(uint32_t);
1195 /* First transmit length of raw data, then the raw data itself */
1196 arg_size = (uint16_t)length;
1198 memcpy((log->buffer)+log->size,&(arg_size),sizeof(uint16_t));
1199 log->size += sizeof(uint16_t);
1201 memcpy((log->buffer)+log->size,data,arg_size);
1202 log->size += arg_size;
1209 int dlt_user_log_write_float32(DltContextData *log, float32_t data)
1218 if (sizeof(float32_t)!=4)
1223 if ((log->size+sizeof(float32_t))>DLT_USER_BUF_MAX_SIZE)
1228 if (dlt_user.verbose_mode)
1230 if ((log->size+sizeof(uint32_t)+sizeof(float32_t))>DLT_USER_BUF_MAX_SIZE)
1235 type_info = DLT_TYPE_INFO_FLOA | DLT_TYLE_32BIT;
1237 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1238 log->size += sizeof(uint32_t);
1241 memcpy((log->buffer)+log->size,&data, sizeof(float32_t));
1242 log->size += sizeof(float32_t);
1249 int dlt_user_log_write_float64(DltContextData *log, float64_t data)
1258 if (sizeof(float64_t)!=8)
1263 if ((log->size+sizeof(float64_t))>DLT_USER_BUF_MAX_SIZE)
1268 if (dlt_user.verbose_mode)
1270 if ((log->size+sizeof(uint32_t)+sizeof(float64_t))>DLT_USER_BUF_MAX_SIZE)
1275 type_info = DLT_TYPE_INFO_FLOA | DLT_TYLE_64BIT;
1277 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1278 log->size += sizeof(uint32_t);
1281 memcpy((log->buffer)+log->size,&data, sizeof(float64_t));
1282 log->size += sizeof(float64_t);
1289 int dlt_user_log_write_uint( DltContextData *log, unsigned int data)
1296 switch (sizeof(unsigned int))
1300 return dlt_user_log_write_uint8(log, (uint8_t)data);
1305 return dlt_user_log_write_uint16(log, (uint16_t)data);
1310 return dlt_user_log_write_uint32(log, (uint32_t)data);
1315 return dlt_user_log_write_uint64(log, (uint64_t)data);
1328 int dlt_user_log_write_uint8(DltContextData *log, uint8_t data)
1337 if ((log->size+sizeof(uint8_t))>DLT_USER_BUF_MAX_SIZE)
1342 if (dlt_user.verbose_mode)
1344 if ((log->size+sizeof(uint32_t)+sizeof(uint8_t))>DLT_USER_BUF_MAX_SIZE)
1349 type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_8BIT;
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(uint8_t));
1356 log->size += sizeof(uint8_t);
1363 int dlt_user_log_write_uint16(DltContextData *log, uint16_t data)
1372 if ((log->size+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1377 if (dlt_user.verbose_mode)
1379 if ((log->size+sizeof(uint32_t)+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1384 type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_16BIT;
1386 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1387 log->size += sizeof(uint32_t);
1390 memcpy((log->buffer)+log->size,&data,sizeof(uint16_t));
1391 log->size += sizeof(uint16_t);
1398 int dlt_user_log_write_uint32(DltContextData *log, uint32_t data)
1407 if ((log->size+sizeof(uint32_t))>DLT_USER_BUF_MAX_SIZE)
1412 if (dlt_user.verbose_mode)
1414 if ((log->size+sizeof(uint32_t)+sizeof(uint32_t))>DLT_USER_BUF_MAX_SIZE)
1419 type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_32BIT;
1421 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1422 log->size += sizeof(uint32_t);
1425 memcpy((log->buffer)+log->size,&data, sizeof(uint32_t));
1426 log->size += sizeof(uint32_t);
1433 int dlt_user_log_write_uint64(DltContextData *log, uint64_t data)
1442 if ((log->size+sizeof(uint64_t))>DLT_USER_BUF_MAX_SIZE)
1447 if (dlt_user.verbose_mode)
1449 if ((log->size+sizeof(uint32_t)+sizeof(uint64_t))>DLT_USER_BUF_MAX_SIZE)
1454 type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_64BIT;
1456 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1457 log->size +=sizeof(uint32_t);
1460 memcpy((log->buffer)+log->size,&data,sizeof(uint64_t));
1461 log->size += sizeof(uint64_t);
1468 int dlt_user_log_write_int(DltContextData *log, int data)
1475 switch (sizeof(int))
1479 return dlt_user_log_write_int8(log, (int8_t)data);
1484 return dlt_user_log_write_int16(log, (int16_t)data);
1489 return dlt_user_log_write_int32(log, (int32_t)data);
1494 return dlt_user_log_write_int64(log, (int64_t)data);
1507 int dlt_user_log_write_int8(DltContextData *log, int8_t data)
1516 if ((log->size+sizeof(int8_t))>DLT_USER_BUF_MAX_SIZE)
1521 if (dlt_user.verbose_mode)
1523 if ((log->size+sizeof(uint32_t)+sizeof(int8_t))>DLT_USER_BUF_MAX_SIZE)
1528 type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_8BIT;
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(int8_t));
1535 log->size += sizeof(int8_t);
1542 int dlt_user_log_write_int16(DltContextData *log, int16_t data)
1551 if ((log->size+sizeof(int16_t))>DLT_USER_BUF_MAX_SIZE)
1556 if (dlt_user.verbose_mode)
1558 if ((log->size+sizeof(uint32_t)+sizeof(int16_t))>DLT_USER_BUF_MAX_SIZE)
1563 type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_16BIT;
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(int16_t));
1570 log->size += sizeof(int16_t);
1577 int dlt_user_log_write_int32(DltContextData *log, int32_t data)
1586 if ((log->size+sizeof(int32_t))>DLT_USER_BUF_MAX_SIZE)
1591 if (dlt_user.verbose_mode)
1593 if ((log->size+sizeof(uint32_t)+sizeof(int32_t))>DLT_USER_BUF_MAX_SIZE)
1598 type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_32BIT;
1600 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1601 log->size += sizeof(uint32_t);
1604 memcpy((log->buffer)+log->size,&data, sizeof(int32_t));
1605 log->size += sizeof(int32_t);
1612 int dlt_user_log_write_int64(DltContextData *log, int64_t data)
1621 if ((log->size+sizeof(int64_t))>DLT_USER_BUF_MAX_SIZE)
1626 if (dlt_user.verbose_mode)
1628 if ((log->size+sizeof(uint32_t)+sizeof(int64_t))>DLT_USER_BUF_MAX_SIZE)
1633 type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_64BIT;
1635 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1636 log->size += sizeof(uint32_t);
1639 memcpy((log->buffer)+log->size,&data,sizeof(int64_t));
1640 log->size += sizeof(int64_t);
1647 int dlt_user_log_write_bool(DltContextData *log, uint8_t data)
1656 if ((log->size+sizeof(uint8_t))>DLT_USER_BUF_MAX_SIZE)
1661 if (dlt_user.verbose_mode)
1663 if ((log->size+sizeof(uint32_t)+sizeof(uint8_t))>DLT_USER_BUF_MAX_SIZE)
1668 type_info = DLT_TYPE_INFO_BOOL;
1670 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1671 log->size += sizeof(uint32_t);
1674 memcpy((log->buffer)+log->size,&data,sizeof(uint8_t));
1675 log->size += sizeof(uint8_t);
1682 int dlt_user_log_write_string(DltContextData *log, const char *text)
1687 if ((log==0) || (text==0))
1692 if ((log->size+(strlen(text)+1)+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1697 if (dlt_user.verbose_mode)
1699 if ((log->size+(strlen(text)+1)+sizeof(uint32_t)+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1704 type_info = DLT_TYPE_INFO_STRG;
1706 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1707 log->size += sizeof(uint32_t);
1710 arg_size = strlen(text) + 1;
1712 memcpy((log->buffer)+log->size,&(arg_size),sizeof(uint16_t));
1713 log->size += sizeof(uint16_t);
1715 memcpy((log->buffer)+log->size,text,arg_size);
1716 log->size += arg_size;
1723 int dlt_register_injection_callback(DltContext *handle, uint32_t service_id,
1724 int (*dlt_injection_callback)(uint32_t service_id, void *data, uint32_t length))
1730 DltUserInjectionCallback *old;
1737 if (dlt_user_log_init(handle, &log)==-1)
1742 if (service_id<DLT_USER_INJECTION_MIN)
1746 /* This function doesn't make sense storing to local file is choosen;
1747 so terminate this function */
1748 if (dlt_user.dlt_is_file)
1755 if (dlt_user.dlt_ll_ts==0)
1761 /* Insert callback in corresponding table */
1762 i=handle->log_level_pos;
1764 /* Insert each service_id only once */
1765 for (k=0;k<dlt_user.dlt_ll_ts[i].nrcallbacks;k++)
1767 if ((dlt_user.dlt_ll_ts[i].injection_table) &&
1768 (dlt_user.dlt_ll_ts[i].injection_table[k].service_id == service_id))
1781 j=dlt_user.dlt_ll_ts[i].nrcallbacks;
1783 /* Allocate or expand injection table */
1784 if (dlt_user.dlt_ll_ts[i].injection_table == 0)
1786 dlt_user.dlt_ll_ts[i].injection_table = (DltUserInjectionCallback*) malloc(sizeof(DltUserInjectionCallback));
1787 if(dlt_user.dlt_ll_ts[i].injection_table == 0)
1795 old = dlt_user.dlt_ll_ts[i].injection_table;
1796 dlt_user.dlt_ll_ts[i].injection_table = (DltUserInjectionCallback*) malloc(sizeof(DltUserInjectionCallback)*(j+1));
1797 if(dlt_user.dlt_ll_ts[i].injection_table == 0)
1799 dlt_user.dlt_ll_ts[i].injection_table = old;
1803 memcpy(dlt_user.dlt_ll_ts[i].injection_table,old,sizeof(DltUserInjectionCallback)*j);
1807 dlt_user.dlt_ll_ts[i].nrcallbacks++;
1810 /* Store service_id and corresponding function pointer for callback function */
1811 dlt_user.dlt_ll_ts[i].injection_table[j].service_id = service_id;
1812 dlt_user.dlt_ll_ts[i].injection_table[j].injection_callback = dlt_injection_callback;
1825 int total_size, used_size;
1826 dlt_user_check_buffer(&total_size, &used_size);
1828 if((total_size - used_size) < (total_size/2))
1836 * Send the start of a segment chain.
1837 * Returns -1 on failure
1839 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)
1850 if (dlt_user_log_init(handle, &log)==-1)
1857 if (dlt_user.dlt_ll_ts==0)
1863 if (dlt_user.dlt_ll_ts[handle->log_level_pos].trace_status==DLT_TRACE_STATUS_ON)
1868 log.trace_status = nw_trace_type;
1871 gettimeofday(&tv, NULL);
1874 /* Write identifier */
1875 if(dlt_user_log_write_string(&log, "NWST") < 0)
1880 /* Write stream handle */
1881 if(dlt_user_log_write_uint16(&log, *id) < 0)
1887 if(dlt_user_log_write_raw(&log, header, header_len) < 0)
1892 /* Write size of payload */
1893 if(dlt_user_log_write_uint16(&log, payload_len) < 0)
1898 /* Write expected segment count */
1899 uint16_t segment_count = payload_len/DLT_MAX_TRACE_SEGMENT_SIZE+1;
1901 /* If segments align perfectly with segment size, avoid sending empty segment */
1902 if((payload_len % DLT_MAX_TRACE_SEGMENT_SIZE) == 0)
1907 if(dlt_user_log_write_uint16(&log, segment_count) < 0)
1912 /* Write length of one segment */
1913 if(dlt_user_log_write_uint16(&log, DLT_MAX_TRACE_SEGMENT_SIZE) < 0)
1919 return dlt_user_log_send_log(&log, DLT_TYPE_NW_TRACE);
1928 int dlt_user_trace_network_segmented_segment(uint16_t id, DltContext *handle, DltNetworkTraceType nw_trace_type, int sequence, uint16_t payload_len, void *payload)
1930 while(check_buffer() < 0)
1932 usleep(1000*50); // Wait 50ms
1933 dlt_user_log_resend_buffer();
1943 if (dlt_user_log_init(handle, &log)==-1)
1950 if (dlt_user.dlt_ll_ts==0)
1956 if (dlt_user.dlt_ll_ts[handle->log_level_pos].trace_status==DLT_TRACE_STATUS_ON)
1961 log.trace_status = nw_trace_type;
1964 /* Write identifier */
1965 if(dlt_user_log_write_string(&log, "NWCH") < 0)
1970 /* Write stream handle */
1971 if(dlt_user_log_write_uint16(&log, id) < 0)
1976 /* Write segment sequence number */
1977 if(dlt_user_log_write_uint16(&log, sequence) < 0)
1983 if(dlt_user_log_write_raw(&log, payload, payload_len) < 0)
1989 return dlt_user_log_send_log(&log, DLT_TYPE_NW_TRACE);
1996 /* Allow other threads to log between chunks */
2001 int dlt_user_trace_network_segmented_end(uint16_t id, DltContext *handle, DltNetworkTraceType nw_trace_type)
2010 if (dlt_user_log_init(handle, &log)==-1)
2019 if (dlt_user.dlt_ll_ts==0)
2025 if (dlt_user.dlt_ll_ts[handle->log_level_pos].trace_status==DLT_TRACE_STATUS_ON)
2030 log.trace_status = nw_trace_type;
2033 /* Write identifier */
2034 if(dlt_user_log_write_string(&log, "NWEN") < 0)
2039 /* Write stream handle */
2040 if(dlt_user_log_write_uint(&log, id) < 0)
2046 return dlt_user_log_send_log(&log, DLT_TYPE_NW_TRACE);
2055 void dlt_user_trace_network_segmented_thread(void *unused)
2057 /* Unused on purpose. */
2060 s_segmented_data *data;
2064 ssize_t read = mq_receive(dlt_user.dlt_segmented_queue_read_handle, (char *)&data,
2065 sizeof(s_segmented_data * ), NULL);
2066 if(read != sizeof(s_segmented_data *))
2068 dlt_log(LOG_ERR, "NWTSegmented: Error while reading queue.\n");
2069 dlt_log(LOG_ERR, strerror(errno));
2073 /* Indicator just to try to flush the buffer */
2074 if(data->payload == (void *)DLT_DELAYED_RESEND_INDICATOR_PATTERN)
2076 dlt_user_log_resend_buffer();
2081 /* Segment the data and send the chunks */
2083 uint16_t offset = 0;
2084 uint16_t sequence = 0;
2088 if(offset + DLT_MAX_TRACE_SEGMENT_SIZE > data->payload_len)
2090 len = data->payload_len - offset;
2094 len = DLT_MAX_TRACE_SEGMENT_SIZE;
2096 /* If payload size aligns perfectly with segment size, avoid sendind empty segment */
2102 ptr = data->payload + offset;
2103 DltReturnValue err = dlt_user_trace_network_segmented_segment(data->id, data->handle, data->nw_trace_type, sequence++, len, ptr);
2104 if(err == DLT_RETURN_BUFFER_FULL || err == DLT_RETURN_ERROR)
2106 dlt_log(LOG_ERR,"NWTSegmented: Could not send segment. Aborting.\n");
2107 break; // Inner loop
2110 }while(ptr < data->payload + data->payload_len);
2112 /* Send the end message */
2113 DltReturnValue err = dlt_user_trace_network_segmented_end(data->id, data->handle, data->nw_trace_type);
2114 if(err == DLT_RETURN_BUFFER_FULL || err == DLT_RETURN_ERROR)
2116 dlt_log(LOG_ERR,"NWTSegmented: Could not send end segment.\n");
2119 /* Free resources */
2121 free(data->payload);
2126 int dlt_user_trace_network_segmented(DltContext *handle, DltNetworkTraceType nw_trace_type, uint16_t header_len, void *header, uint16_t payload_len, void *payload)
2128 /* Send as normal trace if possible */
2129 if(header_len+payload_len+sizeof(uint16_t) < DLT_USER_BUF_MAX_SIZE) {
2130 return dlt_user_trace_network(handle, nw_trace_type, header_len, header, payload_len, payload);
2133 /* Allocate Memory */
2134 s_segmented_data *thread_data = malloc(sizeof(s_segmented_data));
2135 if(thread_data == NULL)
2139 thread_data->header = malloc(header_len);
2140 if(thread_data->header == NULL)
2145 thread_data->payload = malloc(payload_len);
2146 if(thread_data->payload == NULL)
2148 free(thread_data->header);
2154 thread_data->handle = handle;
2155 thread_data->nw_trace_type = nw_trace_type;
2156 thread_data->header_len = header_len;
2157 memcpy(thread_data->header, header, header_len);
2158 thread_data->payload_len = payload_len;
2159 memcpy(thread_data->payload, payload, payload_len);
2161 /* Send start message */
2162 DltReturnValue err = dlt_user_trace_network_segmented_start(&(thread_data->id),
2163 thread_data->handle, thread_data->nw_trace_type,
2164 thread_data->header_len, thread_data->header,
2165 thread_data->payload_len);
2166 if(err == DLT_RETURN_BUFFER_FULL || err == DLT_RETURN_ERROR)
2168 dlt_log(LOG_ERR,"NWTSegmented: Could not send start segment. Aborting.\n");
2169 free(thread_data->header);
2170 free(thread_data->payload);
2176 if(mq_send(dlt_user.dlt_segmented_queue_write_handle,
2177 (char *)&thread_data, sizeof(s_segmented_data *), 1) < 0)
2179 free(thread_data->header);
2180 free(thread_data->payload);
2182 dlt_log(LOG_ERR, "NWTSegmented: Could not write into queue.\n");
2183 dlt_log(LOG_ERR, strerror(errno));
2189 int dlt_user_trace_network(DltContext *handle, DltNetworkTraceType nw_trace_type, uint16_t header_len, void *header, uint16_t payload_len, void *payload)
2191 return dlt_user_trace_network_truncated(handle, nw_trace_type, header_len, header, payload_len, payload, 1);
2194 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)
2198 if (dlt_user_initialised==0)
2206 if (dlt_user_log_init(handle, &log)==-1)
2216 /* Commented out because of DltNetworkTraceType:
2218 if ((nw_trace_type<=0) || (nw_trace_type>0x15))
2227 if (dlt_user.dlt_ll_ts==0)
2233 if (dlt_user.dlt_ll_ts[handle->log_level_pos].trace_status==DLT_TRACE_STATUS_ON)
2238 log.trace_status = nw_trace_type;
2246 /* If truncation is allowed, check if we must do it */
2247 if(allow_truncate > 0 && (header_len+payload_len+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
2249 /* Identify as truncated */
2250 if(dlt_user_log_write_string(&log, "NWTR") < 0)
2255 /* Write header and its length */
2256 if (dlt_user_log_write_raw(&log, header, header_len) < 0)
2261 /* Write original size of payload */
2262 if(dlt_user_log_write_uint16(&log, payload_len) < 0)
2268 * Calculate maximum avaialble space in sending buffer after headers.
2271 int truncated_payload_len = DLT_USER_BUF_MAX_SIZE -
2272 log.size - sizeof(uint16_t) - sizeof(uint32_t);
2274 /* Write truncated payload */
2275 if (dlt_user_log_write_raw(&log, payload, truncated_payload_len) < 0)
2280 else /* Truncation not allowed or data short enough */
2282 /* Write header and its length */
2283 if (dlt_user_log_write_raw(&log, header, header_len)==-1)
2293 /* Write payload and its length */
2294 if (dlt_user_log_write_raw(&log, payload, payload_len)==-1)
2301 return dlt_user_log_send_log(&log, DLT_TYPE_NW_TRACE);
2311 int dlt_log_string(DltContext *handle,DltLogLevelType loglevel, const char *text)
2315 if (dlt_user.verbose_mode==0)
2320 if ((handle==0) || (text==0))
2325 if (dlt_user_log_write_start(handle,&log,loglevel)>0)
2327 if (dlt_user_log_write_string(&log,text)==-1)
2331 if (dlt_user_log_write_finish(&log)==-1)
2340 int dlt_log_string_int(DltContext *handle,DltLogLevelType loglevel, const char *text, int data)
2344 if (dlt_user.verbose_mode==0)
2349 if ((handle==0) || (text==0))
2354 if (dlt_user_log_write_start(handle,&log,loglevel)>0)
2356 if (dlt_user_log_write_string(&log,text)==-1)
2360 if (dlt_user_log_write_int(&log,data)==-1)
2364 if (dlt_user_log_write_finish(&log)==-1)
2373 int dlt_log_string_uint(DltContext *handle,DltLogLevelType loglevel, const char *text, unsigned int data)
2377 if (dlt_user.verbose_mode==0)
2382 if ((handle==0) || (text==0))
2387 if (dlt_user_log_write_start(handle,&log,loglevel)>0)
2389 if (dlt_user_log_write_string(&log,text)==-1)
2393 if (dlt_user_log_write_uint(&log,data)==-1)
2397 if (dlt_user_log_write_finish(&log)==-1)
2406 int dlt_log_int(DltContext *handle,DltLogLevelType loglevel, int data)
2410 if (dlt_user.verbose_mode==0)
2420 if (dlt_user_log_write_start(handle,&log,loglevel)>0)
2422 if (dlt_user_log_write_int(&log,data)==-1)
2426 if (dlt_user_log_write_finish(&log)==-1)
2435 int dlt_log_uint(DltContext *handle,DltLogLevelType loglevel, unsigned int data)
2439 if (dlt_user.verbose_mode==0)
2449 if (dlt_user_log_write_start(handle,&log,loglevel)>0)
2451 if (dlt_user_log_write_uint(&log,data)==-1)
2455 if (dlt_user_log_write_finish(&log)==-1)
2464 int dlt_log_raw(DltContext *handle,DltLogLevelType loglevel, void *data,uint16_t length)
2468 if (dlt_user.verbose_mode==0)
2478 if (dlt_user_log_write_start(handle,&log,loglevel)>0)
2480 if (dlt_user_log_write_raw(&log,data,length)==-1)
2484 if (dlt_user_log_write_finish(&log)==-1)
2493 int dlt_verbose_mode(void)
2495 if (dlt_user_initialised==0)
2503 /* Switch to verbose mode */
2504 dlt_user.verbose_mode = 1;
2509 int dlt_nonverbose_mode(void)
2511 if (dlt_user_initialised==0)
2519 /* Switch to non-verbose mode */
2520 dlt_user.verbose_mode = 0;
2525 int dlt_enable_local_print(void)
2527 if (dlt_user_initialised==0)
2535 dlt_user.enable_local_print = 1;
2540 int dlt_disable_local_print(void)
2542 if (dlt_user_initialised==0)
2550 dlt_user.enable_local_print = 0;
2555 void dlt_user_receiverthread_function(__attribute__((unused)) void *ptr)
2559 /* Check for new messages from DLT daemon */
2560 if (dlt_user_log_check_user_message()==-1)
2562 /* Critical error */
2563 dlt_log(LOG_CRIT,"Receiver thread encountered error condition\n");
2566 usleep(DLT_USER_RECEIVE_DELAY); /* delay */
2570 /* Private functions of user library */
2572 int dlt_user_log_init(DltContext *handle, DltContextData *log)
2574 if (dlt_user_initialised==0)
2582 log->handle = handle;
2587 DltReturnValue dlt_user_log_send_log(DltContextData *log, int mtype)
2590 DltUserHeader userheader;
2593 DltReturnValue ret = DLT_RETURN_OK;
2597 return DLT_RETURN_ERROR;
2602 return DLT_RETURN_ERROR;
2605 if (dlt_user.appID[0]=='\0')
2607 return DLT_RETURN_ERROR;
2610 if (log->handle->contextID[0]=='\0')
2612 return DLT_RETURN_ERROR;
2615 if ((mtype<DLT_TYPE_LOG) || (mtype>DLT_TYPE_CONTROL))
2617 return DLT_RETURN_ERROR;
2620 /* also for Trace messages */
2621 #ifdef DLT_SHM_ENABLE
2622 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG_SHM)==-1)
2624 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG)==-1)
2627 return DLT_RETURN_ERROR;
2630 if (dlt_message_init(&msg,0)==-1)
2632 return DLT_RETURN_ERROR;
2635 msg.storageheader = (DltStorageHeader*)msg.headerbuffer;
2637 if (dlt_set_storageheader(msg.storageheader,dlt_user.ecuID)==-1)
2639 return DLT_RETURN_ERROR;
2642 msg.standardheader = (DltStandardHeader*)(msg.headerbuffer + sizeof(DltStorageHeader));
2643 msg.standardheader->htyp = DLT_HTYP_WEID | DLT_HTYP_WTMS | DLT_HTYP_PROTOCOL_VERSION1 ;
2645 if (dlt_user.verbose_mode)
2647 /* In verbose mode, send extended header */
2648 msg.standardheader->htyp = (msg.standardheader->htyp | DLT_HTYP_UEH );
2652 /* In non-verbose, send extended header if desired */
2653 #if (DLT_USER_USE_EXTENDED_HEADER_FOR_NONVERBOSE==1)
2654 msg.standardheader->htyp = (msg.standardheader->htyp | DLT_HTYP_UEH );
2658 #if (BYTE_ORDER==BIG_ENDIAN)
2659 msg.standardheader->htyp = (msg.standardheader->htyp | DLT_HTYP_MSBF);
2662 msg.standardheader->mcnt = log->handle->mcnt++;
2664 /* Set header extra parameters */
2665 dlt_set_id(msg.headerextra.ecu,dlt_user.ecuID);
2666 //msg.headerextra.seid = 0;
2667 msg.headerextra.tmsp = dlt_uptime();
2669 if (dlt_message_set_extraparameters(&msg,0)==-1)
2671 return DLT_RETURN_ERROR;
2674 /* Fill out extended header, if extended header should be provided */
2675 if (DLT_IS_HTYP_UEH(msg.standardheader->htyp))
2677 /* with extended header */
2678 msg.extendedheader = (DltExtendedHeader*)(msg.headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp) );
2684 msg.extendedheader->msin = (DLT_TYPE_LOG << DLT_MSIN_MSTP_SHIFT) | ((log->log_level << DLT_MSIN_MTIN_SHIFT) & DLT_MSIN_MTIN) ; /* messsage info */
2687 case DLT_TYPE_NW_TRACE:
2689 msg.extendedheader->msin = (DLT_TYPE_NW_TRACE << DLT_MSIN_MSTP_SHIFT) | ((log->trace_status << DLT_MSIN_MTIN_SHIFT) & DLT_MSIN_MTIN) ; /* messsage info */
2694 /* This case should not occur */
2695 return DLT_RETURN_ERROR;
2700 /* If in verbose mode, set flag in header for verbose mode */
2701 if (dlt_user.verbose_mode)
2703 msg.extendedheader->msin |= DLT_MSIN_VERB;
2706 msg.extendedheader->noar = log->args_num; /* number of arguments */
2707 dlt_set_id(msg.extendedheader->apid,dlt_user.appID); /* application id */
2708 dlt_set_id(msg.extendedheader->ctid,log->handle->contextID); /* context id */
2710 msg.headersize = sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + sizeof(DltExtendedHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp);
2714 /* without extended header */
2715 msg.headersize = sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp);
2718 len=msg.headersize - sizeof(DltStorageHeader) +log->size;
2721 dlt_log(LOG_CRIT,"Huge message discarded!\n");
2722 return DLT_RETURN_ERROR;
2725 msg.standardheader->len = DLT_HTOBE_16(len);
2727 /* print to std out, if enabled */
2728 if ((dlt_user.local_print_mode != DLT_PM_FORCE_OFF) &&
2729 (dlt_user.local_print_mode != DLT_PM_AUTOMATIC))
2731 if ((dlt_user.enable_local_print) || (dlt_user.local_print_mode == DLT_PM_FORCE_ON))
2733 if (dlt_user_print_msg(&msg, log)==-1)
2735 return DLT_RETURN_ERROR;
2740 if (dlt_user.dlt_is_file)
2743 ret=dlt_user_log_out2(dlt_user.dlt_log_handle, msg.headerbuffer, msg.headersize, log->buffer, log->size);
2748 /* Reattach to daemon if neccesary */
2749 dlt_user_log_reattach_to_daemon();
2751 if (dlt_user.overflow)
2753 if (dlt_user_log_send_overflow()==0)
2755 dlt_user.overflow=0;
2759 /* try to resent old data first */
2760 ret = DLT_RETURN_OK;
2761 if(dlt_user.dlt_log_handle!=-1)
2762 ret = dlt_user_log_resend_buffer();
2763 if(ret==DLT_RETURN_OK)
2765 /* resend ok or nothing to resent */
2766 #ifdef DLT_SHM_ENABLE
2767 if(dlt_user.dlt_log_handle!=-1)
2768 dlt_shm_push(&dlt_user.dlt_shm,msg.headerbuffer+sizeof(DltStorageHeader), msg.headersize-sizeof(DltStorageHeader),
2769 log->buffer, log->size,0,0);
2772 ret = dlt_user_log_out3(dlt_user.dlt_log_handle,
2773 &(userheader), sizeof(DltUserHeader),
2778 #ifdef DLT_TEST_ENABLE
2779 if(dlt_user.corrupt_user_header) {
2780 userheader.pattern[0]=0xff;
2781 userheader.pattern[1]=0xff;
2782 userheader.pattern[2]=0xff;
2783 userheader.pattern[3]=0xff;
2785 if(dlt_user.corrupt_message_size) {
2786 msg.standardheader->len = DLT_HTOBE_16(dlt_user.corrupt_message_size_size);
2789 ret = dlt_user_log_out3(dlt_user.dlt_log_handle,
2790 &(userheader), sizeof(DltUserHeader),
2791 msg.headerbuffer+sizeof(DltStorageHeader), msg.headersize-sizeof(DltStorageHeader),
2792 log->buffer, log->size);
2796 /* store message in ringbuffer, if an error has occured */
2797 if (ret!=DLT_RETURN_OK)
2801 if (dlt_buffer_push3(&(dlt_user.startup_buffer),
2802 (unsigned char *)&(userheader), sizeof(DltUserHeader),
2803 msg.headerbuffer+sizeof(DltStorageHeader), msg.headersize-sizeof(DltStorageHeader),
2804 log->buffer, log->size)==-1)
2806 dlt_log(LOG_ERR,"Storing message to history buffer failed! Message discarded.\n");
2807 ret = DLT_RETURN_BUFFER_FULL;
2813 * Ask segmented thread to try emptying the buffer soon.
2814 * This will be freed in dlt_user_trace_network_segmented_thread
2816 s_segmented_data *resend_data = malloc(sizeof(s_segmented_data));
2817 resend_data->payload = (void *)DLT_DELAYED_RESEND_INDICATOR_PATTERN;
2818 if(mq_send(dlt_user.dlt_segmented_queue_write_handle, (char *)&resend_data, sizeof(s_segmented_data *), 1) < 0)
2820 dlt_log(LOG_ERR,"Could not request resending.\n");
2821 dlt_log(LOG_ERR, strerror(errno));
2828 case DLT_RETURN_BUFFER_FULL:
2831 return DLT_RETURN_BUFFER_FULL;
2833 case DLT_RETURN_PIPE_FULL:
2835 /* data could not be written */
2836 dlt_user.overflow = 1;
2837 return DLT_RETURN_PIPE_FULL;
2839 case DLT_RETURN_PIPE_ERROR:
2841 /* handle not open or pipe error */
2842 close(dlt_user.dlt_log_handle);
2843 dlt_user.dlt_log_handle = -1;
2845 #ifdef DLT_SHM_ENABLE
2846 /* free shared memory */
2847 dlt_shm_free_client(&dlt_user.dlt_shm);
2850 if (dlt_user.local_print_mode == DLT_PM_AUTOMATIC)
2852 dlt_user_print_msg(&msg, log);
2855 return DLT_RETURN_PIPE_ERROR;
2857 case DLT_RETURN_ERROR:
2859 /* other error condition */
2860 return DLT_RETURN_ERROR;
2864 return DLT_RETURN_OK;
2868 /* This case should never occur. */
2869 return DLT_RETURN_ERROR;
2874 return DLT_RETURN_OK;
2877 int dlt_user_log_send_register_application(void)
2879 DltUserHeader userheader;
2880 DltUserControlMsgRegisterApplication usercontext;
2884 if (dlt_user.appID[0]=='\0')
2889 /* set userheader */
2890 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_REGISTER_APPLICATION)==-1)
2895 /* set usercontext */
2896 dlt_set_id(usercontext.apid,dlt_user.appID); /* application id */
2897 usercontext.pid = getpid();
2899 if (dlt_user.application_description!=0)
2901 usercontext.description_length = strlen(dlt_user.application_description);
2905 usercontext.description_length = 0;
2908 if (dlt_user.dlt_is_file)
2914 ret=dlt_user_log_out3(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgRegisterApplication),dlt_user.application_description,usercontext.description_length);
2916 /* store message in ringbuffer, if an error has occured */
2917 if (ret!=DLT_RETURN_OK)
2921 if (dlt_buffer_push3(&(dlt_user.startup_buffer),
2922 (unsigned char *)&(userheader), sizeof(DltUserHeader),
2923 (const unsigned char*)&(usercontext), sizeof(DltUserControlMsgRegisterApplication),
2924 (const unsigned char*)dlt_user.application_description, usercontext.description_length)==-1)
2926 dlt_log(LOG_ERR,"Storing message to history buffer failed! Message discarded.\n");
2937 int dlt_user_log_send_unregister_application(void)
2939 DltUserHeader userheader;
2940 DltUserControlMsgUnregisterApplication usercontext;
2944 if (dlt_user.appID[0]=='\0')
2949 /* set userheader */
2950 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_UNREGISTER_APPLICATION)==-1)
2955 /* set usercontext */
2956 dlt_set_id(usercontext.apid,dlt_user.appID); /* application id */
2957 usercontext.pid = getpid();
2959 if (dlt_user.dlt_is_file)
2965 ret=dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgUnregisterApplication));
2966 return ((ret==DLT_RETURN_OK)?0:-1);
2969 int dlt_user_log_send_register_context(DltContextData *log)
2971 DltUserHeader userheader;
2972 DltUserControlMsgRegisterContext usercontext;
2985 if ((dlt_user.appID[0]=='\0') || (log->handle->contextID=='\0'))
2990 /* set userheader */
2991 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_REGISTER_CONTEXT)==-1)
2996 /* set usercontext */
2997 dlt_set_id(usercontext.apid,dlt_user.appID); /* application id */
2998 dlt_set_id(usercontext.ctid,log->handle->contextID); /* context id */
2999 usercontext.log_level_pos = log->handle->log_level_pos;
3000 usercontext.pid = getpid();
3002 usercontext.log_level = (int8_t)log->log_level;
3003 usercontext.trace_status = (int8_t)log->trace_status;
3005 if (log->context_description!=0)
3007 usercontext.description_length = strlen(log->context_description);
3011 usercontext.description_length = 0;
3014 if (dlt_user.dlt_is_file)
3020 ret=dlt_user_log_out3(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgRegisterContext),log->context_description,usercontext.description_length);
3022 /* store message in ringbuffer, if an error has occured */
3023 if (ret!=DLT_RETURN_OK)
3027 if (dlt_buffer_push3(&(dlt_user.startup_buffer),
3028 (unsigned char *)&(userheader), sizeof(DltUserHeader),
3029 (const unsigned char*)&(usercontext), sizeof(DltUserControlMsgRegisterContext),
3030 (const unsigned char*)log->context_description, usercontext.description_length)==-1)
3032 dlt_log(LOG_ERR,"Storing message to history buffer failed! Message discarded.\n");
3044 int dlt_user_log_send_unregister_context(DltContextData *log)
3046 DltUserHeader userheader;
3047 DltUserControlMsgUnregisterContext usercontext;
3060 if ((dlt_user.appID[0]=='\0') || (log->handle->contextID=='\0'))
3065 /* set userheader */
3066 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_UNREGISTER_CONTEXT)==-1)
3071 /* set usercontext */
3072 dlt_set_id(usercontext.apid,dlt_user.appID); /* application id */
3073 dlt_set_id(usercontext.ctid,log->handle->contextID); /* context id */
3074 usercontext.pid = getpid();
3076 if (dlt_user.dlt_is_file)
3082 ret=dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgUnregisterContext));
3083 return ((ret==DLT_RETURN_OK)?0:-1);
3086 int dlt_send_app_ll_ts_limit(const char *appid, DltLogLevelType loglevel, DltTraceStatusType tracestatus)
3088 DltUserHeader userheader;
3089 DltUserControlMsgAppLogLevelTraceStatus usercontext;
3092 if ((appid==0) || (appid[0]=='\0'))
3097 /* Removed because of DltLogLevelType and DltTraceStatusType
3099 if ((loglevel<DLT_LOG_DEFAULT) || (loglevel>DLT_LOG_VERBOSE))
3104 if ((tracestatus<DLT_TRACE_STATUS_DEFAULT) || (tracestatus>DLT_TRACE_STATUS_ON))
3111 /* set userheader */
3112 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_APP_LL_TS)==-1)
3117 /* set usercontext */
3118 dlt_set_id(usercontext.apid,appid); /* application id */
3119 usercontext.log_level = loglevel;
3120 usercontext.trace_status = tracestatus;
3122 if (dlt_user.dlt_is_file)
3128 ret=dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgAppLogLevelTraceStatus));
3129 return ((ret==DLT_RETURN_OK)?0:-1);
3132 int dlt_user_log_send_log_mode(DltUserLogMode mode)
3134 DltUserHeader userheader;
3135 DltUserControlMsgLogMode logmode;
3139 /* set userheader */
3140 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG_MODE)==-1)
3146 logmode.log_mode = (unsigned char) mode;
3148 if (dlt_user.dlt_is_file)
3154 ret=dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(logmode), sizeof(DltUserControlMsgLogMode));
3155 return ((ret==DLT_RETURN_OK)?0:-1);
3158 int dlt_user_print_msg(DltMessage *msg, DltContextData *log)
3160 uint8_t *databuffer_tmp;
3161 int32_t datasize_tmp;
3162 int32_t databuffersize_tmp;
3163 static char text[DLT_USER_TEXT_LENGTH];
3165 if ((msg==0) || (log==0))
3170 /* Save variables before print */
3171 databuffer_tmp = msg->databuffer;
3172 datasize_tmp = msg->datasize;
3173 databuffersize_tmp = msg->databuffersize;
3175 /* Act like a receiver, convert header back to host format */
3176 msg->standardheader->len = DLT_BETOH_16(msg->standardheader->len);
3177 dlt_message_get_extraparameters(msg,0);
3179 msg->databuffer = log->buffer;
3180 msg->datasize = log->size;
3181 msg->databuffersize = log->size;
3183 /* Print message as ASCII */
3184 if (dlt_message_print_ascii(msg,text,DLT_USER_TEXT_LENGTH,0)==-1)
3189 /* Restore variables and set len to BE*/
3190 msg->databuffer = databuffer_tmp;
3191 msg->databuffersize = databuffersize_tmp;
3192 msg->datasize = datasize_tmp;
3194 msg->standardheader->len = DLT_HTOBE_16(msg->standardheader->len);
3199 int dlt_user_log_check_user_message(void)
3206 DltUserHeader *userheader;
3207 DltReceiver *receiver = &(dlt_user.receiver);
3209 DltUserControlMsgLogLevel *usercontextll;
3210 DltUserControlMsgInjection *usercontextinj;
3211 DltUserControlMsgLogState *userlogstate;
3212 unsigned char *userbuffer;
3214 /* For delayed calling of injection callback, to avoid deadlock */
3215 DltUserInjectionCallback delayed_injection_callback;
3216 unsigned char *delayed_inject_buffer = 0;
3217 uint32_t delayed_inject_data_length = 0;
3219 /* Ensure that callback is null before searching for it */
3220 delayed_injection_callback.injection_callback = 0;
3221 delayed_injection_callback.service_id = 0;
3223 if (dlt_user.dlt_user_handle!=DLT_FD_INIT)
3227 if (dlt_receiver_receive_fd(receiver)<=0)
3229 /* No new message available */
3233 /* look through buffer as long as data is in there */
3236 if (receiver->bytesRcvd < (int32_t)sizeof(DltUserHeader))
3241 /* resync if necessary */
3245 userheader = (DltUserHeader*) (receiver->buf+offset);
3247 /* Check for user header pattern */
3248 if (dlt_user_check_userheader(userheader))
3255 while ((int32_t)(sizeof(DltUserHeader)+offset)<=receiver->bytesRcvd);
3257 /* Check for user header pattern */
3258 if (dlt_user_check_userheader(userheader)==0)
3263 /* Set new start offset */
3266 receiver->buf+=offset;
3267 receiver->bytesRcvd-=offset;
3270 switch (userheader->message)
3272 case DLT_USER_MESSAGE_LOG_LEVEL:
3274 if (receiver->bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogLevel)))
3280 usercontextll = (DltUserControlMsgLogLevel*) (receiver->buf+sizeof(DltUserHeader));
3282 /* Update log level and trace status */
3283 if (usercontextll!=0)
3287 if ((usercontextll->log_level_pos >= 0) && (usercontextll->log_level_pos < (int32_t)dlt_user.dlt_ll_ts_num_entries))
3289 // printf("Store ll, ts\n");
3290 if (dlt_user.dlt_ll_ts)
3292 dlt_user.dlt_ll_ts[usercontextll->log_level_pos].log_level = usercontextll->log_level;
3293 dlt_user.dlt_ll_ts[usercontextll->log_level_pos].trace_status = usercontextll->trace_status;
3300 /* keep not read data in buffer */
3301 if (dlt_receiver_remove(receiver,sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogLevel))==-1)
3307 case DLT_USER_MESSAGE_INJECTION:
3309 /* At least, user header, user context, and service id and data_length of injected message is available */
3310 if (receiver->bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgInjection)))
3316 usercontextinj = (DltUserControlMsgInjection*) (receiver->buf+sizeof(DltUserHeader));
3317 userbuffer = (unsigned char*) (receiver->buf+sizeof(DltUserHeader)+sizeof(DltUserControlMsgInjection));
3322 if (receiver->bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgInjection)+usercontextinj->data_length_inject))
3330 if ((usercontextinj->data_length_inject>0) && (dlt_user.dlt_ll_ts))
3332 /* Check if injection callback is registered for this context */
3333 for (i=0; i<dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].nrcallbacks;i++)
3335 if ((dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table) &&
3336 (dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table[i].service_id == usercontextinj->service_id))
3338 /* Prepare delayed injection callback call */
3339 if (dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table[i].injection_callback!=0)
3341 delayed_injection_callback.injection_callback = dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table[i].injection_callback;
3342 delayed_injection_callback.service_id = usercontextinj->service_id;
3343 delayed_inject_data_length = usercontextinj->data_length_inject;
3344 delayed_inject_buffer = malloc(delayed_inject_data_length);
3345 if(delayed_inject_buffer != 0) {
3346 memcpy(delayed_inject_buffer, userbuffer, delayed_inject_data_length);
3357 /* Delayed injection callback call */
3358 if(delayed_inject_buffer != 0 && delayed_injection_callback.injection_callback != 0) {
3359 delayed_injection_callback.injection_callback(delayed_injection_callback.service_id, delayed_inject_buffer, delayed_inject_data_length);
3360 free(delayed_inject_buffer);
3363 /* keep not read data in buffer */
3364 if (dlt_receiver_remove(receiver,(sizeof(DltUserHeader)+sizeof(DltUserControlMsgInjection)+usercontextinj->data_length_inject))==-1)
3371 case DLT_USER_MESSAGE_LOG_STATE:
3373 /* At least, user header, user context, and service id and data_length of injected message is available */
3374 if (receiver->bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogState)))
3380 userlogstate = (DltUserControlMsgLogState*) (receiver->buf+sizeof(DltUserHeader));
3381 dlt_user.log_state = userlogstate->log_state;
3383 /* keep not read data in buffer */
3384 if (dlt_receiver_remove(receiver,(sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogState)))==-1)
3392 dlt_log(LOG_ERR,"Invalid user message type received!\n");
3394 dlt_receiver_remove(receiver,sizeof(DltUserHeader));
3395 /* In next invocation of while loop, a resync will be triggered if additional data was received */
3408 if (dlt_receiver_move_to_begin(receiver)==-1)
3412 } /* while receive */
3415 return DLT_RETURN_OK;
3418 int dlt_user_log_resend_buffer(void)
3421 uint8_t buf[DLT_USER_RCVBUF_MAX_SIZE];
3425 /* Send content of ringbuffer */
3427 count = dlt_buffer_get_message_count(&(dlt_user.startup_buffer));
3430 for (num=0;num<count;num++)
3434 size = dlt_buffer_copy(&(dlt_user.startup_buffer),buf,sizeof(buf));
3438 #ifdef DLT_SHM_ENABLE
3439 dlt_shm_push(&dlt_user.dlt_shm,buf+sizeof(DltUserHeader),size-sizeof(DltUserHeader),0,0,0,0);
3442 ret = dlt_user_log_out3(dlt_user.dlt_log_handle, buf,sizeof(DltUserHeader),0,0,0,0);
3445 ret = dlt_user_log_out3(dlt_user.dlt_log_handle, buf,size,0,0,0,0);
3448 /* in case of error, keep message in ringbuffer */
3449 if (ret==DLT_RETURN_OK)
3451 dlt_buffer_remove(&(dlt_user.startup_buffer));
3455 /* keep message in ringbuffer */
3466 void dlt_user_log_reattach_to_daemon(void)
3468 uint32_t num,reregistered=0;
3471 DltContextData log_new;
3473 if (dlt_user.dlt_log_handle<0)
3475 dlt_user.dlt_log_handle=-1;
3477 /* try to open pipe to dlt daemon */
3478 dlt_user.dlt_log_handle = open(DLT_USER_FIFO, O_WRONLY | O_NONBLOCK);
3479 if (dlt_user.dlt_log_handle > 0)
3481 if (dlt_user_log_init(&handle,&log_new)==-1)
3486 #ifdef DLT_SHM_ENABLE
3487 /* init shared memory */
3488 if (dlt_shm_init_client(&dlt_user.dlt_shm,DLT_SHM_KEY) < 0)
3490 sprintf(str,"Loging disabled, Shared memory %d cannot be created!\n",DLT_SHM_KEY);
3491 dlt_log(LOG_WARNING, str);
3496 dlt_log(LOG_NOTICE, "Logging re-enabled!\n");
3498 /* Re-register application */
3499 if (dlt_user_log_send_register_application()==-1)
3506 /* Re-register all stored contexts */
3507 for (num=0; num<dlt_user.dlt_ll_ts_num_entries; num++)
3509 /* Re-register stored context */
3510 if ((dlt_user.appID[0]!='\0') && (dlt_user.dlt_ll_ts[num].contextID[0]!='\0') && (dlt_user.dlt_ll_ts))
3512 //dlt_set_id(log_new.appID, dlt_user.appID);
3513 dlt_set_id(handle.contextID, dlt_user.dlt_ll_ts[num].contextID);
3514 handle.log_level_pos = num;
3515 log_new.context_description = dlt_user.dlt_ll_ts[num].context_description;
3517 log_new.log_level = DLT_USER_LOG_LEVEL_NOT_SET;
3518 log_new.trace_status = DLT_USER_TRACE_STATUS_NOT_SET;
3520 if (dlt_user_log_send_register_context(&log_new)==-1)
3532 if (reregistered==1)
3534 dlt_user_log_resend_buffer();
3540 int dlt_user_log_send_overflow(void)
3542 DltUserHeader userheader;
3545 /* set userheader */
3546 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_OVERFLOW)==-1)
3551 if (dlt_user.dlt_is_file)
3557 ret=dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), 0, 0);
3558 return ((ret==DLT_RETURN_OK)?0:-1);
3561 int dlt_user_check_buffer(int *total_size, int *used_size)
3563 #ifdef DLT_SHM_ENABLE
3564 *total_size = dlt_shm_get_total_size(&(dlt_user.dlt_shm));
3565 *used_size = dlt_shm_get_used_size(&(dlt_user.dlt_shm));
3567 *total_size = dlt_buffer_get_total_size(&(dlt_user.startup_buffer));
3568 *used_size = dlt_buffer_get_used_size(&(dlt_user.startup_buffer));
3574 #ifdef DLT_TEST_ENABLE
3575 void dlt_user_test_corrupt_user_header(int enable)
3577 dlt_user.corrupt_user_header = enable;
3579 void dlt_user_test_corrupt_message_size(int enable,int16_t size)
3581 dlt_user.corrupt_message_size = enable;
3582 dlt_user.corrupt_message_size_size = size;