automotive-dlt
dlt_user.c
Go to the documentation of this file.
1 /*
2  * @licence app begin@
3  * SPDX license identifier: MPL-2.0
4  *
5  * Copyright (C) 2011-2015, BMW AG
6  *
7  * This file is part of GENIVI Project DLT - Diagnostic Log and Trace.
8  *
9  * This Source Code Form is subject to the terms of the
10  * Mozilla Public License (MPL), v. 2.0.
11  * If a copy of the MPL was not distributed with this file,
12  * You can obtain one at http://mozilla.org/MPL/2.0/.
13  *
14  * For further information see http://www.genivi.org/.
15  * @licence end@
16  */
17 
30 #include <stdlib.h> /* for getenv(), free(), atexit() */
31 #include <string.h> /* for strcmp(), strncmp(), strlen(), memset(), memcpy() */
32 #include <signal.h> /* for signal(), SIGPIPE, SIG_IGN */
33 
34 #if !defined (__WIN32__)
35 #include <syslog.h> /* for LOG_... */
36 #include <semaphore.h>
37 #include <pthread.h> /* POSIX Threads */
38 #endif
39 
40 #include <sys/time.h>
41 #include <math.h>
42 
43 #include <sys/stat.h>
44 #include <fcntl.h>
45 #include <errno.h>
46 
47 #include <sys/uio.h> /* writev() */
48 
49 #include <limits.h>
50 #ifdef linux
51 #include <sys/prctl.h>
52 #endif
53 
54 #include <sys/types.h> /* needed for getpid() */
55 #include <unistd.h>
56 
57 #include <stdbool.h>
58 
59 
60 #include "dlt_user.h"
61 #include "dlt_common.h"
62 #include "dlt_user_shared.h"
63 #include "dlt_user_shared_cfg.h"
64 #include "dlt_user_cfg.h"
65 
66 #ifdef DLT_FATAL_LOG_RESET_ENABLE
67 #define DLT_LOG_FATAL_RESET_TRAP(LOGLEVEL) \
68  do { \
69  if (LOGLEVEL == DLT_LOG_FATAL) { \
70  int *p = NULL; \
71  *p = 0; \
72  } \
73  } while(0)
74 #else /* DLT_FATAL_LOG_RESET_ENABLE */
75 #define DLT_LOG_FATAL_RESET_TRAP(LOGLEVEL)
76 #endif /* DLT_FATAL_LOG_RESET_ENABLE */
77 
79 static bool dlt_user_initialised = false;
80 static int dlt_user_freeing = 0;
81 
82 static char dlt_user_dir[NAME_MAX + 1];
83 static char dlt_daemon_fifo[NAME_MAX + 1];
84 
86 
87 static sem_t dlt_mutex;
88 static pthread_t dlt_receiverthread_handle;
89 
90 // calling dlt_user_atexit_handler() second time fails with error message
91 static int atexit_registered = 0;
92 
93 // calling atfork_handler() only once
94 static int atfork_registered = 0;
95 
96 
97 /* Segmented Network Trace */
98 #define DLT_MAX_TRACE_SEGMENT_SIZE 1024
99 #define DLT_MESSAGE_QUEUE_NAME "/dlt_message_queue"
100 #define DLT_DELAYED_RESEND_INDICATOR_PATTERN 0xFFFF
101 
102 /* Mutex to wait on while message queue is not initialized */
103 pthread_mutex_t mq_mutex;
104 pthread_cond_t mq_init_condition;
105 
106 void dlt_lock_mutex(pthread_mutex_t *mutex)
107 {
108  int32_t lock_mutex_result = pthread_mutex_lock(mutex);
109  if (lock_mutex_result == EOWNERDEAD)
110  {
111  pthread_mutex_consistent(mutex);
112  lock_mutex_result = 0;
113  }
114  else if ( lock_mutex_result != 0 )
115  {
116  snprintf(str,DLT_USER_BUFFER_LENGTH, "Mutex lock failed unexpected pid=%i with result %i!\n", getpid(), lock_mutex_result);
117  dlt_log(LOG_ERR, str);
118  }
119 }
120 
121 void dlt_unlock_mutex(pthread_mutex_t *mutex)
122 {
123  pthread_mutex_unlock(mutex);
124 }
125 
126 /* Structure to pass data to segmented thread */
127 typedef struct
128 {
130  uint32_t id;
132  uint32_t header_len;
133  void *header;
134  uint32_t payload_len;
135  void *payload;
137 
138 /* Function prototypes for internally used functions */
139 static void dlt_user_receiverthread_function(void *ptr);
140 static void dlt_user_atexit_handler(void);
142 static DltReturnValue dlt_user_log_send_log(DltContextData *log, int mtype);
147 static DltReturnValue dlt_send_app_ll_ts_limit(const char *appid, DltLogLevelType loglevel, DltTraceStatusType tracestatus);
152 static void dlt_user_log_reattach_to_daemon(void);
154 static void dlt_user_trace_network_segmented_thread(void *unused);
157 
158 static int dlt_start_threads();
159 static void dlt_stop_threads();
160 static void dlt_fork_pre_fork_handler();
161 static void dlt_fork_parent_fork_handler();
162 static void dlt_fork_child_fork_handler();
163 
164 
165 DltReturnValue dlt_user_check_library_version(const char *user_major_version,const char *user_minor_version)
166 {
167  char lib_major_version[DLT_USER_MAX_LIB_VERSION_LENGTH];
168  char lib_minor_version[DLT_USER_MAX_LIB_VERSION_LENGTH];
169 
172 
173  if( (strcmp(lib_major_version,user_major_version) != 0) || (strcmp(lib_minor_version,user_minor_version) != 0))
174  {
175  dlt_vnlog(LOG_WARNING, DLT_USER_BUFFER_LENGTH,
176  "DLT Library version check failed! Installed DLT library version is %s.%s - Application using DLT library version %s.%s\n",
177  lib_major_version,
178  lib_minor_version,
179  user_major_version,
180  user_minor_version);
181 
182  return DLT_RETURN_ERROR;
183  }
184 
185  return DLT_RETURN_OK;
186 }
187 
189 {
190  char filename[DLT_USER_MAX_FILENAME_LENGTH];
191  int ret;
192 
193  // process is exiting. Do not allocate new resources.
194  if (dlt_user_freeing != 0)
195  {
196  // return negative value, to stop the current log
197  return DLT_RETURN_ERROR;
198  }
199 
200  // WARNING: multithread unsafe !
201  // Another thread will check that dlt_user_initialised != 0, but the lib is not initialised !
202  dlt_user_initialised = true;
203 
204  /* Initialize common part of dlt_init()/dlt_init_file() */
206  {
207  dlt_user_initialised = false;
208  return DLT_RETURN_ERROR;
209  }
210 
211  /* check environment variables */
213 
214  snprintf(dlt_user_dir, NAME_MAX, "%s/dltpipes", dltFifoBaseDir);
215  snprintf(dlt_daemon_fifo, NAME_MAX, "%s/dlt", dltFifoBaseDir);
216 
217  dlt_user.dlt_is_file = 0;
218  dlt_user.overflow = 0;
219  dlt_user.overflow_counter = 0;
220 #ifdef DLT_SHM_ENABLE
221  memset(&(dlt_user.dlt_shm),0,sizeof(DltShm));
222 #endif
223 
224  /* create dlt pipes directory */
225  /* Make sure the parent user directory is created */
227  {
228  dlt_vnlog(LOG_ERR,DLT_USER_BUFFER_LENGTH, "Base dir %s cannot be created!\n", dltFifoBaseDir);
229  return DLT_RETURN_ERROR;
230  }
231 
232  ret=mkdir(dlt_user_dir, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH | S_ISVTX );
233  if (ret==-1 && errno != EEXIST)
234  {
235  dlt_vnlog(LOG_ERR, DLT_USER_BUFFER_LENGTH, "FIFO user dir %s cannot be created!\n", dlt_user_dir);
236  return DLT_RETURN_ERROR;
237  }
238 
239  /* if dlt pipes directory is created by the application also chmod the directory */
240  if(ret == 0)
241  {
242  // S_ISGID cannot be set by mkdir, let's reassign right bits
243  ret=chmod(dlt_user_dir, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH | S_ISGID | S_ISVTX );
244  if (ret==-1)
245  {
246  dlt_vnlog(LOG_ERR, DLT_USER_BUFFER_LENGTH, "FIFO user dir %s cannot be chmoded!\n", dlt_user_dir);
247  return DLT_RETURN_ERROR;
248  }
249  }
250 
251  /* create and open DLT user FIFO */
252  snprintf(filename,DLT_USER_MAX_FILENAME_LENGTH,"%s/dlt%d",dlt_user_dir,getpid());
253 
254  /* Try to delete existing pipe, ignore result of unlink */
255  unlink(filename);
256 
257  ret=mkfifo(filename, S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP );
258  if (ret==-1)
259  {
260  dlt_vnlog(LOG_WARNING, DLT_USER_BUFFER_LENGTH, "Loging disabled, FIFO user %s cannot be created!\n", filename);
261  /* return DLT_RETURN_OK; */ /* removed to prevent error, when FIFO already exists */
262  }
263 
264  // S_IWGRP cannot be set by mkfifo (???), let's reassign right bits
265  ret=chmod(filename, S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP );
266  if (ret==-1)
267  {
268  dlt_vnlog(LOG_WARNING, DLT_USER_BUFFER_LENGTH, "FIFO user %s cannot be chmoded!\n", dlt_user_dir);
269  return DLT_RETURN_ERROR;
270  }
271 
272  dlt_user.dlt_user_handle = open(filename, O_RDWR | O_CLOEXEC);
273  if (dlt_user.dlt_user_handle == DLT_FD_INIT)
274  {
275  dlt_vnlog(LOG_WARNING, DLT_USER_BUFFER_LENGTH, "Logging disabled, FIFO user %s cannot be opened!\n", filename);
276  unlink(filename);
277  return DLT_RETURN_OK;
278  }
279 
280  /* open DLT output FIFO */
281  dlt_user.dlt_log_handle = open(dlt_daemon_fifo, O_WRONLY | O_NONBLOCK | O_CLOEXEC );
282  if (dlt_user.dlt_log_handle==-1)
283  {
284  /* This is a normal usecase. It is OK that the daemon (and thus the FIFO /tmp/dlt)
285  starts later and some DLT users have already been started before.
286  Thus it is OK if the FIFO can't be opened. */
287  dlt_vnlog(LOG_INFO, DLT_USER_BUFFER_LENGTH, "FIFO %s cannot be opened. Retrying later...\n",dlt_daemon_fifo);
288  //return DLT_RETURN_OK;
289  }
290  else
291  {
292 #ifdef DLT_SHM_ENABLE
293  /* init shared memory */
294  if (dlt_shm_init_client(&(dlt_user.dlt_shm),DLT_SHM_KEY) < 0)
295  {
296  /* This is a normal usecase. It is OK that the daemon (and thus the FIFO /tmp/dlt)
297  starts later and some DLT users have already been started before.
298  Thus it is OK if the FIFO can't be opened. */
299  dlt_vnlog(LOG_INFO, DLT_USER_BUFFER_LENGTH, "Shared memory %d cannot be created. Retrying later...\n", DLT_SHM_KEY);
300  //return DLT_RETURN_OK;
301  }
302 #endif
303  }
304 
305 
307  {
308  dlt_user_initialised = false;
309  return DLT_RETURN_ERROR;
310  }
311 
312  /* These will be lazy initialized only when needed */
313  dlt_user.dlt_segmented_queue_read_handle = -1;
314  dlt_user.dlt_segmented_queue_write_handle = -1;
315 
316  /* Wait mutext for segmented thread */
317  pthread_mutexattr_t attr;
318  if (pthread_mutexattr_init(&attr) != 0)
319  {
320  dlt_user_initialised = false;
321  return DLT_RETURN_ERROR;
322  }
323  /* make mutex robust to prevent from deadlock when the segmented thread was cancelled, but held the mutex */
324  if ( pthread_mutexattr_setrobust(&attr, PTHREAD_MUTEX_ROBUST) != 0 )
325  {
326  dlt_user_initialised = false;
327  return DLT_RETURN_ERROR;
328  }
329 
330  pthread_mutex_init(&mq_mutex, &attr);
331  pthread_mutexattr_destroy(&attr);
332  pthread_cond_init(&mq_init_condition, NULL);
333 
334  if (dlt_start_threads() < 0)
335  {
336  dlt_user_initialised = false;
337  return DLT_RETURN_ERROR;
338  }
339 
340  // prepare for fork() call
341  if (atfork_registered == 0)
342  {
343  atfork_registered = 1;
345  }
346 
347  return DLT_RETURN_OK;
348 }
349 
350 DltReturnValue dlt_init_file(const char *name)
351 {
352  // check null pointer
353  if(!name)
355 
356  dlt_user_initialised = true;
357 
358  /* Initialize common part of dlt_init()/dlt_init_file() */
360  {
361  dlt_user_initialised = false;
362  return DLT_RETURN_ERROR;
363  }
364 
365  dlt_user.dlt_is_file = 1;
366 
367  /* open DLT output file */
368  dlt_user.dlt_log_handle = open(name,O_WRONLY|O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); /* mode: wb */
369  if (dlt_user.dlt_log_handle == -1)
370  {
371  dlt_vnlog(LOG_ERR, DLT_USER_BUFFER_LENGTH, "Log file %s cannot be opened!\n", name);
372  return DLT_RETURN_ERROR;
373  }
374 
375  return DLT_RETURN_OK;
376 }
377 
379 {
381  if(dlt_user.dlt_segmented_queue_read_handle >= 0 &&
382  dlt_user.dlt_segmented_queue_write_handle >= 0)
383  {
384  // Already intialized
386  return DLT_RETURN_OK;
387  }
388 
389  /* Generate per process name for queue */
390  char queue_name[NAME_MAX];
391  snprintf(queue_name,NAME_MAX, "%s.%d", DLT_MESSAGE_QUEUE_NAME, getpid());
392 
393  /* Maximum queue size is 10, limit to size of pointers */
394  struct mq_attr mqatr;
395  mqatr.mq_flags = 0;
396  mqatr.mq_maxmsg = 10;
397  mqatr.mq_msgsize = sizeof(s_segmented_data *);
398  mqatr.mq_curmsgs = 0;
399 
404  dlt_user.dlt_segmented_queue_read_handle = mq_open(queue_name, O_CREAT| O_RDONLY | O_EXCL,
405  S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, &mqatr);
406  if(dlt_user.dlt_segmented_queue_read_handle < 0)
407  {
408  if(errno == EEXIST)
409  {
410  dlt_log(LOG_WARNING, "Old message queue exists, trying to delete.\n");
411  if(mq_unlink(queue_name) < 0)
412  {
413  dlt_vnlog(LOG_CRIT, 256, "Could not delete existing message queue!: %s \n", strerror(errno));
414  }
415  else // Retry
416  {
417  dlt_user.dlt_segmented_queue_read_handle = mq_open(queue_name, O_CREAT| O_RDONLY | O_EXCL,
418  S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, &mqatr);
419  }
420  }
421  if(dlt_user.dlt_segmented_queue_read_handle < 0)
422  {
423  dlt_vnlog(LOG_CRIT, 256, "Can't create message queue read handle!: %s \n", strerror(errno));
425  return DLT_RETURN_ERROR;
426  }
427  }
428 
429  dlt_user.dlt_segmented_queue_write_handle = mq_open(queue_name, O_WRONLY|O_NONBLOCK);
430  if(dlt_user.dlt_segmented_queue_write_handle < 0)
431  {
432 
433  dlt_vnlog(LOG_CRIT, 256, "Can't open message queue write handle!: %s \n", strerror(errno));
435  return DLT_RETURN_ERROR;
436  }
437 
438  pthread_cond_signal(&mq_init_condition);
440  return DLT_RETURN_OK;
441 }
442 
444 {
445  char *env_local_print;
446  char * env_initial_log_level;
447  char *env_buffer_min;
448  uint32_t buffer_min = DLT_USER_RINGBUFFER_MIN_SIZE;
449  char *env_buffer_max;
450  uint32_t buffer_max = DLT_USER_RINGBUFFER_MAX_SIZE;
451  char *env_buffer_step;
452  uint32_t buffer_step = DLT_USER_RINGBUFFER_STEP_SIZE;
453 
454  /* Binary semaphore for threads */
455  if (sem_init(&dlt_mutex, 0, 1)==-1)
456  {
457  dlt_user_initialised = false;
458  return DLT_RETURN_ERROR;
459  }
460 
461  /* set to unknown state of connected client */
462  dlt_user.log_state = -1;
463 
464  dlt_user.dlt_log_handle=-1;
465  dlt_user.dlt_user_handle=DLT_FD_INIT;
466 
468  dlt_set_id(dlt_user.appID,"");
469 
470  dlt_user.application_description = NULL;
471 
472  /* Verbose mode is enabled by default */
473  dlt_user.verbose_mode = 1;
474 
475  /* Use extended header for non verbose is enabled by default */
477 
478  /* WIth session id is enabled by default */
480 
481  /* With timestamp is enabled by default */
483 
484  /* With timestamp is enabled by default */
486 
487  /* Local print is disabled by default */
488  dlt_user.enable_local_print = 0;
489 
490  dlt_user.local_print_mode = DLT_PM_UNSET;
491 
493 
494  env_local_print = getenv(DLT_USER_ENV_LOCAL_PRINT_MODE);
495  if (env_local_print)
496  {
497  if (strcmp(env_local_print,"AUTOMATIC")==0)
498  {
500  }
501  else if (strcmp(env_local_print,"FORCE_ON")==0)
502  {
504  }
505  else if (strcmp(env_local_print,"FORCE_OFF")==0)
506  {
508  }
509  }
510 
511  env_initial_log_level = getenv("DLT_INITIAL_LOG_LEVEL");
512  if( env_initial_log_level != NULL )
513  {
514  if (dlt_env_extract_ll_set(&env_initial_log_level, &dlt_user.initial_ll_set) != 0)
515  {
516  snprintf(str, DLT_USER_BUFFER_LENGTH, "Unable to parse initial set of log-levels from environment! Env:\n%s\n", getenv("DLT_INITIAL_LOG_LEVEL"));
517  dlt_log(LOG_WARNING, str);
518  }
519  }
520 
521  /* Initialize LogLevel/TraceStatus field */
522  DLT_SEM_LOCK();
523  dlt_user.dlt_ll_ts = NULL;
524  dlt_user.dlt_ll_ts_max_num_entries = 0;
525  dlt_user.dlt_ll_ts_num_entries = 0;
526 
527 
528  env_buffer_min = getenv(DLT_USER_ENV_BUFFER_MIN_SIZE);
529  env_buffer_max = getenv(DLT_USER_ENV_BUFFER_MAX_SIZE);
530  env_buffer_step = getenv(DLT_USER_ENV_BUFFER_STEP_SIZE);
531 
532  if (env_buffer_min != NULL)
533  {
534  buffer_min = (uint32_t) strtol(env_buffer_min, NULL, 10);
535  if (errno == EINVAL || errno == ERANGE)
536  {
537  dlt_vlog(LOG_ERR,
538  "Wrong value specified for %s. Using default\n",
540  buffer_min = DLT_USER_RINGBUFFER_MIN_SIZE;
541  }
542  }
543 
544  if (env_buffer_max != NULL)
545  {
546  buffer_max = (uint32_t) strtol(env_buffer_max, NULL, 10);
547  if (errno == EINVAL || errno == ERANGE)
548  {
549  dlt_vlog(LOG_ERR,
550  "Wrong value specified for %s. Using default\n",
552  buffer_max = DLT_USER_RINGBUFFER_MAX_SIZE;
553  }
554  }
555 
556  if (env_buffer_step != NULL)
557  {
558  buffer_step = (uint32_t) strtol(env_buffer_step, NULL, 10);
559  if (errno == EINVAL || errno == ERANGE)
560  {
561  dlt_vlog(LOG_ERR,
562  "Wrong value specified for %s. Using default\n",
564  buffer_step = DLT_USER_RINGBUFFER_STEP_SIZE;
565  }
566  }
567 
568  if (dlt_buffer_init_dynamic(&(dlt_user.startup_buffer),
569  buffer_min,
570  buffer_max,
571  buffer_step) == DLT_RETURN_ERROR)
572  {
573  dlt_user_initialised = false;
574  DLT_SEM_FREE();
575  return DLT_RETURN_ERROR;
576  }
577  DLT_SEM_FREE();
578 
579  signal(SIGPIPE,SIG_IGN); /* ignore pipe signals */
580 
581  if (atexit_registered == 0)
582  {
583  atexit_registered = 1;
584  atexit(dlt_user_atexit_handler);
585  }
586 
587 #ifdef DLT_TEST_ENABLE
588  dlt_user.corrupt_user_header = 0;
589  dlt_user.corrupt_message_size = 0;
590  dlt_user.corrupt_message_size_size = 0;
591 #endif
592 
593  return DLT_RETURN_OK;
594 }
595 
597 {
599  {
600  dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__);
601  // close file
602  dlt_log_free();
603  return;
604  }
605 
606  /* Try to resend potential log messages in the user buffer */
608 
609  if(count != 0)
610  dlt_vnlog(LOG_WARNING, 128, "Lost log messages in user buffer when exiting: %i\n", count);
611 
612  /* Unregister app (this also unregisters all contexts in daemon) */
613  /* Ignore return value */
615 
616  /* Cleanup */
617  /* Ignore return value */
618  dlt_free();
619 }
620 
622 
623  int count,ret;
624 
625  uint32_t exitTime = dlt_uptime() + dlt_user.timeout_at_exit_handler;
626 
627  /* Send content of ringbuffer */
628  DLT_SEM_LOCK();
629  count = dlt_buffer_get_message_count(&(dlt_user.startup_buffer));
630  DLT_SEM_FREE();
631 
632  if (count > 0)
633  {
634  while(dlt_uptime() < exitTime )
635  {
636  if (dlt_user.dlt_log_handle == -1)
637  {
638  /* Reattach to daemon if neccesary */
640 
641  if ((dlt_user.dlt_log_handle != -1) && (dlt_user.overflow_counter))
642  {
644  {
645  dlt_vnlog(LOG_WARNING, DLT_USER_BUFFER_LENGTH, "%u messages discarded!\n", dlt_user.overflow_counter);
646  dlt_user.overflow_counter=0;
647  }
648  }
649  }
650 
651  if (dlt_user.dlt_log_handle != -1)
652  {
654 
655  if(ret == 0)
656  {
657  DLT_SEM_LOCK();
658  count = dlt_buffer_get_message_count(&(dlt_user.startup_buffer));
659  DLT_SEM_FREE();
660 
661  return count;
662  }
663  }
664 
666  }
667 
668  DLT_SEM_LOCK();
669  count = dlt_buffer_get_message_count(&(dlt_user.startup_buffer));
670  DLT_SEM_FREE();
671  }
672 
673  return count;
674 }
675 
677 {
678  uint32_t i;
679  char filename[DLT_USER_MAX_FILENAME_LENGTH];
680 
681  if( dlt_user_freeing != 0 )
682  // resources are already being freed. Do nothing and return.
683  return DLT_RETURN_ERROR;
684 
685  // library is freeing its resources. Avoid to allocate it in dlt_init()
686  dlt_user_freeing = 1;
687 
689  {
690  dlt_user_freeing = 0;
691  return DLT_RETURN_ERROR;
692  }
693  dlt_user_initialised = false;
694 
696 
697  if (dlt_user.dlt_user_handle!=DLT_FD_INIT)
698  {
699  snprintf(filename,DLT_USER_MAX_FILENAME_LENGTH,"%s/dlt%d",dlt_user_dir,getpid());
700 
701  close(dlt_user.dlt_user_handle);
702  dlt_user.dlt_user_handle=DLT_FD_INIT;
703 
704  unlink(filename);
705  }
706 
707 #ifdef DLT_SHM_ENABLE
708  /* free shared memory */
709  dlt_shm_free_client(&dlt_user.dlt_shm);
710 #endif
711 
712  if (dlt_user.dlt_log_handle!=-1)
713  {
714  /* close log file/output fifo to daemon */
715  close(dlt_user.dlt_log_handle);
716  dlt_user.dlt_log_handle = -1;
717  }
718 
719  /* Ignore return value */
720  DLT_SEM_LOCK();
721  dlt_receiver_free(&(dlt_user.receiver));
722  DLT_SEM_FREE();
723 
724  /* Ignore return value */
725  DLT_SEM_LOCK();
727  DLT_SEM_FREE();
728 
729  DLT_SEM_LOCK();
730  if (dlt_user.dlt_ll_ts)
731  {
732  for (i=0;i<dlt_user.dlt_ll_ts_max_num_entries;i++)
733  {
734  if( dlt_user.dlt_ll_ts[i].context_description != NULL)
735  {
736  free (dlt_user.dlt_ll_ts[i].context_description);
737  dlt_user.dlt_ll_ts[i].context_description = NULL;
738  }
739 
740  if (dlt_user.dlt_ll_ts[i].log_level_ptr != NULL)
741  {
742  free(dlt_user.dlt_ll_ts[i].log_level_ptr);
743  dlt_user.dlt_ll_ts[i].log_level_ptr = NULL;
744  }
745 
746  if (dlt_user.dlt_ll_ts[i].trace_status_ptr != NULL)
747  {
748  free(dlt_user.dlt_ll_ts[i].trace_status_ptr);
749  dlt_user.dlt_ll_ts[i].trace_status_ptr = NULL;
750  }
751 
752  if (dlt_user.dlt_ll_ts[i].injection_table != NULL)
753  {
754  free(dlt_user.dlt_ll_ts[i].injection_table);
755  dlt_user.dlt_ll_ts[i].injection_table = NULL;
756  }
757  dlt_user.dlt_ll_ts[i].nrcallbacks = 0;
758  dlt_user.dlt_ll_ts[i].log_level_changed_callback = 0;
759  }
760 
761  free(dlt_user.dlt_ll_ts);
762  dlt_user.dlt_ll_ts = NULL;
763  dlt_user.dlt_ll_ts_max_num_entries = 0;
764  dlt_user.dlt_ll_ts_num_entries = 0;
765  }
766 
768  DLT_SEM_FREE();
769 
770  char queue_name[NAME_MAX];
771  snprintf(queue_name,NAME_MAX, "%s.%d", DLT_MESSAGE_QUEUE_NAME, getpid());
772 
777  mq_close(dlt_user.dlt_segmented_queue_write_handle);
778  mq_close(dlt_user.dlt_segmented_queue_read_handle);
779  dlt_user.dlt_segmented_queue_write_handle = -1;
780  dlt_user.dlt_segmented_queue_read_handle = -1;
781  mq_unlink(queue_name);
782 
783  pthread_cond_destroy(&mq_init_condition);
784  pthread_mutex_destroy(&mq_mutex);
785  sem_destroy(&dlt_mutex);
786 
787  // allow the user app to do dlt_init() again.
788  // The flag is unset only to keep almost the same behaviour as before, on EntryNav
789  // This should be removed for other projects (see documentation of dlt_free()
790  dlt_user_freeing = 0;
791 
792  return DLT_RETURN_OK;
793 }
794 
795 DltReturnValue dlt_check_library_version(const char * user_major_version,const char * user_minor_version)
796 {
797  return dlt_user_check_library_version(user_major_version, user_minor_version);
798 }
799 
800 DltReturnValue dlt_register_app(const char *appid, const char * description)
801 {
803 
805  {
806  if (dlt_init() < 0)
807  {
808  dlt_vlog(LOG_ERR, "%s Failed to initialise dlt", __FUNCTION__);
809  return DLT_RETURN_ERROR;
810  }
811  }
812 
813  if ((appid == NULL) || (appid[0] == '\0'))
815 
816  /* check if application already registered */
817  /* if yes do not register again */
818  if (appid[1] == 0)
819  {
820  if (appid[0] == dlt_user.appID[0])
821  return DLT_RETURN_OK;
822  }
823  else if (appid[2] == 0)
824  {
825  if (appid[0] == dlt_user.appID[0] &&
826  appid[1] == dlt_user.appID[1])
827  return DLT_RETURN_OK;
828  }
829  else if (appid[3] == 0)
830  {
831  if (appid[0] == dlt_user.appID[0] &&
832  appid[1] == dlt_user.appID[1] &&
833  appid[2] == dlt_user.appID[2])
834  return DLT_RETURN_OK;
835  }
836  else
837  {
838  if (appid[0] == dlt_user.appID[0] &&
839  appid[1] == dlt_user.appID[1] &&
840  appid[2] == dlt_user.appID[2] &&
841  appid[3] == dlt_user.appID[3])
842  return DLT_RETURN_OK;
843  }
844 
845  DLT_SEM_LOCK();
846 
847  /* Store locally application id and application description */
848  dlt_set_id(dlt_user.appID, appid);
849 
850  if (dlt_user.application_description != NULL)
851  free(dlt_user.application_description);
852 
853  dlt_user.application_description = NULL;
854 
855  if (description != NULL)
856  {
857  size_t desc_len = strlen(description);
858  dlt_user.application_description = malloc(desc_len + 1);
859  if (dlt_user.application_description)
860  {
861  strncpy(dlt_user.application_description, description, desc_len);
862  dlt_user.application_description[desc_len] = '\0';
863  }
864  else
865  {
866  DLT_SEM_FREE();
867  return DLT_RETURN_ERROR;
868  }
869  }
870 
871  DLT_SEM_FREE();
872 
874 
875  if (( ret == DLT_RETURN_OK ) && (dlt_user.dlt_log_handle!=-1))
876  {
878  }
879 
880  return ret;
881 }
882 
883 DltReturnValue dlt_register_context(DltContext *handle, const char *contextid, const char * description)
884 {
885  // check nullpointer
886  if(handle == NULL)
888 
890  {
891  if (dlt_init() < 0)
892  {
893  dlt_vlog(LOG_ERR, "%s Failed to initialise dlt", __FUNCTION__);
894  return DLT_RETURN_ERROR;
895  }
896  }
897 
898  DLT_SEM_LOCK();
899 
900  if ((contextid == NULL) || (contextid[0] == '\0'))
901  {
902  DLT_SEM_FREE();
904  }
905 
906  DLT_SEM_FREE();
907 
909 }
910 
911 DltReturnValue dlt_register_context_ll_ts(DltContext *handle, const char *contextid, const char * description, int loglevel, int tracestatus)
912 {
913  DltContextData log;
914  uint32_t i;
915  int envLogLevel = DLT_USER_LOG_LEVEL_NOT_SET;
916 
917  //check nullpointer
918  if(!handle)
920 
921  if ((contextid == NULL) || (contextid[0]=='\0'))
922  {
924  }
925 
926  if (loglevel < DLT_USER_LOG_LEVEL_NOT_SET || loglevel >= DLT_LOG_MAX)
927  {
928  dlt_vlog(LOG_ERR, "Loglevel %d is outside valid range", loglevel);
930  }
931 
932  if (tracestatus < DLT_USER_TRACE_STATUS_NOT_SET || tracestatus >= DLT_TRACE_STATUS_MAX)
933  {
934  dlt_vlog(LOG_ERR, "Tracestatus %d is outside valid range", tracestatus);
936  }
937 
938 
939  if (dlt_user_log_init(handle, &log)==-1)
940  {
941  return DLT_RETURN_ERROR;
942  }
943 
944  /* Reset message counter */
945  handle->mcnt = 0;
946 
947  /* Store context id in log level/trace status field */
948 
949  /* Check if already registered, else register context */
950  DLT_SEM_LOCK();
951 
952  /* Check of double context registration removed */
953  /* Double registration is already checked by daemon */
954 
955  /* Allocate or expand context array */
956  if (dlt_user.dlt_ll_ts == 0)
957  {
959  if (dlt_user.dlt_ll_ts==0)
960  {
961  DLT_SEM_FREE();
962  return DLT_RETURN_ERROR;
963  }
964 
966 
967  /* Initialize new entries */
968  for (i=0;i<dlt_user.dlt_ll_ts_max_num_entries;i++)
969  {
970  dlt_set_id(dlt_user.dlt_ll_ts[i].contextID,"");
971 
972  /* At startup, logging and tracing is locally enabled */
973  /* the correct log level/status is set after received from daemon */
976 
977  dlt_user.dlt_ll_ts[i].log_level_ptr = 0;
978  dlt_user.dlt_ll_ts[i].trace_status_ptr = 0;
979 
980  dlt_user.dlt_ll_ts[i].context_description = 0;
981 
982  dlt_user.dlt_ll_ts[i].injection_table = 0;
983  dlt_user.dlt_ll_ts[i].nrcallbacks = 0;
984  dlt_user.dlt_ll_ts[i].log_level_changed_callback = 0;
985 
986  }
987  }
988  else
989  {
991  {
992  /* allocate memory in steps of DLT_USER_CONTEXT_ALLOC_SIZE, e.g. 500 */
993  dlt_ll_ts_type *old_ll_ts;
994  uint32_t old_max_entries;
995 
996  old_ll_ts = dlt_user.dlt_ll_ts;
997  old_max_entries = dlt_user.dlt_ll_ts_max_num_entries;
998 
1000  dlt_user.dlt_ll_ts = (dlt_ll_ts_type*) malloc(sizeof(dlt_ll_ts_type)*
1001  dlt_user.dlt_ll_ts_max_num_entries);
1002  if (dlt_user.dlt_ll_ts==0)
1003  {
1004  dlt_user.dlt_ll_ts = old_ll_ts;
1005  dlt_user.dlt_ll_ts_max_num_entries = old_max_entries;
1006  DLT_SEM_FREE();
1007  return DLT_RETURN_ERROR;
1008  }
1009 
1010  memcpy(dlt_user.dlt_ll_ts,old_ll_ts,sizeof(dlt_ll_ts_type)*dlt_user.dlt_ll_ts_num_entries);
1011  free(old_ll_ts);
1012 
1013  /* Initialize new entries */
1014  for (i=dlt_user.dlt_ll_ts_num_entries;i<dlt_user.dlt_ll_ts_max_num_entries;i++)
1015  {
1016  dlt_set_id(dlt_user.dlt_ll_ts[i].contextID,"");
1017 
1018  /* At startup, logging and tracing is locally enabled */
1019  /* the correct log level/status is set after received from daemon */
1022 
1023  dlt_user.dlt_ll_ts[i].log_level_ptr = 0;
1024  dlt_user.dlt_ll_ts[i].trace_status_ptr = 0;
1025 
1026  dlt_user.dlt_ll_ts[i].context_description = 0;
1027 
1028  dlt_user.dlt_ll_ts[i].injection_table = 0;
1029  dlt_user.dlt_ll_ts[i].nrcallbacks = 0;
1030  dlt_user.dlt_ll_ts[i].log_level_changed_callback = 0;
1031  }
1032  }
1033  }
1034 
1035  /* Store locally context id and context description */
1036  dlt_set_id(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].contextID, contextid);
1037 
1038  if (dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description!=0)
1039  {
1040  free(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description);
1041  }
1042 
1043  dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description = 0;
1044 
1045  if (description!=0)
1046  {
1047  size_t desc_len = strlen(description);
1048  dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description = malloc(desc_len+1);
1049  if(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description == 0)
1050  {
1051  DLT_SEM_FREE();
1052  return DLT_RETURN_ERROR;
1053  }
1054 
1055  strncpy(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description, description, desc_len);
1056  dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description[desc_len]='\0';
1057  }
1058 
1059  if(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].log_level_ptr == 0)
1060  {
1061  dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].log_level_ptr = malloc(sizeof(int8_t));
1062  if(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].log_level_ptr == 0)
1063  {
1064  DLT_SEM_FREE();
1065  return DLT_RETURN_ERROR;
1066  }
1067  }
1068  if(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].trace_status_ptr == 0)
1069  {
1070  dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].trace_status_ptr = malloc(sizeof(int8_t));
1071  if(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].trace_status_ptr == 0)
1072  {
1073  DLT_SEM_FREE();
1074  return DLT_RETURN_ERROR;
1075  }
1076  }
1077 
1078  /* check if the log level is set in the environement */
1079  envLogLevel = dlt_env_adjust_ll_from_env(&dlt_user.initial_ll_set, dlt_user.appID, contextid, DLT_USER_LOG_LEVEL_NOT_SET);
1080  if( envLogLevel!=DLT_USER_LOG_LEVEL_NOT_SET)
1081  {
1082  dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].log_level = envLogLevel;
1083  loglevel = envLogLevel;
1084  }
1085  else if( loglevel != DLT_USER_LOG_LEVEL_NOT_SET )
1086  {
1087  dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].log_level = loglevel;
1088  }
1089 
1090  if (tracestatus!=DLT_USER_TRACE_STATUS_NOT_SET)
1091  {
1092  dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].trace_status = tracestatus;
1093  }
1094 
1095  /* Prepare transfer struct */
1096  //dlt_set_id(log->appID, dlt_user.appID);
1097  dlt_set_id(handle->contextID, contextid);
1098  handle->log_level_pos = dlt_user.dlt_ll_ts_num_entries;
1099 
1100  handle->log_level_ptr = dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].log_level_ptr;
1102 
1104 
1105  *(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].log_level_ptr) = dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].log_level;
1106  *(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].trace_status_ptr) = dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].trace_status = tracestatus;
1107 
1108  log.log_level = loglevel;
1109  log.trace_status = tracestatus;
1110 
1111  dlt_user.dlt_ll_ts_num_entries++;
1112 
1113  DLT_SEM_FREE();
1114 
1116 }
1117 
1119 {
1121 
1122  if (!dlt_user_initialised)
1123  {
1124  dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__);
1125  return DLT_RETURN_ERROR;
1126  }
1127 
1128  /* Inform daemon to unregister application and all of its contexts */
1130 
1131  DLT_SEM_LOCK();
1132 
1133  /* Clear and free local stored application information */
1134  dlt_set_id(dlt_user.appID, "");
1135 
1136  if (dlt_user.application_description != NULL)
1137  {
1138  free(dlt_user.application_description);
1139  }
1140 
1141  dlt_user.application_description = NULL;
1142 
1143  DLT_SEM_FREE();
1144 
1145  return ret;
1146 }
1147 
1149 {
1150  DltContextData log;
1152 
1153  log.handle = NULL;
1154  log.context_description = NULL;
1155  if (dlt_user_log_init(handle, &log) <= DLT_RETURN_ERROR)
1156  return DLT_RETURN_ERROR;
1157 
1158  DLT_SEM_LOCK();
1159 
1160  handle->log_level_ptr = NULL;
1161  handle->trace_status_ptr = NULL;
1162 
1163  if (dlt_user.dlt_ll_ts != NULL)
1164  {
1165  /* Clear and free local stored context information */
1166  dlt_set_id(dlt_user.dlt_ll_ts[handle->log_level_pos].contextID, "");
1167 
1170 
1171  if (dlt_user.dlt_ll_ts[handle->log_level_pos].context_description != NULL)
1172  {
1173  free(dlt_user.dlt_ll_ts[handle->log_level_pos].context_description);
1174  }
1175 
1176  if (dlt_user.dlt_ll_ts[handle->log_level_pos].log_level_ptr != NULL)
1177  {
1178  free(dlt_user.dlt_ll_ts[handle->log_level_pos].log_level_ptr);
1179  dlt_user.dlt_ll_ts[handle->log_level_pos].log_level_ptr = NULL;
1180  }
1181 
1182  if (dlt_user.dlt_ll_ts[handle->log_level_pos].trace_status_ptr != NULL)
1183  {
1184  free(dlt_user.dlt_ll_ts[handle->log_level_pos].trace_status_ptr);
1185  dlt_user.dlt_ll_ts[handle->log_level_pos].trace_status_ptr = NULL;
1186  }
1187 
1188  dlt_user.dlt_ll_ts[handle->log_level_pos].context_description = NULL;
1189 
1190  if (dlt_user.dlt_ll_ts[handle->log_level_pos].injection_table != NULL)
1191  {
1192  free(dlt_user.dlt_ll_ts[handle->log_level_pos].injection_table);
1193  dlt_user.dlt_ll_ts[handle->log_level_pos].injection_table = NULL;
1194  }
1195 
1196  dlt_user.dlt_ll_ts[handle->log_level_pos].nrcallbacks = 0;
1197  dlt_user.dlt_ll_ts[handle->log_level_pos].log_level_changed_callback = 0;
1198  }
1199 
1200  DLT_SEM_FREE();
1201 
1202  /* Inform daemon to unregister context */
1204 
1205  return ret;
1206 }
1207 
1209 {
1210  uint32_t i;
1211 
1212  if (loglevel < DLT_USER_LOG_LEVEL_NOT_SET || loglevel >= DLT_LOG_MAX)
1213  {
1214  dlt_vlog(LOG_ERR, "Loglevel %d is outside valid range", loglevel);
1216  }
1217 
1218  if (tracestatus < DLT_USER_TRACE_STATUS_NOT_SET || tracestatus >= DLT_TRACE_STATUS_MAX)
1219  {
1220  dlt_vlog(LOG_ERR, "Tracestatus %d is outside valid range", tracestatus);
1222  }
1223 
1224  if (!dlt_user_initialised)
1225  {
1226  if (dlt_init() < 0)
1227  {
1228  dlt_vlog(LOG_ERR, "%s Failed to initialise dlt", __FUNCTION__);
1229  return DLT_RETURN_ERROR;
1230  }
1231  }
1232 
1233  /* Removed because of DltLogLevelType and DltTraceStatusType
1234 
1235  if ((loglevel<DLT_LOG_DEFAULT) || (loglevel>DLT_LOG_VERBOSE))
1236  {
1237  return DLT_RETURN_ERROR;
1238  }
1239 
1240  if ((tracestatus<DLT_TRACE_STATUS_DEFAULT) || (tracestatus>DLT_TRACE_STATUS_ON))
1241  {
1242  return DLT_RETURN_ERROR;
1243  }
1244 
1245  if (dlt_user.dlt_ll_ts==0)
1246  {
1247  return DLT_RETURN_ERROR;
1248  }
1249 
1250  */
1251 
1252  DLT_SEM_LOCK();
1253  if (dlt_user.dlt_ll_ts == NULL)
1254  {
1255  DLT_SEM_FREE();
1256  return DLT_RETURN_ERROR;
1257  }
1258 
1259  /* Update local structures */
1260  for (i=0; i<dlt_user.dlt_ll_ts_num_entries;i++)
1261  {
1262  dlt_user.dlt_ll_ts[i].log_level = loglevel;
1263  dlt_user.dlt_ll_ts[i].trace_status = tracestatus;
1264  if(dlt_user.dlt_ll_ts[i].log_level_ptr)
1265  *(dlt_user.dlt_ll_ts[i].log_level_ptr) = loglevel;
1266  if(dlt_user.dlt_ll_ts[i].trace_status_ptr)
1267  *(dlt_user.dlt_ll_ts[i].trace_status_ptr) = tracestatus;
1268  }
1269 
1270  DLT_SEM_FREE();
1271 
1272  /* Inform DLT server about update */
1273  return dlt_send_app_ll_ts_limit(dlt_user.appID, loglevel, tracestatus);
1274 }
1275 
1277 {
1278  return dlt_user.log_state;
1279 }
1280 
1282 {
1283  if (mode < DLT_USER_MODE_UNDEFINED || mode >= DLT_USER_MODE_MAX)
1284  {
1285  dlt_vlog(LOG_ERR, "User log mode %d is outside valid range", mode);
1287  }
1288 
1289  if (!dlt_user_initialised)
1290  {
1291  if (dlt_init() < 0)
1292  {
1293  dlt_vlog(LOG_ERR, "%s Failed to initialise dlt", __FUNCTION__);
1294  return DLT_RETURN_ERROR;
1295  }
1296  }
1297 
1298  return dlt_user_log_send_log_mode(mode);
1299 }
1300 
1301 int dlt_set_resend_timeout_atexit(uint32_t timeout_in_milliseconds)
1302 {
1303  if (dlt_user_initialised==0)
1304  {
1305  if (dlt_init()<0)
1306  {
1307  return -1;
1308  }
1309  }
1310  dlt_user.timeout_at_exit_handler = timeout_in_milliseconds * 10;
1311  return 0;
1312 }
1313 
1314 
1315 DltReturnValue dlt_forward_msg(void *msgdata,size_t size)
1316 {
1317  DltUserHeader userheader;
1318  DltReturnValue ret;
1319 
1320  if ((msgdata == NULL) || (size == 0))
1321  {
1323  }
1324 
1326  {
1327  /* Type of internal user message; same value for Trace messages */
1328  return DLT_RETURN_ERROR;
1329  }
1330 
1331  if (dlt_user.dlt_is_file)
1332  {
1333  /* log to file */
1334  return dlt_user_log_out2(dlt_user.dlt_log_handle, msgdata, size, 0, 0);
1335  }
1336  else
1337  {
1338  /* Reattach to daemon if neccesary */
1340 
1341  if (dlt_user.overflow_counter)
1342  {
1343  if (dlt_user_log_send_overflow()==0)
1344  {
1345  dlt_vnlog(LOG_WARNING, DLT_USER_BUFFER_LENGTH, "Buffer full! %u messages discarded!\n", dlt_user.overflow_counter);
1346  dlt_user.overflow_counter=0;
1347  }
1348  }
1349 
1350  /* log to FIFO */
1351  ret = dlt_user_log_out3(dlt_user.dlt_log_handle,
1352  &(userheader), sizeof(DltUserHeader),
1353  msgdata, size, 0, 0);
1354 
1355  /* store message in ringbuffer, if an error has occured */
1356  if (ret < DLT_RETURN_OK)
1357  {
1358  DLT_SEM_LOCK();
1359 
1360  if (dlt_buffer_push3(&(dlt_user.startup_buffer),
1361  (unsigned char *)&(userheader), sizeof(DltUserHeader),
1362  msgdata, size, 0, 0) == DLT_RETURN_ERROR)
1363  {
1364  if(dlt_user.overflow_counter==0)
1365  {
1366  dlt_log(LOG_WARNING,"Buffer full! First message discarded!\n");
1367  }
1368 
1369  ret = DLT_RETURN_BUFFER_FULL;
1370  }
1371 
1372  DLT_SEM_FREE();
1373 
1374  if(dlt_user_queue_resend() < DLT_RETURN_OK && dlt_user.dlt_log_handle >= 0)
1375  {
1376  ;//dlt_log(LOG_WARNING, "dlt_forward_msg: Failed to queue resending.\n");
1377  }
1378  }
1379 
1380  switch (ret)
1381  {
1383  {
1384  /* wrong parameters */
1386  }
1388  {
1389  /* Buffer full */
1390  dlt_user.overflow_counter += 1;
1391  return DLT_RETURN_ERROR;
1392  }
1393  case DLT_RETURN_PIPE_FULL:
1394  {
1395  /* data could not be written */
1396  return DLT_RETURN_ERROR;
1397  }
1398  case DLT_RETURN_PIPE_ERROR:
1399  {
1400  /* handle not open or pipe error */
1401  close(dlt_user.dlt_log_handle);
1402  dlt_user.dlt_log_handle = -1;
1403 
1404  return DLT_RETURN_ERROR;
1405  }
1406  case DLT_RETURN_ERROR:
1407  {
1408  /* other error condition */
1409  return DLT_RETURN_ERROR;
1410  }
1411  case DLT_RETURN_OK:
1412  {
1413  return DLT_RETURN_OK;
1414  }
1415  default:
1416  {
1417  /* This case should not occur */
1418  return DLT_RETURN_ERROR;
1419  }
1420  }
1421  }
1422 
1423  return DLT_RETURN_OK;
1424 }
1425 
1426 /* ********************************************************************************************* */
1427 
1429 {
1430  return dlt_user_log_write_start_id(handle,log,loglevel,DLT_USER_DEFAULT_MSGID);
1431 }
1432 
1434 {
1435  DLT_LOG_FATAL_RESET_TRAP(loglevel);
1436 
1437  // check nullpointer
1438  if (handle == NULL || log == NULL)
1440 
1441  if (loglevel < DLT_USER_LOG_LEVEL_NOT_SET || loglevel >= DLT_LOG_MAX)
1442  {
1443  dlt_vlog(LOG_ERR, "Loglevel %d is outside valid range", loglevel);
1445  }
1446 
1447  if (dlt_user_log_init(handle, log) < DLT_RETURN_OK || dlt_user.dlt_ll_ts == NULL)
1448  return DLT_RETURN_ERROR;
1449 
1450  /* initialize values */
1451  log->args_num = 0;
1452  log->log_level = loglevel;
1453  log->size = 0;
1454 
1455  /* check log levels */
1456  if (dlt_user_is_logLevel_enabled(handle, loglevel) == DLT_RETURN_TRUE)
1457  {
1458  /* In non-verbose mode, insert message id */
1459  if (dlt_user.verbose_mode == 0)
1460  {
1461  if ((sizeof(uint32_t)) > DLT_USER_BUF_MAX_SIZE)
1463 
1464  /* Write message id */
1465  memcpy(log->buffer, &(messageid), sizeof(uint32_t));
1466  log->size = sizeof(uint32_t);
1467 
1468  /* as the message id is part of each message in non-verbose mode,
1469  it doesn't increment the argument counter in extended header (if used) */
1470  }
1471 
1472  return DLT_RETURN_TRUE;
1473  }
1474  else
1475  {
1476  return DLT_RETURN_OK;
1477  }
1478 
1479  return DLT_RETURN_ERROR;
1480 }
1481 
1483 {
1484  if (log == NULL)
1486 
1487  return dlt_user_log_send_log(log, DLT_TYPE_LOG);
1488 }
1489 
1491 {
1492  return dlt_user_log_write_raw_formatted(log, data, length, DLT_FORMAT_DEFAULT);
1493 }
1494 
1496 {
1497  size_t new_log_size = 0;
1498  uint32_t type_info = 0;
1499 
1500  // check nullpointer
1501  if (log == NULL || (data == NULL && length!=0))
1503 
1504  // Have to cast type to signed type because some compilers assume that DltFormatType is unsigned and issue a warning
1505  if ((int16_t)type < DLT_FORMAT_DEFAULT || type >= DLT_FORMAT_MAX)
1506  {
1507  dlt_vlog(LOG_ERR, "Format type %d is outside valid range", type);
1509  }
1510 
1511  if (!dlt_user_initialised)
1512  {
1513  dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__);
1514  return DLT_RETURN_ERROR;
1515  }
1516 
1517  new_log_size = log->size + length + sizeof(uint16_t);
1518 
1519  if (new_log_size > DLT_USER_BUF_MAX_SIZE)
1521 
1522  if (dlt_user.verbose_mode)
1523  {
1524  new_log_size = log->size + length + sizeof(uint32_t) + sizeof(uint16_t);
1525 
1526  if (new_log_size > DLT_USER_BUF_MAX_SIZE)
1528 
1529  /* Transmit type information */
1530  type_info = DLT_TYPE_INFO_RAWD;
1531 
1532  if (type >= DLT_FORMAT_HEX8 && type <= DLT_FORMAT_HEX64)
1533  {
1534  type_info |= DLT_SCOD_HEX;
1535  type_info += type;
1536  }
1537  else if (type >= DLT_FORMAT_BIN8 && type <= DLT_FORMAT_BIN16)
1538  {
1539  type_info |= DLT_SCOD_BIN;
1540  type_info += type - DLT_FORMAT_BIN8 + 1;
1541  }
1542 
1543  memcpy((log->buffer) + log->size, &(type_info), sizeof(uint32_t));
1544  log->size += sizeof(uint32_t);
1545  }
1546 
1547  /* First transmit length of raw data, then the raw data itself */
1548  memcpy((log->buffer) + log->size, &(length), sizeof(uint16_t));
1549  log->size += sizeof(uint16_t);
1550 
1551  memcpy((log->buffer) + log->size, data, length);
1552  log->size += length;
1553 
1554  log->args_num++;
1555 
1556  return DLT_RETURN_OK;
1557 }
1558 
1560 {
1561  uint32_t type_info;
1562 
1563  if (log == NULL)
1565 
1566  if (!dlt_user_initialised)
1567  {
1568  dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__);
1569  return DLT_RETURN_ERROR;
1570  }
1571 
1572  if (sizeof(float32_t)!=4)
1573  {
1574  return DLT_RETURN_ERROR;
1575  }
1576 
1577  if ((log->size+sizeof(float32_t))>DLT_USER_BUF_MAX_SIZE)
1579 
1580  if (dlt_user.verbose_mode)
1581  {
1582  if ((log->size+sizeof(uint32_t)+sizeof(float32_t))>DLT_USER_BUF_MAX_SIZE)
1584 
1585  type_info = DLT_TYPE_INFO_FLOA | DLT_TYLE_32BIT;
1586 
1587  memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1588  log->size += sizeof(uint32_t);
1589  }
1590 
1591  memcpy((log->buffer)+log->size,&data, sizeof(float32_t));
1592  log->size += sizeof(float32_t);
1593 
1594  log->args_num ++;
1595 
1596  return DLT_RETURN_OK;
1597 }
1598 
1600 {
1601  uint32_t type_info;
1602 
1603  if (log == NULL)
1605 
1606  if (!dlt_user_initialised)
1607  {
1608  dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__);
1609  return DLT_RETURN_ERROR;
1610  }
1611 
1612  if (sizeof(float64_t)!=8)
1613  {
1614  return DLT_RETURN_ERROR;
1615  }
1616 
1617  if ((log->size+sizeof(float64_t))>DLT_USER_BUF_MAX_SIZE)
1619 
1620  if (dlt_user.verbose_mode)
1621  {
1622  if ((log->size+sizeof(uint32_t)+sizeof(float64_t))>DLT_USER_BUF_MAX_SIZE)
1624 
1625  type_info = DLT_TYPE_INFO_FLOA | DLT_TYLE_64BIT;
1626 
1627  memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1628  log->size += sizeof(uint32_t);
1629  }
1630 
1631  memcpy((log->buffer)+log->size,&data, sizeof(float64_t));
1632  log->size += sizeof(float64_t);
1633 
1634  log->args_num ++;
1635 
1636  return DLT_RETURN_OK;
1637 }
1638 
1640 {
1641  if (log == NULL)
1643 
1644  if (!dlt_user_initialised)
1645  {
1646  dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__);
1647  return DLT_RETURN_ERROR;
1648  }
1649 
1650  switch (sizeof(unsigned int))
1651  {
1652  case 1:
1653  {
1654  return dlt_user_log_write_uint8(log, (uint8_t)data);
1655  break;
1656  }
1657  case 2:
1658  {
1659  return dlt_user_log_write_uint16(log, (uint16_t)data);
1660  break;
1661  }
1662  case 4:
1663  {
1664  return dlt_user_log_write_uint32(log, (uint32_t)data);
1665  break;
1666  }
1667  case 8:
1668  {
1669  return dlt_user_log_write_uint64(log, (uint64_t)data);
1670  break;
1671  }
1672  default:
1673  {
1674  return DLT_RETURN_ERROR;
1675  break;
1676  }
1677  }
1678 
1679  return DLT_RETURN_OK;
1680 }
1681 
1683 {
1684  uint32_t type_info;
1685 
1686  if (log == NULL)
1688 
1689  if (!dlt_user_initialised)
1690  {
1691  dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__);
1692  return DLT_RETURN_ERROR;
1693  }
1694 
1695  if ((log->size+sizeof(uint8_t))>DLT_USER_BUF_MAX_SIZE)
1697 
1698  if (dlt_user.verbose_mode)
1699  {
1700  if ((log->size+sizeof(uint32_t)+sizeof(uint8_t))>DLT_USER_BUF_MAX_SIZE)
1702 
1703  type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_8BIT;
1704 
1705  memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1706  log->size += sizeof(uint32_t);
1707  }
1708 
1709  memcpy((log->buffer)+log->size,&data,sizeof(uint8_t));
1710  log->size += sizeof(uint8_t);
1711 
1712  log->args_num ++;
1713 
1714  return DLT_RETURN_OK;
1715 }
1716 
1718 {
1719  uint32_t type_info;
1720 
1721  if (log == NULL)
1723 
1724  if (!dlt_user_initialised)
1725  {
1726  dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__);
1727  return DLT_RETURN_ERROR;
1728  }
1729 
1730  if ((log->size+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1732 
1733  if (dlt_user.verbose_mode)
1734  {
1735  if ((log->size+sizeof(uint32_t)+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1737 
1738  type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_16BIT;
1739 
1740  memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1741  log->size += sizeof(uint32_t);
1742  }
1743 
1744  memcpy((log->buffer)+log->size,&data,sizeof(uint16_t));
1745  log->size += sizeof(uint16_t);
1746 
1747  log->args_num ++;
1748 
1749  return DLT_RETURN_OK;
1750 }
1751 
1753 {
1754  uint32_t type_info;
1755 
1756  if (log == NULL)
1758 
1759  if (!dlt_user_initialised)
1760  {
1761  dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__);
1762  return DLT_RETURN_ERROR;
1763  }
1764 
1765  if ((log->size+sizeof(uint32_t))>DLT_USER_BUF_MAX_SIZE)
1767 
1768  if (dlt_user.verbose_mode)
1769  {
1770  if ((log->size+sizeof(uint32_t)+sizeof(uint32_t))>DLT_USER_BUF_MAX_SIZE)
1772 
1773  type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_32BIT;
1774 
1775  memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1776  log->size += sizeof(uint32_t);
1777  }
1778 
1779  memcpy((log->buffer)+log->size,&data, sizeof(uint32_t));
1780  log->size += sizeof(uint32_t);
1781 
1782  log->args_num ++;
1783 
1784  return DLT_RETURN_OK;
1785 }
1786 
1788 {
1789  uint32_t type_info;
1790 
1791  if (log == NULL)
1793 
1794  if (!dlt_user_initialised)
1795  {
1796  dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__);
1797  return DLT_RETURN_ERROR;
1798  }
1799 
1800  if ((log->size+sizeof(uint64_t))>DLT_USER_BUF_MAX_SIZE)
1802 
1803  if (dlt_user.verbose_mode)
1804  {
1805  if ((log->size+sizeof(uint32_t)+sizeof(uint64_t))>DLT_USER_BUF_MAX_SIZE)
1807 
1808  type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_64BIT;
1809 
1810  memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1811  log->size +=sizeof(uint32_t);
1812  }
1813 
1814  memcpy((log->buffer)+log->size,&data,sizeof(uint64_t));
1815  log->size += sizeof(uint64_t);
1816 
1817  log->args_num ++;
1818 
1819  return DLT_RETURN_OK;
1820 }
1821 
1823 {
1824  uint32_t type_info;
1825 
1826  if (log == NULL)
1828 
1829  // Have to cast type to signed type because some compilers assume that DltFormatType is unsigned and issue a warning
1830  if ((int16_t)type < DLT_FORMAT_DEFAULT || type >= DLT_FORMAT_MAX)
1831  {
1832  dlt_vlog(LOG_ERR, "Format type %d is outside valid range", type);
1834  }
1835 
1836  if (!dlt_user_initialised)
1837  {
1838  dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__);
1839  return DLT_RETURN_ERROR;
1840  }
1841 
1842  if ((log->size+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1844 
1845  if (dlt_user.verbose_mode)
1846  {
1847  if ((log->size+sizeof(uint32_t)+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1849 
1850  type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_8BIT;
1851 
1852  if(type>=DLT_FORMAT_HEX8 && type<=DLT_FORMAT_HEX64)
1853  {
1854  type_info |= DLT_SCOD_HEX;
1855  }
1856 
1857  else if(type>=DLT_FORMAT_BIN8 && type<=DLT_FORMAT_BIN16)
1858  {
1859  type_info |= DLT_SCOD_BIN;
1860  }
1861 
1862  memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1863  log->size += sizeof(uint32_t);
1864  }
1865 
1866  memcpy((log->buffer)+log->size,&data,sizeof(uint8_t));
1867  log->size += sizeof(uint8_t);
1868 
1869  log->args_num ++;
1870 
1871  return DLT_RETURN_OK;
1872 }
1873 
1875 {
1876  uint32_t type_info;
1877 
1878  if (log == NULL)
1880 
1881  // Have to cast type to signed type because some compilers assume that DltFormatType is unsigned and issue a warning
1882  if ((int16_t)type < DLT_FORMAT_DEFAULT || type >= DLT_FORMAT_MAX)
1883  {
1884  dlt_vlog(LOG_ERR, "Format type %d is outside valid range", type);
1886  }
1887 
1888  if (!dlt_user_initialised)
1889  {
1890  dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__);
1891  return DLT_RETURN_ERROR;
1892  }
1893 
1894  if ((log->size+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1896 
1897  if (dlt_user.verbose_mode)
1898  {
1899  if ((log->size+sizeof(uint32_t)+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1901 
1902  type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_16BIT;
1903 
1904  if(type>=DLT_FORMAT_HEX8 && type<=DLT_FORMAT_HEX64)
1905  {
1906  type_info |= DLT_SCOD_HEX;
1907  }
1908 
1909  else if(type>=DLT_FORMAT_BIN8 && type<=DLT_FORMAT_BIN16)
1910  {
1911  type_info |= DLT_SCOD_BIN;
1912  }
1913 
1914  memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1915  log->size += sizeof(uint32_t);
1916  }
1917 
1918  memcpy((log->buffer)+log->size,&data,sizeof(uint16_t));
1919  log->size += sizeof(uint16_t);
1920 
1921  log->args_num ++;
1922 
1923  return DLT_RETURN_OK;
1924 }
1925 
1927 {
1928  uint32_t type_info;
1929 
1930  if (log == NULL)
1932 
1933  // Have to cast type to signed type because some compilers assume that DltFormatType is unsigned and issue a warning
1934  if ((int16_t)type < DLT_FORMAT_DEFAULT || type >= DLT_FORMAT_MAX)
1935  {
1936  dlt_vlog(LOG_ERR, "Format type %d is outside valid range", type);
1938  }
1939 
1940  if (!dlt_user_initialised)
1941  {
1942  dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__);
1943  return DLT_RETURN_ERROR;
1944  }
1945 
1946  if ((log->size+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1948 
1949  if (dlt_user.verbose_mode)
1950  {
1951  if ((log->size+sizeof(uint32_t)+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1953 
1954  type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_32BIT;
1955 
1956  if(type>=DLT_FORMAT_HEX8 && type<=DLT_FORMAT_HEX64)
1957  {
1958  type_info |= DLT_SCOD_HEX;
1959  }
1960 
1961  else if(type>=DLT_FORMAT_BIN8 && type<=DLT_FORMAT_BIN16)
1962  {
1963  type_info |= DLT_SCOD_BIN;
1964  }
1965 
1966  memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1967  log->size += sizeof(uint32_t);
1968  }
1969 
1970  memcpy((log->buffer)+log->size,&data,sizeof(uint32_t));
1971  log->size += sizeof(uint32_t);
1972 
1973  log->args_num ++;
1974 
1975  return DLT_RETURN_OK;
1976 }
1977 
1979 {
1980  uint32_t type_info;
1981 
1982  if (log == NULL)
1984 
1985  // Have to cast type to signed type because some compilers assume that DltFormatType is unsigned and issue a warning
1986  if ((int16_t)type < DLT_FORMAT_DEFAULT || type >= DLT_FORMAT_MAX)
1987  {
1988  dlt_vlog(LOG_ERR, "Format type %d is outside valid range", type);
1990  }
1991 
1992  if (!dlt_user_initialised)
1993  {
1994  dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__);
1995  return DLT_RETURN_ERROR;
1996  }
1997 
1998  if ((log->size+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
2000 
2001  if (dlt_user.verbose_mode)
2002  {
2003  if ((log->size+sizeof(uint32_t)+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
2005 
2006  type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_64BIT;
2007 
2008  if(type>=DLT_FORMAT_HEX8 && type<=DLT_FORMAT_HEX64)
2009  {
2010  type_info |= DLT_SCOD_HEX;
2011  }
2012 
2013  else if(type>=DLT_FORMAT_BIN8 && type<=DLT_FORMAT_BIN16)
2014  {
2015  type_info |= DLT_SCOD_BIN;
2016  }
2017 
2018  memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
2019  log->size += sizeof(uint32_t);
2020  }
2021 
2022  memcpy((log->buffer)+log->size,&data,sizeof(uint64_t));
2023  log->size += sizeof(uint64_t);
2024 
2025  log->args_num ++;
2026 
2027  return DLT_RETURN_OK;
2028 }
2029 
2031 {
2032  if (log == NULL)
2033  {
2035  }
2036 
2037  if (!dlt_user_initialised)
2038  {
2039  dlt_vlog(LOG_WARNING, "%user_initialised false\n", __FUNCTION__);
2040  return DLT_RETURN_ERROR;
2041  }
2042 
2043  switch(sizeof(void *))
2044  {
2045  case 4:
2047  (uintptr_t)data,
2049  break;
2050  case 8:
2052  (uintptr_t)data,
2054  break;
2055  default:
2056  ; /* skip */
2057  }
2058 
2059  return DLT_RETURN_OK;
2060 }
2061 
2063 {
2064  if (log == NULL)
2066 
2067  if (!dlt_user_initialised)
2068  {
2069  dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__);
2070  return DLT_RETURN_ERROR;
2071  }
2072 
2073  switch (sizeof(int))
2074  {
2075  case 1:
2076  {
2077  return dlt_user_log_write_int8(log, (int8_t)data);
2078  break;
2079  }
2080  case 2:
2081  {
2082  return dlt_user_log_write_int16(log, (int16_t)data);
2083  break;
2084  }
2085  case 4:
2086  {
2087  return dlt_user_log_write_int32(log, (int32_t)data);
2088  break;
2089  }
2090  case 8:
2091  {
2092  return dlt_user_log_write_int64(log, (int64_t)data);
2093  break;
2094  }
2095  default:
2096  {
2097  return DLT_RETURN_ERROR;
2098  break;
2099  }
2100  }
2101 
2102  return DLT_RETURN_OK;
2103 }
2104 
2106 {
2107  uint32_t type_info;
2108 
2109  if (log == NULL)
2111 
2112  if (!dlt_user_initialised)
2113  {
2114  dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__);
2115  return DLT_RETURN_ERROR;
2116  }
2117 
2118  if ((log->size+sizeof(int8_t))>DLT_USER_BUF_MAX_SIZE)
2120 
2121  if (dlt_user.verbose_mode)
2122  {
2123  if ((log->size+sizeof(uint32_t)+sizeof(int8_t))>DLT_USER_BUF_MAX_SIZE)
2125 
2126  type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_8BIT;
2127 
2128  memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
2129  log->size += sizeof(uint32_t);
2130  }
2131 
2132  memcpy((log->buffer)+log->size,&data,sizeof(int8_t));
2133  log->size += sizeof(int8_t);
2134 
2135  log->args_num ++;
2136 
2137  return DLT_RETURN_OK;
2138 }
2139 
2141 {
2142  uint32_t type_info;
2143 
2144  if (log == NULL)
2146 
2147  if (!dlt_user_initialised)
2148  {
2149  dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__);
2150  return DLT_RETURN_ERROR;
2151  }
2152 
2153  if ((log->size+sizeof(int16_t))>DLT_USER_BUF_MAX_SIZE)
2155 
2156  if (dlt_user.verbose_mode)
2157  {
2158  if ((log->size+sizeof(uint32_t)+sizeof(int16_t))>DLT_USER_BUF_MAX_SIZE)
2160 
2161  type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_16BIT;
2162 
2163  memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
2164  log->size += sizeof(uint32_t);
2165  }
2166 
2167  memcpy((log->buffer)+log->size,&data,sizeof(int16_t));
2168  log->size += sizeof(int16_t);
2169 
2170  log->args_num ++;
2171 
2172  return DLT_RETURN_OK;
2173 }
2174 
2176 {
2177  uint32_t type_info;
2178 
2179  if (log == NULL)
2181 
2182  if (!dlt_user_initialised)
2183  {
2184  dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__);
2185  return DLT_RETURN_ERROR;
2186  }
2187 
2188  if ((log->size+sizeof(int32_t))>DLT_USER_BUF_MAX_SIZE)
2190 
2191  if (dlt_user.verbose_mode)
2192  {
2193  if ((log->size+sizeof(uint32_t)+sizeof(int32_t))>DLT_USER_BUF_MAX_SIZE)
2195 
2196  type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_32BIT;
2197 
2198  memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
2199  log->size += sizeof(uint32_t);
2200  }
2201 
2202  memcpy((log->buffer)+log->size,&data, sizeof(int32_t));
2203  log->size += sizeof(int32_t);
2204 
2205  log->args_num ++;
2206 
2207  return DLT_RETURN_OK;
2208 }
2209 
2211 {
2212  uint32_t type_info;
2213 
2214  if (log == NULL)
2216 
2217  if (!dlt_user_initialised)
2218  {
2219  dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__);
2220  return DLT_RETURN_ERROR;
2221  }
2222 
2223  if ((log->size+sizeof(int64_t))>DLT_USER_BUF_MAX_SIZE)
2225 
2226  if (dlt_user.verbose_mode)
2227  {
2228  if ((log->size+sizeof(uint32_t)+sizeof(int64_t))>DLT_USER_BUF_MAX_SIZE)
2230 
2231  type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_64BIT;
2232 
2233  memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
2234  log->size += sizeof(uint32_t);
2235  }
2236 
2237  memcpy((log->buffer)+log->size,&data,sizeof(int64_t));
2238  log->size += sizeof(int64_t);
2239 
2240  log->args_num ++;
2241 
2242  return DLT_RETURN_OK;
2243 }
2244 
2246 {
2247  uint32_t type_info;
2248 
2249  if (log == NULL)
2251 
2252  if (!dlt_user_initialised)
2253  {
2254  dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__);
2255  return DLT_RETURN_ERROR;
2256  }
2257 
2258  if ((log->size+sizeof(uint8_t))>DLT_USER_BUF_MAX_SIZE)
2260 
2261  if (dlt_user.verbose_mode)
2262  {
2263  if ((log->size+sizeof(uint32_t)+sizeof(uint8_t))>DLT_USER_BUF_MAX_SIZE)
2265 
2266  type_info = DLT_TYPE_INFO_BOOL;
2267 
2268  memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
2269  log->size += sizeof(uint32_t);
2270  }
2271 
2272  memcpy((log->buffer)+log->size,&data,sizeof(uint8_t));
2273  log->size += sizeof(uint8_t);
2274 
2275  log->args_num ++;
2276 
2277  return DLT_RETURN_OK;
2278 }
2279 
2281 {
2282  uint16_t arg_size = 0;
2283  uint32_t type_info = 0;
2284  size_t new_log_size = 0;
2285 
2286  if (log == NULL || text == NULL)
2288 
2289  if (!dlt_user_initialised)
2290  {
2291  dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__);
2292  return DLT_RETURN_ERROR;
2293  }
2294 
2295  arg_size = strlen(text) + 1;
2296 
2297  new_log_size = log->size + arg_size + sizeof(uint16_t);
2298 
2299  if (new_log_size > DLT_USER_BUF_MAX_SIZE)
2301 
2302  if (dlt_user.verbose_mode)
2303  {
2304  new_log_size = log->size + arg_size + sizeof(uint32_t) + sizeof(uint16_t);
2305 
2306  if (new_log_size > DLT_USER_BUF_MAX_SIZE)
2308 
2309  type_info = DLT_TYPE_INFO_STRG | DLT_SCOD_ASCII;
2310 
2311  memcpy((log->buffer) + log->size, &(type_info), sizeof(uint32_t));
2312  log->size += sizeof(uint32_t);
2313  }
2314 
2315  memcpy((log->buffer) + log->size, &(arg_size), sizeof(uint16_t));
2316  log->size += sizeof(uint16_t);
2317 
2318  memcpy((log->buffer) + log->size, text, arg_size);
2319  log->size += arg_size;
2320 
2321  log->args_num++;
2322 
2323  return DLT_RETURN_OK;
2324 }
2325 
2327 {
2328  /* Send parameter only in verbose mode */
2329  return dlt_user.verbose_mode ? dlt_user_log_write_string(log, text) : DLT_RETURN_OK;
2330 }
2331 
2333 {
2334  uint16_t arg_size;
2335  uint32_t type_info;
2336  size_t new_log_size = 0;
2337 
2338  if (log == NULL || text == NULL)
2340 
2341  if (!dlt_user_initialised)
2342  {
2343  dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__);
2344  return DLT_RETURN_ERROR;
2345  }
2346 
2347  arg_size = strlen(text) + 1;
2348  new_log_size = log->size + arg_size + sizeof(uint16_t);
2349 
2350  if (new_log_size > DLT_USER_BUF_MAX_SIZE)
2352 
2353  if (dlt_user.verbose_mode)
2354  {
2355  new_log_size = log->size + arg_size + sizeof(uint32_t) + sizeof(uint16_t);
2356 
2357  if (new_log_size > DLT_USER_BUF_MAX_SIZE)
2359 
2360  type_info = DLT_TYPE_INFO_STRG | DLT_SCOD_UTF8;
2361 
2362  memcpy((log->buffer) + log->size, &(type_info), sizeof(uint32_t));
2363  log->size += sizeof(uint32_t);
2364  }
2365 
2366  memcpy((log->buffer) + log->size, &(arg_size), sizeof(uint16_t));
2367  log->size += sizeof(uint16_t);
2368 
2369  memcpy((log->buffer) + log->size, text, arg_size);
2370  log->size += arg_size;
2371 
2372  log->args_num++;
2373 
2374  return DLT_RETURN_OK;
2375 }
2376 
2378  int (*dlt_injection_callback)(uint32_t service_id, void *data, uint32_t length))
2379 {
2380  DltContextData log;
2381  uint32_t i,j,k;
2382  int found = 0;
2383 
2385 
2386  if (dlt_user_log_init(handle, &log) < DLT_RETURN_OK)
2387  return DLT_RETURN_ERROR;
2388 
2389  if (service_id<DLT_USER_INJECTION_MIN)
2391 
2392  /* This function doesn't make sense storing to local file is choosen;
2393  so terminate this function */
2394  if (dlt_user.dlt_is_file)
2395  return DLT_RETURN_OK;
2396 
2397  DLT_SEM_LOCK();
2398 
2399  if (dlt_user.dlt_ll_ts == NULL)
2400  {
2401  DLT_SEM_FREE();
2402  return DLT_RETURN_OK;
2403  }
2404 
2405  /* Insert callback in corresponding table */
2406  i=handle->log_level_pos;
2407 
2408  /* Insert each service_id only once */
2409  for (k=0;k<dlt_user.dlt_ll_ts[i].nrcallbacks;k++)
2410  {
2411  if ((dlt_user.dlt_ll_ts[i].injection_table) &&
2412  (dlt_user.dlt_ll_ts[i].injection_table[k].service_id == service_id))
2413  {
2414  found = 1;
2415  break;
2416  }
2417  }
2418 
2419  if (found)
2420  {
2421  j = k;
2422  }
2423  else
2424  {
2425  j=dlt_user.dlt_ll_ts[i].nrcallbacks;
2426 
2427  /* Allocate or expand injection table */
2428  if (dlt_user.dlt_ll_ts[i].injection_table == NULL)
2429  {
2431  if(dlt_user.dlt_ll_ts[i].injection_table == NULL)
2432  {
2433  DLT_SEM_FREE();
2434  return DLT_RETURN_ERROR;
2435  }
2436  }
2437  else
2438  {
2439  old = dlt_user.dlt_ll_ts[i].injection_table;
2440  dlt_user.dlt_ll_ts[i].injection_table = (DltUserInjectionCallback*) malloc(sizeof(DltUserInjectionCallback)*(j+1));
2441  if(dlt_user.dlt_ll_ts[i].injection_table == NULL)
2442  {
2443  dlt_user.dlt_ll_ts[i].injection_table = old;
2444  DLT_SEM_FREE();
2445  return DLT_RETURN_ERROR;
2446  }
2447  memcpy(dlt_user.dlt_ll_ts[i].injection_table,old,sizeof(DltUserInjectionCallback)*j);
2448  free(old);
2449  }
2450 
2451  dlt_user.dlt_ll_ts[i].nrcallbacks++;
2452  }
2453 
2454  /* Store service_id and corresponding function pointer for callback function */
2456  dlt_user.dlt_ll_ts[i].injection_table[j].injection_callback = dlt_injection_callback;
2457 
2458  DLT_SEM_FREE();
2459 
2460  return DLT_RETURN_OK;
2461 }
2462 
2464  void (*dlt_log_level_changed_callback)(char context_id[DLT_ID_SIZE],uint8_t log_level, uint8_t trace_status))
2465 {
2466  DltContextData log;
2467  uint32_t i;
2468 
2469  if (dlt_user_log_init(handle, &log) < DLT_RETURN_OK)
2470  return DLT_RETURN_ERROR;
2471 
2472  /* This function doesn't make sense storing to local file is choosen;
2473  so terminate this function */
2474  if (dlt_user.dlt_is_file)
2475  return DLT_RETURN_OK;
2476 
2477  DLT_SEM_LOCK();
2478 
2479  if (dlt_user.dlt_ll_ts == NULL)
2480  {
2481  DLT_SEM_FREE();
2482  return DLT_RETURN_OK;
2483  }
2484 
2485  /* Insert callback in corresponding table */
2486  i=handle->log_level_pos;
2487 
2488  /* Store new callback function */
2489  dlt_user.dlt_ll_ts[i].log_level_changed_callback = dlt_log_level_changed_callback;
2490 
2491  DLT_SEM_FREE();
2492 
2493  return DLT_RETURN_OK;
2494 }
2495 
2501 int check_buffer(void)
2502 {
2503  int total_size, used_size;
2504  dlt_user_check_buffer(&total_size, &used_size);
2505 
2506  return (total_size - used_size < total_size / 2) ? -1 : 1;
2507 }
2508 
2513 DltReturnValue dlt_user_trace_network_segmented_start(uint32_t *id, DltContext *handle, DltNetworkTraceType nw_trace_type, uint16_t header_len, void *header, uint16_t payload_len)
2514 {
2515  DltContextData log;
2516  struct timeval tv;
2517 
2518  // check null pointer
2519  if(id == NULL)
2521 
2522  if (nw_trace_type < DLT_NW_TRACE_IPC || nw_trace_type >= DLT_NW_TRACE_MAX)
2523  {
2524  dlt_vlog(LOG_ERR, "Network trace type %d is outside valid range", nw_trace_type);
2526  }
2527 
2528  if (dlt_user_log_init(handle, &log) < DLT_RETURN_OK)
2529  return DLT_RETURN_ERROR;
2530 
2531  if (dlt_user.dlt_ll_ts == NULL)
2532  return DLT_RETURN_ERROR;
2533 
2534  if (handle->trace_status_ptr && *(handle->trace_status_ptr) == DLT_TRACE_STATUS_ON)
2535  {
2536 
2537  log.args_num = 0;
2539  log.size = 0;
2540 
2541  gettimeofday(&tv, NULL);
2542  *id = tv.tv_usec;
2543 
2544  /* Write identifier */
2545  if(dlt_user_log_write_string(&log, "NWST") < 0)
2546  return DLT_RETURN_ERROR;
2547 
2548  /* Write stream handle */
2549  if(dlt_user_log_write_uint32(&log, *id) < 0)
2550  return DLT_RETURN_ERROR;
2551 
2552  /* Write header */
2553  if(dlt_user_log_write_raw(&log, header, header_len) < 0)
2554  return DLT_RETURN_ERROR;
2555 
2556  /* Write size of payload */
2557  if(dlt_user_log_write_uint32(&log, payload_len) < 0)
2558  return DLT_RETURN_ERROR;
2559 
2560  /* Write expected segment count */
2561  uint16_t segment_count = payload_len/DLT_MAX_TRACE_SEGMENT_SIZE+1;
2562 
2563  /* If segments align perfectly with segment size, avoid sending empty segment */
2564  if((payload_len % DLT_MAX_TRACE_SEGMENT_SIZE) == 0)
2565  segment_count--;
2566 
2567  if(dlt_user_log_write_uint16(&log, segment_count) < 0)
2568  return DLT_RETURN_ERROR;
2569 
2570  /* Write length of one segment */
2571  if(dlt_user_log_write_uint16(&log, DLT_MAX_TRACE_SEGMENT_SIZE) < 0)
2572  return DLT_RETURN_ERROR;
2573 
2574  /* Send log */
2576  }
2577 
2578  return DLT_RETURN_OK;
2579 }
2580 
2581 DltReturnValue dlt_user_trace_network_segmented_segment(uint32_t id, DltContext *handle, DltNetworkTraceType nw_trace_type, int sequence, uint16_t payload_len, void *payload)
2582 {
2583  if (nw_trace_type < DLT_NW_TRACE_IPC || nw_trace_type >= DLT_NW_TRACE_MAX)
2584  {
2585  dlt_vlog(LOG_ERR, "Network trace type %d is outside valid range", nw_trace_type);
2587  }
2588 
2589  while(check_buffer() < 0)
2590  {
2591  usleep(1000*50); // Wait 50ms
2593  }
2594 
2595  DltContextData log;
2596 
2597  if (dlt_user_log_init(handle, &log) < DLT_RETURN_OK)
2598  return DLT_RETURN_ERROR;
2599 
2600  if (dlt_user.dlt_ll_ts == NULL)
2601  return DLT_RETURN_ERROR;
2602 
2603  if (handle->trace_status_ptr && *(handle->trace_status_ptr) == DLT_TRACE_STATUS_ON)
2604  {
2605 
2606  log.args_num = 0;
2608  log.size = 0;
2609 
2610  /* Write identifier */
2611  if(dlt_user_log_write_string(&log, "NWCH") < DLT_RETURN_OK)
2612  return DLT_RETURN_ERROR;
2613 
2614  /* Write stream handle */
2616  return DLT_RETURN_ERROR;
2617 
2618  /* Write segment sequence number */
2619  if(dlt_user_log_write_uint16(&log, sequence) < DLT_RETURN_OK)
2620  return DLT_RETURN_ERROR;
2621 
2622  /* Write data */
2623  if(dlt_user_log_write_raw(&log, payload, payload_len) < DLT_RETURN_OK)
2624  return DLT_RETURN_ERROR;
2625 
2626  /* Send log */
2628  }
2629 
2630  /* Allow other threads to log between chunks */
2631  pthread_yield();
2632  return DLT_RETURN_OK;
2633 }
2634 
2636 {
2637  DltContextData log;
2638 
2639  if (nw_trace_type < DLT_NW_TRACE_IPC || nw_trace_type >= DLT_NW_TRACE_MAX)
2640  {
2641  dlt_vlog(LOG_ERR, "Network trace type %d is outside valid range", nw_trace_type);
2643  }
2644 
2645  if (dlt_user_log_init(handle, &log) < DLT_RETURN_OK)
2646  return DLT_RETURN_ERROR;
2647 
2648  if (dlt_user.dlt_ll_ts == NULL)
2649  return DLT_RETURN_ERROR;
2650 
2651  if (handle->trace_status_ptr && *(handle->trace_status_ptr) == DLT_TRACE_STATUS_ON)
2652  {
2653  log.args_num = 0;
2655  log.size = 0;
2656 
2657  /* Write identifier */
2658  if(dlt_user_log_write_string(&log, "NWEN") < DLT_RETURN_OK)
2659  return DLT_RETURN_ERROR;
2660 
2661  /* Write stream handle */
2663  return DLT_RETURN_ERROR;
2664 
2665  /* Send log */
2667  }
2668 
2669  return DLT_RETURN_OK;
2670 }
2671 
2672 
2674 {
2675  /* Unused on purpose. */
2676  (void) unused;
2677 #ifdef linux
2678  prctl(PR_SET_NAME, "dlt_segmented", 0, 0, 0);
2679 #endif
2680 
2682 
2683  while(1)
2684  {
2685  // Wait until message queue is initialized
2687  if(dlt_user.dlt_segmented_queue_read_handle < 0)
2688  {
2689  pthread_cond_wait(&mq_init_condition, &mq_mutex);
2690  }
2692 
2693  ssize_t read = mq_receive(dlt_user.dlt_segmented_queue_read_handle, (char *)&data,
2694  sizeof(s_segmented_data * ), NULL);
2695 
2696  if(read != sizeof(s_segmented_data *))
2697  {
2698  dlt_log(LOG_WARNING,"NWTSegmented: Could not send end segment.\n");
2699  continue;
2700  }
2701 
2702  /* Indicator just to try to flush the buffer */
2704  {
2705  // Sleep 100ms, to allow other process to read FIFO
2706  usleep(100*1000);
2707  if(dlt_user_log_resend_buffer() < 0)
2708  {
2709  // Requeue if still not empty
2710  if ( dlt_user_queue_resend() < 0 )
2711  {
2712  //dlt_log(LOG_WARNING, "Failed to queue resending in dlt_user_trace_network_segmented_thread.\n");
2713  }
2714  }
2715  free(data);
2716  continue;
2717  }
2718 
2720 
2721  /* Send the end message */
2723  if(err == DLT_RETURN_BUFFER_FULL || err == DLT_RETURN_ERROR)
2724  {
2725  dlt_log(LOG_WARNING,"NWTSegmented: Could not send end segment.\n");
2726  }
2727 
2728  /* Free resources */
2729  free(data->header);
2730  free(data->payload);
2731  free(data);
2732  }
2733 }
2734 
2736 {
2737  /* Segment the data and send the chunks */
2738  void *ptr = NULL;
2739  uint32_t offset = 0;
2740  uint16_t sequence = 0;
2741  do
2742  {
2743  uint16_t len = 0;
2744  if(offset + DLT_MAX_TRACE_SEGMENT_SIZE > data->payload_len)
2745  {
2746  len = data->payload_len - offset;
2747  }
2748  else
2749  {
2751  }
2752  /* If payload size aligns perfectly with segment size, avoid sending empty segment */
2753  if(len == 0)
2754  {
2755  break;
2756  }
2757 
2758  ptr = data->payload + offset;
2759  DltReturnValue err = dlt_user_trace_network_segmented_segment(data->id, data->handle, data->nw_trace_type, sequence++, len, ptr);
2760  if(err == DLT_RETURN_BUFFER_FULL || err == DLT_RETURN_ERROR)
2761  {
2762  dlt_log(LOG_ERR,"NWTSegmented: Could not send segment. Aborting.\n");
2763  break; // loop
2764  }
2765  offset += len;
2766  }while(ptr < data->payload + data->payload_len);
2767 }
2768 
2769 
2770 DltReturnValue dlt_user_trace_network_segmented(DltContext *handle, DltNetworkTraceType nw_trace_type, uint16_t header_len, void *header, uint16_t payload_len, void *payload)
2771 {
2772  /* Send as normal trace if possible */
2773  if(header_len+payload_len+sizeof(uint16_t) < DLT_USER_BUF_MAX_SIZE) {
2774  return dlt_user_trace_network(handle, nw_trace_type, header_len, header, payload_len, payload);
2775  }
2776 
2777  /* Allocate Memory */
2778  s_segmented_data *thread_data = malloc(sizeof(s_segmented_data));
2779  if(thread_data == NULL)
2780  {
2781  return DLT_RETURN_ERROR;
2782  }
2783  thread_data->header = malloc(header_len);
2784  if(thread_data->header == NULL)
2785  {
2786  free(thread_data);
2787  return DLT_RETURN_ERROR;
2788  }
2789  thread_data->payload = malloc(payload_len);
2790  if(thread_data->payload == NULL)
2791  {
2792  free(thread_data->header);
2793  free(thread_data);
2794  return DLT_RETURN_ERROR;
2795  }
2796 
2797  /* Copy data */
2798  thread_data->handle = handle;
2799  thread_data->nw_trace_type = nw_trace_type;
2800  thread_data->header_len = header_len;
2801  memcpy(thread_data->header, header, header_len);
2802  thread_data->payload_len = payload_len;
2803  memcpy(thread_data->payload, payload, payload_len);
2804 
2805  /* Send start message */
2807  thread_data->handle, thread_data->nw_trace_type,
2808  thread_data->header_len, thread_data->header,
2809  thread_data->payload_len);
2810  if(err == DLT_RETURN_BUFFER_FULL || err == DLT_RETURN_ERROR)
2811  {
2812  dlt_log(LOG_ERR,"NWTSegmented: Could not send start segment. Aborting.\n");
2813  free(thread_data->header);
2814  free(thread_data->payload);
2815  free(thread_data);
2816  return DLT_RETURN_ERROR;
2817  }
2818 
2819  /* Open queue if it is not open */
2820  if(dlt_init_message_queue() < 0)
2821  {
2822  dlt_log(LOG_ERR, "NWTSegmented: Could not open queue.\n");
2823  free(thread_data->header);
2824  free(thread_data->payload);
2825  free(thread_data);
2826 
2827  return DLT_RETURN_ERROR;
2828  }
2829 
2830  /* Add to queue */
2831  if(mq_send(dlt_user.dlt_segmented_queue_write_handle,
2832  (char *)&thread_data, sizeof(s_segmented_data *), 1) < 0)
2833  {
2834  if(errno == EAGAIN)
2835  {
2836  dlt_log(LOG_WARNING, "NWTSegmented: Queue full. Message discarded.\n");
2837  }
2838  free(thread_data->header);
2839  free(thread_data->payload);
2840  free(thread_data);
2841  dlt_vnlog(LOG_WARNING, 256,"NWTSegmented: Could not write into queue: %s \n",strerror(errno));
2842  return DLT_RETURN_ERROR;
2843  }
2844 
2845  //thread_data will be freed by the receiver function
2846  //coverity[leaked_storage]
2847  return DLT_RETURN_OK;
2848 }
2849 
2850 DltReturnValue dlt_user_trace_network(DltContext *handle, DltNetworkTraceType nw_trace_type, uint16_t header_len, void *header, uint16_t payload_len, void *payload)
2851 {
2852  return dlt_user_trace_network_truncated(handle, nw_trace_type, header_len, header, payload_len, payload, 1);
2853 }
2854 
2855 DltReturnValue 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)
2856 {
2857  if(payload == NULL && payload_len > 0)
2859 
2860  DltContextData log;
2861 
2862  if (nw_trace_type < DLT_NW_TRACE_IPC || nw_trace_type >= DLT_NW_TRACE_MAX)
2863  {
2864  dlt_vlog(LOG_ERR, "Network trace type %d is outside valid range", nw_trace_type);
2866  }
2867 
2868  if (dlt_user_log_init(handle, &log) < DLT_RETURN_OK || dlt_user.dlt_ll_ts == NULL)
2869  return DLT_RETURN_ERROR;
2870 
2871  /* Commented out because of DltNetworkTraceType:
2872 
2873  if ((nw_trace_type<=0) || (nw_trace_type>0x15))
2874  {
2875  return DLT_RETURN_ERROR;
2876  }
2877 
2878  */
2879 
2880  if (dlt_user.dlt_ll_ts==0)
2881  {
2882  return DLT_RETURN_ERROR;
2883  }
2884 
2885  if (handle->trace_status_ptr && *(handle->trace_status_ptr)==DLT_TRACE_STATUS_ON)
2886  {
2887  log.args_num = 0;
2889  log.size = 0;
2890 
2891  if (header == NULL)
2892  header_len = 0;
2893 
2894  /* If truncation is allowed, check if we must do it */
2895  if(allow_truncate > 0 && (header_len+payload_len+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
2896  {
2897  /* Identify as truncated */
2898  if(dlt_user_log_write_string(&log, "NWTR") < DLT_RETURN_OK)
2899  return DLT_RETURN_ERROR;
2900 
2901  /* Write header and its length */
2902  if (dlt_user_log_write_raw(&log, header, header_len) < DLT_RETURN_OK)
2903  return DLT_RETURN_ERROR;
2904 
2905  /* Write original size of payload */
2906  if(dlt_user_log_write_uint32(&log, payload_len) < DLT_RETURN_OK)
2907  return DLT_RETURN_ERROR;
2908 
2913  int truncated_payload_len = DLT_USER_BUF_MAX_SIZE - log.size - sizeof(uint16_t) - sizeof(uint32_t);
2914 
2915  /* Write truncated payload */
2916  if (dlt_user_log_write_raw(&log, payload, truncated_payload_len) < DLT_RETURN_OK)
2917  return DLT_RETURN_ERROR;
2918  }
2919  else /* Truncation not allowed or data short enough */
2920  {
2921  /* Write header and its length */
2922  if (dlt_user_log_write_raw(&log, header, header_len) < DLT_RETURN_OK)
2923  return DLT_RETURN_ERROR;
2924 
2925  if (payload == NULL)
2926  payload_len = 0;
2927 
2928  /* Write payload and its length */
2929  if (dlt_user_log_write_raw(&log, payload, payload_len) < DLT_RETURN_OK)
2930  return DLT_RETURN_ERROR;
2931  }
2932 
2933  /* Send log */
2935  }
2936 
2937  return DLT_RETURN_OK;
2938 }
2939 
2940 DltReturnValue dlt_log_string(DltContext *handle, DltLogLevelType loglevel, const char *text)
2941 {
2942  DltContextData log;
2944 
2945  if (dlt_user.verbose_mode==0)
2946  {
2947  return DLT_RETURN_ERROR;
2948  }
2949 
2950  if (loglevel < DLT_USER_LOG_LEVEL_NOT_SET || loglevel >= DLT_LOG_MAX)
2951  {
2952  dlt_vlog(LOG_ERR, "Loglevel %d is outside valid range", loglevel);
2954  }
2955 
2956  if ((handle == NULL) || (text == NULL))
2957  {
2959  }
2960 
2961  if (dlt_user_log_write_start(handle,&log,loglevel) > 0)
2962  {
2963  if ( (ret = dlt_user_log_write_string(&log,text)) < DLT_RETURN_OK)
2964  {
2965  return ret;
2966  }
2968  {
2969  return DLT_RETURN_ERROR;
2970  }
2971  }
2972 
2973  return DLT_RETURN_OK;
2974 }
2975 
2976 DltReturnValue dlt_log_string_int(DltContext *handle, DltLogLevelType loglevel, const char *text, int data)
2977 {
2978  DltContextData log;
2980 
2981  if (dlt_user.verbose_mode==0)
2982  {
2983  return DLT_RETURN_ERROR;
2984  }
2985 
2986  if (loglevel < DLT_USER_LOG_LEVEL_NOT_SET || loglevel >= DLT_LOG_MAX)
2987  {
2988  dlt_vlog(LOG_ERR, "Loglevel %d is outside valid range", loglevel);
2990  }
2991 
2992  if ((handle == NULL) || (text == NULL))
2993  {
2995  }
2996 
2997  if (dlt_user_log_write_start(handle, &log, loglevel) > 0)
2998  {
2999  if ( (ret = dlt_user_log_write_string(&log, text)) < DLT_RETURN_OK)
3000  {
3001  return ret;
3002  }
3003  if ( (ret = dlt_user_log_write_int(&log, data)) < DLT_RETURN_OK)
3004  {
3005  return ret;
3006  }
3008  {
3009  return DLT_RETURN_ERROR;
3010  }
3011  }
3012 
3013  return DLT_RETURN_OK;
3014 }
3015 
3016 DltReturnValue dlt_log_string_uint(DltContext *handle, DltLogLevelType loglevel, const char *text, unsigned int data)
3017 {
3018  DltContextData log;
3020 
3021  if (dlt_user.verbose_mode==0)
3022  {
3023  return DLT_RETURN_ERROR;
3024  }
3025 
3026  if (loglevel < DLT_USER_LOG_LEVEL_NOT_SET || loglevel >= DLT_LOG_MAX)
3027  {
3028  dlt_vlog(LOG_ERR, "Loglevel %d is outside valid range", loglevel);
3030  }
3031 
3032  if ((handle == NULL) || (text == NULL))
3033  {
3035  }
3036 
3037  if (dlt_user_log_write_start(handle,&log,loglevel) > 0)
3038  {
3039  if ( (ret = dlt_user_log_write_string(&log,text)) < DLT_RETURN_OK)
3040  {
3041  return ret;
3042  }
3043  if ( (ret = dlt_user_log_write_uint(&log,data)) < DLT_RETURN_OK)
3044  {
3045  return ret;
3046  }
3048  {
3049  return DLT_RETURN_ERROR;
3050  }
3051  }
3052 
3053  return DLT_RETURN_OK;
3054 }
3055 
3057 {
3058  DltContextData log;
3060 
3061  if (dlt_user.verbose_mode==0)
3062  {
3063  return DLT_RETURN_ERROR;
3064  }
3065 
3066  if (loglevel < DLT_USER_LOG_LEVEL_NOT_SET || loglevel >= DLT_LOG_MAX)
3067  {
3068  dlt_vlog(LOG_ERR, "Loglevel %d is outside valid range", loglevel);
3070  }
3071 
3072  if (handle == NULL)
3073  {
3074  return DLT_RETURN_ERROR;
3075  }
3076 
3077  if (dlt_user_log_write_start(handle,&log,loglevel) > 0)
3078  {
3079  if ( (ret = dlt_user_log_write_int(&log,data)) < DLT_RETURN_OK)
3080  {
3081  return ret;
3082  }
3084  {
3085  return DLT_RETURN_ERROR;
3086  }
3087  }
3088 
3089  return DLT_RETURN_OK;
3090 }
3091 
3093 {
3094  DltContextData log;
3096 
3097  if (dlt_user.verbose_mode==0)
3098  {
3099  return DLT_RETURN_ERROR;
3100  }
3101 
3102  if (loglevel < DLT_USER_LOG_LEVEL_NOT_SET || loglevel >= DLT_LOG_MAX)
3103  {
3104  dlt_vlog(LOG_ERR, "Loglevel %d is outside valid range", loglevel);
3105  return DLT_RETURN_ERROR;
3106  }
3107 
3108  if (handle == NULL)
3109  {
3111  }
3112 
3113  if (dlt_user_log_write_start(handle,&log,loglevel) > 0)
3114  {
3115  if ( (ret = dlt_user_log_write_uint(&log,data)) < DLT_RETURN_OK)
3116  {
3117  return ret;
3118  }
3120  {
3121  return DLT_RETURN_ERROR;
3122  }
3123  }
3124 
3125  return DLT_RETURN_OK;
3126 }
3127 
3128 DltReturnValue dlt_log_raw(DltContext *handle, DltLogLevelType loglevel, void *data, uint16_t length)
3129 {
3130  DltContextData log;
3132 
3133  if (dlt_user.verbose_mode==0)
3134  {
3135  return DLT_RETURN_ERROR;
3136  }
3137 
3138  if (loglevel < DLT_USER_LOG_LEVEL_NOT_SET || loglevel >= DLT_LOG_MAX)
3139  {
3140  dlt_vlog(LOG_ERR, "Loglevel %d is outside valid range", loglevel);
3142  }
3143 
3144  if (handle == NULL)
3145  {
3147  }
3148 
3149  if (dlt_user_log_write_start(handle,&log,loglevel) > 0)
3150  {
3151  if ( (ret = dlt_user_log_write_raw(&log,data,length)) < DLT_RETURN_OK)
3152  {
3153  return ret;
3154  }
3156  {
3157  return DLT_RETURN_ERROR;
3158  }
3159  }
3160 
3161  return DLT_RETURN_OK;
3162 }
3163 
3165 {
3166  if (!dlt_user_initialised)
3167  {
3168  if (dlt_init() < DLT_RETURN_OK)
3169  {
3170  dlt_vlog(LOG_ERR, "%s Failed to initialise dlt", __FUNCTION__);
3171  return DLT_RETURN_ERROR;
3172  }
3173  }
3174 
3175  return dlt_user_log_send_marker();
3176 }
3177 
3179 {
3180  if (!dlt_user_initialised)
3181  {
3182  if (dlt_init() < DLT_RETURN_OK)
3183  {
3184  dlt_vlog(LOG_ERR, "%s Failed to initialise dlt", __FUNCTION__);
3185  return DLT_RETURN_ERROR;
3186  }
3187  }
3188 
3189  /* Switch to verbose mode */
3190  dlt_user.verbose_mode = 1;
3191 
3192  return DLT_RETURN_OK;
3193 }
3194 
3196 {
3197  if (!dlt_user_initialised)
3198  {
3199  if (dlt_init() < DLT_RETURN_OK)
3200  {
3201  dlt_vlog(LOG_ERR, "%s Failed to initialise dlt", __FUNCTION__);
3202  return DLT_RETURN_ERROR;
3203  }
3204  }
3205 
3206  /* Switch to non-verbose mode */
3207  dlt_user.verbose_mode = 0;
3208 
3209  return DLT_RETURN_OK;
3210 }
3211 
3212 DltReturnValue dlt_use_extended_header_for_non_verbose(int8_t use_extende_header_for_non_verbose)
3213 {
3214  if (!dlt_user_initialised)
3215  {
3216  if (dlt_init() < DLT_RETURN_OK)
3217  {
3218  dlt_vlog(LOG_ERR, "%s Failed to initialise dlt", __FUNCTION__);
3219  return DLT_RETURN_ERROR;
3220  }
3221  }
3222 
3223  /* Set use_extende_header_for_non_verbose */
3224  dlt_user.use_extende_header_for_non_verbose = use_extende_header_for_non_verbose;
3225 
3226  return DLT_RETURN_OK;
3227 }
3228 
3229 DltReturnValue dlt_with_session_id(int8_t with_session_id)
3230 {
3231  if (!dlt_user_initialised)
3232  {
3233  if (dlt_init() < DLT_RETURN_OK)
3234  {
3235  dlt_vlog(LOG_ERR, "%s Failed to initialise dlt", __FUNCTION__);
3236  return DLT_RETURN_ERROR;
3237  }
3238  }
3239 
3240  /* Set use_extende_header_for_non_verbose */
3241  dlt_user.with_session_id = with_session_id;
3242 
3243  return DLT_RETURN_OK;
3244 }
3245 
3246 DltReturnValue dlt_with_timestamp(int8_t with_timestamp)
3247 {
3248  if (!dlt_user_initialised)
3249  {
3250  if (dlt_init() < DLT_RETURN_OK)
3251  {
3252  dlt_vlog(LOG_ERR, "%s Failed to initialise dlt", __FUNCTION__);
3253  return DLT_RETURN_ERROR;
3254  }
3255  }
3256 
3257  /* Set with_timestamp */
3258  dlt_user.with_timestamp = with_timestamp;
3259 
3260  return DLT_RETURN_OK;
3261 }
3262 
3263 DltReturnValue dlt_with_ecu_id(int8_t with_ecu_id)
3264 {
3265  if (!dlt_user_initialised)
3266  {
3267  if (dlt_init() < DLT_RETURN_OK)
3268  {
3269  dlt_vlog(LOG_ERR, "%s Failed to initialise dlt", __FUNCTION__);
3270  return DLT_RETURN_ERROR;
3271  }
3272  }
3273 
3274  /* Set with_timestamp */
3275  dlt_user.with_ecu_id = with_ecu_id;
3276 
3277  return DLT_RETURN_OK;
3278 }
3279 
3281 {
3282  if (!dlt_user_initialised)
3283  {
3284  if (dlt_init() < DLT_RETURN_OK)
3285  {
3286  dlt_vlog(LOG_ERR, "%s Failed to initialise dlt", __FUNCTION__);
3287  return DLT_RETURN_ERROR;
3288  }
3289  }
3290 
3291  dlt_user.enable_local_print = 1;
3292 
3293  return DLT_RETURN_OK;
3294 }
3295 
3297 {
3298  if (!dlt_user_initialised)
3299  {
3300  if (dlt_init() < DLT_RETURN_OK)
3301  {
3302  dlt_vlog(LOG_ERR, "%s Failed to initialise dlt", __FUNCTION__);
3303  return DLT_RETURN_ERROR;
3304  }
3305  }
3306 
3307  dlt_user.enable_local_print = 0;
3308 
3309  return DLT_RETURN_OK;
3310 }
3311 
3312 void dlt_user_receiverthread_function(__attribute__((unused)) void *ptr)
3313 {
3314 #ifdef linux
3315  prctl(PR_SET_NAME, "dlt_receiver", 0, 0, 0);
3316 #endif
3317  while (1)
3318  {
3319  /* Check for new messages from DLT daemon */
3321  {
3322  /* Critical error */
3323  dlt_log(LOG_CRIT,"Receiver thread encountered error condition\n");
3324  }
3325 
3326  usleep(DLT_USER_RECEIVE_DELAY); /* delay */
3327  }
3328 }
3329 
3330 /* Private functions of user library */
3331 
3333 {
3334  if (handle == NULL || log == NULL)
3336 
3337  if (!dlt_user_initialised)
3338  {
3339  if (dlt_init() < DLT_RETURN_OK)
3340  {
3341  dlt_vlog(LOG_ERR, "%s Failed to initialise dlt", __FUNCTION__);
3342  return DLT_RETURN_ERROR;
3343  }
3344  }
3345 
3346  log->handle = handle;
3347 
3348  return DLT_RETURN_OK;
3349 }
3350 
3352 {
3353  static unsigned char dlt_user_queue_resend_error_counter = 0;
3354 
3355  if(dlt_user.dlt_log_handle < 0)
3356  {
3357  // Fail silenty. FIFO is not open yet
3358  return DLT_RETURN_ERROR;
3359  }
3364  s_segmented_data *resend_data = malloc(sizeof(s_segmented_data));
3365 
3366  if (resend_data == NULL)
3367  {
3368  return DLT_RETURN_ERROR;
3369  }
3370 
3372 
3373 
3374 
3375  /* Open queue if it is not open */
3377  {
3378  if(!dlt_user_queue_resend_error_counter)
3379  {
3380  // log error only when problem occurred first time
3381  dlt_log(LOG_WARNING, "NWTSegmented: Could not open queue.\n");
3382  }
3383  dlt_user_queue_resend_error_counter = 1;
3384  free(resend_data);
3385  return DLT_RETURN_ERROR;
3386  }
3387 
3388  if(mq_send(dlt_user.dlt_segmented_queue_write_handle, (char *)&resend_data, sizeof(s_segmented_data *), 1) < 0)
3389  {
3390  if(!dlt_user_queue_resend_error_counter)
3391  {
3392  // log error only when problem occurred first time
3393  dlt_vnlog(LOG_DEBUG, 256,"Could not request resending.: %s \n",strerror(errno));
3394  }
3395  dlt_user_queue_resend_error_counter = 1;
3396  free(resend_data);
3397  return DLT_RETURN_ERROR;
3398  }
3399 
3400  dlt_user_queue_resend_error_counter = 0;
3401 
3402  //thread_data will be freed by the receiver function
3403  //coverity[leaked_storage]
3404  return DLT_RETURN_OK;
3405 }
3406 
3408 {
3409  DltMessage msg;
3410  DltUserHeader userheader;
3411  int32_t len;
3412 
3414 
3415  if (!dlt_user_initialised)
3416  {
3417  dlt_vlog(LOG_ERR, "%s dlt_user_initialised false\n", __FUNCTION__);
3418  return DLT_RETURN_ERROR;
3419  }
3420 
3421  if (log == NULL ||
3422  log->handle == NULL ||
3423  log->handle->contextID[0] == '\0' ||
3424  (mtype < DLT_TYPE_LOG) || (mtype > DLT_TYPE_CONTROL)
3425  )
3426  {
3428  }
3429 
3430  /* also for Trace messages */
3431 #ifdef DLT_SHM_ENABLE
3433 #else
3435 #endif
3436  {
3437  return DLT_RETURN_ERROR;
3438  }
3439 
3440  if (dlt_message_init(&msg, 0) == DLT_RETURN_ERROR)
3441  {
3442  return DLT_RETURN_ERROR;
3443  }
3444 
3445  msg.storageheader = (DltStorageHeader*)msg.headerbuffer;
3446 
3448  {
3449  return DLT_RETURN_ERROR;
3450  }
3451 
3452  msg.standardheader = (DltStandardHeader*)(msg.headerbuffer + sizeof(DltStorageHeader));
3454 
3455  /* send ecu id */
3456  if(dlt_user.with_ecu_id)
3457  {
3458  msg.standardheader->htyp |= DLT_HTYP_WEID;
3459  }
3460 
3461  /* send timestamp */
3462  if(dlt_user.with_timestamp)
3463  {
3464  msg.standardheader->htyp |= DLT_HTYP_WTMS;
3465  }
3466 
3467  /* send session id */
3468  if(dlt_user.with_session_id)
3469  {
3470  msg.standardheader->htyp |= DLT_HTYP_WSID;
3471  msg.headerextra.seid = getpid();
3472  }
3473 
3474  if (dlt_user.verbose_mode)
3475  {
3476  /* In verbose mode, send extended header */
3477  msg.standardheader->htyp = (msg.standardheader->htyp | DLT_HTYP_UEH );
3478  }
3479  else
3480  {
3481  /* In non-verbose, send extended header if desired */
3483  msg.standardheader->htyp = (msg.standardheader->htyp | DLT_HTYP_UEH );
3484  }
3485 
3486 #if (BYTE_ORDER==BIG_ENDIAN)
3487  msg.standardheader->htyp = (msg.standardheader->htyp | DLT_HTYP_MSBF);
3488 #endif
3489 
3490  msg.standardheader->mcnt = log->handle->mcnt++;
3491 
3492  /* Set header extra parameters */
3493  dlt_set_id(msg.headerextra.ecu,dlt_user.ecuID);
3494  //msg.headerextra.seid = 0;
3495  msg.headerextra.tmsp = dlt_uptime();
3496 
3498  {
3499  return DLT_RETURN_ERROR;
3500  }
3501 
3502  /* Fill out extended header, if extended header should be provided */
3503  if (DLT_IS_HTYP_UEH(msg.standardheader->htyp))
3504  {
3505  /* with extended header */
3506  msg.extendedheader = (DltExtendedHeader*)(msg.headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp) );
3507 
3508  switch (mtype)
3509  {
3510  case DLT_TYPE_LOG:
3511  {
3512  msg.extendedheader->msin = (DLT_TYPE_LOG << DLT_MSIN_MSTP_SHIFT) | ((log->log_level << DLT_MSIN_MTIN_SHIFT) & DLT_MSIN_MTIN) ; /* messsage info */
3513  break;
3514  }
3515  case DLT_TYPE_NW_TRACE:
3516  {
3517  msg.extendedheader->msin = (DLT_TYPE_NW_TRACE << DLT_MSIN_MSTP_SHIFT) | ((log->trace_status << DLT_MSIN_MTIN_SHIFT) & DLT_MSIN_MTIN) ; /* messsage info */
3518  break;
3519  }
3520  default:
3521  {
3522  /* This case should not occur */
3523  return DLT_RETURN_ERROR;
3524  break;
3525  }
3526  }
3527 
3528  /* If in verbose mode, set flag in header for verbose mode */
3529  if (dlt_user.verbose_mode)
3530  {
3531  msg.extendedheader->msin |= DLT_MSIN_VERB;
3532  }
3533 
3534  msg.extendedheader->noar = log->args_num; /* number of arguments */
3535  dlt_set_id(msg.extendedheader->apid,dlt_user.appID); /* application id */
3536  dlt_set_id(msg.extendedheader->ctid,log->handle->contextID); /* context id */
3537 
3538  msg.headersize = sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + sizeof(DltExtendedHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp);
3539  }
3540  else
3541  {
3542  /* without extended header */
3543  msg.headersize = sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp);
3544  }
3545 
3546  len=msg.headersize - sizeof(DltStorageHeader) +log->size;
3547  if (len>UINT16_MAX)
3548  {
3549  dlt_log(LOG_WARNING,"Huge message discarded!\n");
3550  return DLT_RETURN_ERROR;
3551  }
3552 
3553  msg.standardheader->len = DLT_HTOBE_16(len);
3554 
3555  /* print to std out, if enabled */
3556  if ((dlt_user.local_print_mode != DLT_PM_FORCE_OFF) &&
3557  (dlt_user.local_print_mode != DLT_PM_AUTOMATIC))
3558  {
3559  if ((dlt_user.enable_local_print) || (dlt_user.local_print_mode == DLT_PM_FORCE_ON))
3560  {
3561  if (dlt_user_print_msg(&msg, log) == DLT_RETURN_ERROR)
3562  {
3563  return DLT_RETURN_ERROR;
3564  }
3565  }
3566  }
3567 
3568  if (dlt_user.dlt_is_file)
3569  {
3570  /* log to file */
3571  ret=dlt_user_log_out2(dlt_user.dlt_log_handle, msg.headerbuffer, msg.headersize, log->buffer, log->size);
3572  return ret;
3573  }
3574  else
3575  {
3576  /* Reattach to daemon if neccesary */
3578 
3579  if (dlt_user.overflow_counter)
3580  {
3582  {
3583  dlt_vnlog(LOG_WARNING, DLT_USER_BUFFER_LENGTH, "%u messages discarded!\n", dlt_user.overflow_counter);
3584  dlt_user.overflow_counter = 0;
3585  }
3586  }
3587 
3588  /* try to resent old data first */
3589  ret = DLT_RETURN_OK;
3590  if((dlt_user.dlt_log_handle!=-1) && (dlt_user.appID[0]!='\0'))
3591  {
3593  }
3594  if((ret == DLT_RETURN_OK) && (dlt_user.appID[0] != '\0'))
3595  {
3596  /* resend ok or nothing to resent */
3597 #ifdef DLT_SHM_ENABLE
3598  if(dlt_user.dlt_log_handle!=-1)
3599  dlt_shm_push(&dlt_user.dlt_shm,msg.headerbuffer+sizeof(DltStorageHeader), msg.headersize-sizeof(DltStorageHeader),
3600  log->buffer, log->size, 0, 0);
3601 
3602  /* log to FIFO */
3603  ret = dlt_user_log_out3(dlt_user.dlt_log_handle,
3604  &(userheader), sizeof(DltUserHeader),
3605  0, 0,
3606  0, 0);
3607 #else
3608  /* log to FIFO */
3609 #ifdef DLT_TEST_ENABLE
3610  if(dlt_user.corrupt_user_header) {
3611  userheader.pattern[0]=0xff;
3612  userheader.pattern[1]=0xff;
3613  userheader.pattern[2]=0xff;
3614  userheader.pattern[3]=0xff;
3615  }
3616  if(dlt_user.corrupt_message_size) {
3617  msg.standardheader->len = DLT_HTOBE_16(dlt_user.corrupt_message_size_size);
3618  }
3619 #endif
3620  ret = dlt_user_log_out3(dlt_user.dlt_log_handle,
3621  &(userheader), sizeof(DltUserHeader),
3622  msg.headerbuffer+sizeof(DltStorageHeader), msg.headersize-sizeof(DltStorageHeader),
3623  log->buffer, log->size);
3624 #endif
3625  }
3626 
3627  /* store message in ringbuffer, if an error has occured */
3628  if ((ret!=DLT_RETURN_OK) || (dlt_user.appID[0] == '\0'))
3629  {
3630  DLT_SEM_LOCK();
3631 
3632  if (dlt_buffer_push3(&(dlt_user.startup_buffer),
3633  (unsigned char *)&(userheader), sizeof(DltUserHeader),
3634  msg.headerbuffer+sizeof(DltStorageHeader), msg.headersize-sizeof(DltStorageHeader),
3635  log->buffer, log->size) == DLT_RETURN_ERROR)
3636  {
3637  if(dlt_user.overflow_counter == 0)
3638  {
3639 
3640  dlt_log(LOG_WARNING,"Buffer full! Messages will be discarded.\n");
3641  }
3642  ret = DLT_RETURN_BUFFER_FULL;
3643  }
3644 
3645  DLT_SEM_FREE();
3646 
3647  // Fail silenty if FIFO is not open
3648  if((dlt_user.appID[0] != '\0') &&(dlt_user_queue_resend() < 0) && (dlt_user.dlt_log_handle >= 0))
3649  {
3650  ;//dlt_log(LOG_WARNING, "dlt_user_log_send_log: Failed to queue resending.\n");
3651  }
3652  }
3653 
3654  switch (ret)
3655  {
3657  {
3658  /* Buffer full */
3659  dlt_user.overflow_counter += 1;
3660  return DLT_RETURN_BUFFER_FULL;
3661  }
3662  case DLT_RETURN_PIPE_FULL:
3663  {
3664  /* data could not be written */
3665  return DLT_RETURN_PIPE_FULL;
3666  }
3667  case DLT_RETURN_PIPE_ERROR:
3668  {
3669  /* handle not open or pipe error */
3670  close(dlt_user.dlt_log_handle);
3671  dlt_user.dlt_log_handle = -1;
3672 
3673  #ifdef DLT_SHM_ENABLE
3674  /* free shared memory */
3675  dlt_shm_free_client(&dlt_user.dlt_shm);
3676  #endif
3677 
3678  if (dlt_user.local_print_mode == DLT_PM_AUTOMATIC)
3679  {
3680  dlt_user_print_msg(&msg, log);
3681  }
3682 
3683  return DLT_RETURN_PIPE_ERROR;
3684  }
3685  case DLT_RETURN_ERROR:
3686  {
3687  /* other error condition */
3688  return DLT_RETURN_ERROR;
3689  }
3690  case DLT_RETURN_OK:
3691  {
3692  return DLT_RETURN_OK;
3693  }
3694  default:
3695  {
3696  /* This case should never occur. */
3697  return DLT_RETURN_ERROR;
3698  }
3699  }
3700  }
3701 
3702  return DLT_RETURN_OK;
3703 }
3704 
3706 {
3707  DltUserHeader userheader;
3708  DltUserControlMsgRegisterApplication usercontext;
3709 
3710  DltReturnValue ret;
3711 
3712  if (dlt_user.appID[0]=='\0')
3713  {
3714  return DLT_RETURN_ERROR;
3715  }
3716 
3717  /* set userheader */
3719  {
3720  return DLT_RETURN_ERROR;
3721  }
3722 
3723  /* set usercontext */
3724  dlt_set_id(usercontext.apid,dlt_user.appID); /* application id */
3725  usercontext.pid = getpid();
3726 
3727  if (dlt_user.application_description != NULL)
3728  {
3729  usercontext.description_length = strlen(dlt_user.application_description);
3730  }
3731  else
3732  {
3733  usercontext.description_length = 0;
3734  }
3735 
3736  if (dlt_user.dlt_is_file)
3737  {
3738  return DLT_RETURN_OK;
3739  }
3740 
3741  /* log to FIFO */
3742  ret = dlt_user_log_out3(dlt_user.dlt_log_handle,
3743  &(userheader), sizeof(DltUserHeader),
3744  &(usercontext), sizeof(DltUserControlMsgRegisterApplication),
3745  dlt_user.application_description, usercontext.description_length);
3746 
3747  /* store message in ringbuffer, if an error has occured */
3748  if (ret < DLT_RETURN_OK)
3749  {
3750  DLT_SEM_LOCK();
3751 
3752  if (dlt_buffer_push3(&(dlt_user.startup_buffer),
3753  (unsigned char *)&(userheader), sizeof(DltUserHeader),
3754  (const unsigned char*)&(usercontext), sizeof(DltUserControlMsgRegisterApplication),
3755  (const unsigned char*)dlt_user.application_description, usercontext.description_length) == DLT_RETURN_ERROR)
3756  {
3757  dlt_log(LOG_WARNING,"Storing message to history buffer failed! Message discarded.\n");
3758  DLT_SEM_FREE();
3759  return DLT_RETURN_ERROR;
3760  }
3761 
3762  DLT_SEM_FREE();
3763 
3764  if(dlt_user_queue_resend() < DLT_RETURN_OK && dlt_user.dlt_log_handle >= 0)
3765  {
3766  ;//dlt_log(LOG_WARNING, "dlt_user_log_send_register_application: Failed to queue resending.\n");
3767  }
3768  }
3769 
3770  return DLT_RETURN_OK;
3771 }
3772 
3774 {
3775  DltUserHeader userheader;
3776  DltUserControlMsgUnregisterApplication usercontext;
3777 
3778  if (dlt_user.appID[0]=='\0')
3779  {
3780  return DLT_RETURN_ERROR;
3781  }
3782 
3783  /* set userheader */
3785  {
3786  return DLT_RETURN_ERROR;
3787  }
3788 
3789  /* set usercontext */
3790  dlt_set_id(usercontext.apid,dlt_user.appID); /* application id */
3791  usercontext.pid = getpid();
3792 
3793  if (dlt_user.dlt_is_file)
3794  {
3795  return DLT_RETURN_OK;
3796  }
3797 
3798  /* log to FIFO */
3799  return dlt_user_log_out2(dlt_user.dlt_log_handle,
3800  &(userheader), sizeof(DltUserHeader),
3801  &(usercontext), sizeof(DltUserControlMsgUnregisterApplication));
3802 }
3803 
3805 {
3806  DltUserHeader userheader;
3807  DltUserControlMsgRegisterContext usercontext;
3809 
3810  if (log == NULL)
3811  {
3813  }
3814 
3815  if (log->handle == NULL)
3816  {
3817  return DLT_RETURN_ERROR;
3818  }
3819 
3820  if (log->handle->contextID[0] == '\0')
3821  {
3822  return DLT_RETURN_ERROR;
3823  }
3824 
3825  /* set userheader */
3827  {
3828  return DLT_RETURN_ERROR;
3829  }
3830 
3831  /* set usercontext */
3832  dlt_set_id(usercontext.apid,dlt_user.appID); /* application id */
3833  dlt_set_id(usercontext.ctid,log->handle->contextID); /* context id */
3834  usercontext.log_level_pos = log->handle->log_level_pos;
3835  usercontext.pid = getpid();
3836 
3837  usercontext.log_level = (int8_t)log->log_level;
3838  usercontext.trace_status = (int8_t)log->trace_status;
3839 
3840  if (log->context_description != NULL)
3841  {
3842  usercontext.description_length = strlen(log->context_description);
3843  }
3844  else
3845  {
3846  usercontext.description_length = 0;
3847  }
3848 
3849  if (dlt_user.dlt_is_file)
3850  {
3851  return DLT_RETURN_OK;
3852  }
3853 
3854  /* log to FIFO */
3855  if (dlt_user.appID[0]!='\0')
3856  {
3857  ret = dlt_user_log_out3(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgRegisterContext),log->context_description,usercontext.description_length);
3858  }
3859 
3860 
3861  /* store message in ringbuffer, if an error has occured */
3862  if ((ret != DLT_RETURN_OK) || (dlt_user.appID[0] == '\0'))
3863  {
3864  DLT_SEM_LOCK();
3865 
3866  if (dlt_buffer_push3(&(dlt_user.startup_buffer),
3867  (unsigned char *)&(userheader), sizeof(DltUserHeader),
3868  (const unsigned char*)&(usercontext), sizeof(DltUserControlMsgRegisterContext),
3869  (const unsigned char*)log->context_description, usercontext.description_length) == DLT_RETURN_ERROR)
3870  {
3871  dlt_log(LOG_WARNING,"Storing message to history buffer failed! Message discarded.\n");
3872  DLT_SEM_FREE();
3873  return DLT_RETURN_ERROR;
3874  }
3875 
3876  DLT_SEM_FREE();
3877 
3878  if ((dlt_user.appID[0] != '\0') && (dlt_user_queue_resend() < 0) && (dlt_user.dlt_log_handle >= 0))
3879  {
3880  ;//dlt_log(LOG_WARNING, "dlt_user_log_send_register_context: Failed to queue resending.\n");
3881  }
3882  }
3883 
3884  return DLT_RETURN_OK;
3885 
3886 }
3887 
3889 {
3890  DltUserHeader userheader;
3891  DltUserControlMsgUnregisterContext usercontext;
3892 
3893  if (log == NULL)
3894  {
3896  }
3897 
3898  if (log->handle == NULL)
3899  {
3901  }
3902 
3903  if (log->handle->contextID[0] == '\0')
3904  {
3905  return DLT_RETURN_ERROR;
3906  }
3907 
3908  /* set userheader */
3910  {
3911  return DLT_RETURN_ERROR;
3912  }
3913 
3914  /* set usercontext */
3915  dlt_set_id(usercontext.apid,dlt_user.appID); /* application id */
3916  dlt_set_id(usercontext.ctid,log->handle->contextID); /* context id */
3917  usercontext.pid = getpid();
3918 
3919  if (dlt_user.dlt_is_file)
3920  {
3921  return DLT_RETURN_OK;
3922  }
3923 
3924  /* log to FIFO */
3925  return dlt_user_log_out2(dlt_user.dlt_log_handle,
3926  &(userheader), sizeof(DltUserHeader),
3927  &(usercontext), sizeof(DltUserControlMsgUnregisterContext));
3928 }
3929 
3931 {
3932  DltUserHeader userheader;
3933  DltUserControlMsgAppLogLevelTraceStatus usercontext;
3934 
3935  if (loglevel < DLT_USER_LOG_LEVEL_NOT_SET || loglevel >= DLT_LOG_MAX)
3936  {
3937  dlt_vlog(LOG_ERR, "Loglevel %d is outside valid range", loglevel);
3938  return DLT_RETURN_ERROR;
3939  }
3940 
3941  if (tracestatus < DLT_USER_TRACE_STATUS_NOT_SET || tracestatus >= DLT_TRACE_STATUS_MAX)
3942  {
3943  dlt_vlog(LOG_ERR, "Tracestatus %d is outside valid range", tracestatus);
3944  return DLT_RETURN_ERROR;
3945  }
3946 
3947  if ((appid == NULL) || (appid[0]=='\0'))
3948  {
3949  return DLT_RETURN_ERROR;
3950  }
3951 
3952  /* Removed because of DltLogLevelType and DltTraceStatusType
3953 
3954  if ((loglevel<DLT_LOG_DEFAULT) || (loglevel>DLT_LOG_VERBOSE))
3955  {
3956  return DLT_RETURN_ERROR;
3957  }
3958 
3959  if ((tracestatus<DLT_TRACE_STATUS_DEFAULT) || (tracestatus>DLT_TRACE_STATUS_ON))
3960  {
3961  return DLT_RETURN_ERROR;
3962  }
3963 
3964  */
3965 
3966  /* set userheader */
3968  {
3969  return DLT_RETURN_ERROR;
3970  }
3971 
3972  /* set usercontext */
3973  dlt_set_id(usercontext.apid,appid); /* application id */
3974  usercontext.log_level = loglevel;
3975  usercontext.trace_status = tracestatus;
3976 
3977  if (dlt_user.dlt_is_file)
3978  {
3979  return DLT_RETURN_OK;
3980  }
3981 
3982  /* log to FIFO */
3983  return dlt_user_log_out2(dlt_user.dlt_log_handle,
3984  &(userheader), sizeof(DltUserHeader),
3985  &(usercontext), sizeof(DltUserControlMsgAppLogLevelTraceStatus));
3986 }
3987 
3989 {
3990  DltUserHeader userheader;
3991  DltUserControlMsgLogMode logmode;
3992 
3993  if (mode < DLT_USER_MODE_UNDEFINED || mode >= DLT_USER_MODE_MAX)
3994  {
3995  dlt_vlog(LOG_ERR, "User log mode %d is outside valid range", mode);
3997  }
3998 
3999  /* set userheader */
4001  {
4002  return DLT_RETURN_ERROR;
4003  }
4004 
4005  /* set data */
4006  logmode.log_mode = (unsigned char) mode;
4007 
4008  if (dlt_user.dlt_is_file)
4009  {
4010  return DLT_RETURN_OK;
4011  }
4012 
4013  /* log to FIFO */
4014  return dlt_user_log_out2(dlt_user.dlt_log_handle,
4015  &(userheader), sizeof(DltUserHeader),
4016  &(logmode), sizeof(DltUserControlMsgLogMode));
4017 }
4018 
4020 {
4021  DltUserHeader userheader;
4022 
4023  /* set userheader */
4025  {
4026  return DLT_RETURN_ERROR;
4027  }
4028 
4029  if (dlt_user.dlt_is_file)
4030  {
4031  return DLT_RETURN_OK;
4032  }
4033 
4034  /* log to FIFO */
4035  return dlt_user_log_out2(dlt_user.dlt_log_handle,
4036  &(userheader), sizeof(DltUserHeader), 0, 0);
4037 }
4038 
4040 {
4041  uint8_t *databuffer_tmp;
4042  int32_t datasize_tmp;
4043  int32_t databuffersize_tmp;
4044  static char text[DLT_USER_TEXT_LENGTH];
4045 
4046  if ((msg == NULL) || (log == NULL))
4047  {
4049  }
4050 
4051  /* Save variables before print */
4052  databuffer_tmp = msg->databuffer;
4053  datasize_tmp = msg->datasize;
4054  databuffersize_tmp = msg->databuffersize;
4055 
4056  /* Act like a receiver, convert header back to host format */
4057  msg->standardheader->len = DLT_BETOH_16(msg->standardheader->len);
4059 
4060  msg->databuffer = log->buffer;
4061  msg->datasize = log->size;
4062  msg->databuffersize = log->size;
4063 
4064  /* Print message as ASCII */
4066  {
4067  return DLT_RETURN_ERROR;
4068  }
4069 
4070  /* Restore variables and set len to BE*/
4071  msg->databuffer = databuffer_tmp;
4072  msg->databuffersize = databuffersize_tmp;
4073  msg->datasize = datasize_tmp;
4074 
4075  msg->standardheader->len = DLT_HTOBE_16(msg->standardheader->len);
4076 
4077  return DLT_RETURN_OK;
4078 }
4079 
4081 {
4082  int offset=0;
4083  int leave_while=0;
4084 
4085  uint32_t i;
4086 
4087  DltUserHeader *userheader;
4088  DltReceiver *receiver = &(dlt_user.receiver);
4089 
4090  DltUserControlMsgLogLevel *usercontextll;
4091  DltUserControlMsgInjection *usercontextinj;
4092  DltUserControlMsgLogState *userlogstate;
4093  unsigned char *userbuffer;
4094 
4095  /* For delayed calling of injection callback, to avoid deadlock */
4096  DltUserInjectionCallback delayed_injection_callback;
4097  DltUserLogLevelChangedCallback delayed_log_level_changed_callback;
4098  unsigned char *delayed_inject_buffer = 0;
4099  uint32_t delayed_inject_data_length = 0;
4100 
4101  /* Ensure that callback is null before searching for it */
4102  delayed_injection_callback.injection_callback = 0;
4103  delayed_injection_callback.service_id = 0;
4104  delayed_log_level_changed_callback.log_level_changed_callback = 0;
4105 
4106  if (dlt_user.dlt_user_handle!=DLT_FD_INIT)
4107  {
4108  while (1)
4109  {
4110  if (dlt_receiver_receive_fd(receiver)<=0)
4111  {
4112  /* No new message available */
4113  return DLT_RETURN_OK;
4114  }
4115 
4116  /* look through buffer as long as data is in there */
4117  while (1)
4118  {
4119  if (receiver->bytesRcvd < (int32_t)sizeof(DltUserHeader))
4120  {
4121  break;
4122  }
4123 
4124  /* resync if necessary */
4125  offset=0;
4126  do
4127  {
4128  userheader = (DltUserHeader*) (receiver->buf+offset);
4129 
4130  /* Check for user header pattern */
4131  if (dlt_user_check_userheader(userheader))
4132  {
4133  break;
4134  }
4135  offset++;
4136 
4137  }
4138  while ((int32_t)(sizeof(DltUserHeader)+offset)<=receiver->bytesRcvd);
4139 
4140  /* Check for user header pattern */
4141  if (dlt_user_check_userheader(userheader)<0 ||
4142  dlt_user_check_userheader(userheader)==0)
4143  {
4144  break;
4145  }
4146 
4147  /* Set new start offset */
4148  if (offset>0)
4149  {
4150  receiver->buf+=offset;
4151  receiver->bytesRcvd-=offset;
4152  }
4153 
4154  switch (userheader->message)
4155  {
4157  {
4158  if (receiver->bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogLevel)))
4159  {
4160  leave_while=1;
4161  break;
4162  }
4163 
4164  usercontextll = (DltUserControlMsgLogLevel*) (receiver->buf+sizeof(DltUserHeader));
4165 
4166  /* Update log level and trace status */
4167  if (usercontextll != NULL)
4168  {
4169  DLT_SEM_LOCK();
4170 
4171  if ((usercontextll->log_level_pos >= 0) &&
4172  (usercontextll->log_level_pos < (int32_t)dlt_user.dlt_ll_ts_num_entries))
4173  {
4174  // printf("Store ll, ts\n");
4175  if (dlt_user.dlt_ll_ts)
4176  {
4177  dlt_user.dlt_ll_ts[usercontextll->log_level_pos].log_level = usercontextll->log_level;
4178  dlt_user.dlt_ll_ts[usercontextll->log_level_pos].trace_status = usercontextll->trace_status;
4179  if(dlt_user.dlt_ll_ts[usercontextll->log_level_pos].log_level_ptr)
4180  *(dlt_user.dlt_ll_ts[usercontextll->log_level_pos].log_level_ptr) = usercontextll->log_level;
4181  if(dlt_user.dlt_ll_ts[usercontextll->log_level_pos].trace_status_ptr)
4182  *(dlt_user.dlt_ll_ts[usercontextll->log_level_pos].trace_status_ptr) = usercontextll->trace_status;
4183 
4184  delayed_log_level_changed_callback.log_level_changed_callback = dlt_user.dlt_ll_ts[usercontextll->log_level_pos].log_level_changed_callback;
4185  memcpy(delayed_log_level_changed_callback.contextID,dlt_user.dlt_ll_ts[usercontextll->log_level_pos].contextID,DLT_ID_SIZE);
4186  delayed_log_level_changed_callback.log_level = usercontextll->log_level;
4187  delayed_log_level_changed_callback.trace_status = usercontextll->trace_status;
4188  }
4189  }
4190 
4191  DLT_SEM_FREE();
4192  }
4193 
4194  /* call callback outside of semaphore */
4195  if(delayed_log_level_changed_callback.log_level_changed_callback!=0)
4196  {
4197  delayed_log_level_changed_callback.log_level_changed_callback(delayed_log_level_changed_callback.contextID,
4198  delayed_log_level_changed_callback.log_level,
4199  delayed_log_level_changed_callback.trace_status);
4200  }
4201 
4202  /* keep not read data in buffer */
4203  if (dlt_receiver_remove(receiver,sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogLevel)) == DLT_RETURN_ERROR)
4204  {
4205  return DLT_RETURN_ERROR;
4206  }
4207  }
4208  break;
4210  {
4211  /* At least, user header, user context, and service id and data_length of injected message is available */
4212  if (receiver->bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgInjection)))
4213  {
4214  leave_while = 1;
4215  break;
4216  }
4217 
4218  usercontextinj = (DltUserControlMsgInjection*) (receiver->buf+sizeof(DltUserHeader));
4219  userbuffer = (unsigned char*) (receiver->buf+sizeof(DltUserHeader)+sizeof(DltUserControlMsgInjection));
4220 
4221  if (userbuffer != NULL)
4222  {
4223 
4224  if (receiver->bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgInjection)+usercontextinj->data_length_inject))
4225  {
4226  leave_while = 1;
4227  break;
4228  }
4229 
4230  DLT_SEM_LOCK();
4231 
4232  if ((usercontextinj->data_length_inject>0) && (dlt_user.dlt_ll_ts))
4233  {
4234  /* Check if injection callback is registered for this context */
4235  for (i=0; i<dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].nrcallbacks;i++)
4236  {
4237  if ((dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table) &&
4238  (dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table[i].service_id == usercontextinj->service_id))
4239  {
4240  /* Prepare delayed injection callback call */
4241  if (dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table[i].injection_callback!=0)
4242  {
4243  delayed_injection_callback.injection_callback = dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table[i].injection_callback;
4244  delayed_injection_callback.service_id = usercontextinj->service_id;
4245  delayed_inject_data_length = usercontextinj->data_length_inject;
4246  delayed_inject_buffer = malloc(delayed_inject_data_length);
4247 
4248  if(delayed_inject_buffer != NULL)
4249  memcpy(delayed_inject_buffer, userbuffer, delayed_inject_data_length);
4250  }
4251  break;
4252  }
4253  }
4254  }
4255 
4256  DLT_SEM_FREE();
4257 
4258  /* Delayed injection callback call */
4259  if(delayed_inject_buffer != NULL && delayed_injection_callback.injection_callback != 0)
4260  {
4261  delayed_injection_callback.injection_callback(delayed_injection_callback.service_id, delayed_inject_buffer, delayed_inject_data_length);
4262  delayed_injection_callback.injection_callback = 0;
4263  free(delayed_inject_buffer);
4264  delayed_inject_buffer = NULL;
4265 
4266  }
4267 
4268  /* keep not read data in buffer */
4269  if (dlt_receiver_remove(receiver,(sizeof(DltUserHeader)+sizeof(DltUserControlMsgInjection)+usercontextinj->data_length_inject)) == DLT_RETURN_ERROR)
4270  return DLT_RETURN_ERROR;
4271  }
4272  }
4273  break;
4275  {
4276  /* At least, user header, user context, and service id and data_length of injected message is available */
4277  if (receiver->bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogState)))
4278  {
4279  leave_while = 1;
4280  break;
4281  }
4282 
4283  userlogstate = (DltUserControlMsgLogState*) (receiver->buf+sizeof(DltUserHeader));
4284  dlt_user.log_state = userlogstate->log_state;
4285 
4286  /* keep not read data in buffer */
4287  if (dlt_receiver_remove(receiver,(sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogState))) == DLT_RETURN_ERROR)
4288  {
4289  return DLT_RETURN_ERROR;
4290  }
4291  }
4292  break;
4293  default:
4294  {
4295  dlt_log(LOG_WARNING,"Invalid user message type received!\n");
4296  /* Ignore result */
4297  dlt_receiver_remove(receiver,sizeof(DltUserHeader));
4298  /* In next invocation of while loop, a resync will be triggered if additional data was received */
4299  }
4300  break;
4301  } /* switch() */
4302 
4303  if (leave_while==1)
4304  {
4305  leave_while=0;
4306  break;
4307  }
4308 
4309  } /* while buffer*/
4310 
4312  {
4313  return DLT_RETURN_ERROR;
4314  }
4315  } /* while receive */
4316  } /* if */
4317 
4318  return DLT_RETURN_OK;
4319 }
4320 
4322 {
4323  int num,count;
4324  int size;
4325  DltReturnValue ret;
4326 
4327  if (dlt_user.appID[0]=='\0')
4328  {
4329  return 0;
4330  }
4331 
4332  /* Send content of ringbuffer */
4333  DLT_SEM_LOCK();
4334  count = dlt_buffer_get_message_count(&(dlt_user.startup_buffer));
4335  DLT_SEM_FREE();
4336 
4337  for (num=0;num<count;num++)
4338  {
4339 
4340  DLT_SEM_LOCK();
4341  size = dlt_buffer_copy(&(dlt_user.startup_buffer),dlt_user.resend_buffer,sizeof(dlt_user.resend_buffer));
4342 
4343  if (size>0)
4344  {
4345  DltUserHeader *userheader = (DltUserHeader*) (dlt_user.resend_buffer);
4346  /* Add application id to the messages of needed*/
4347  if (dlt_user_check_userheader(userheader))
4348  {
4349  switch (userheader->message)
4350  {
4352  {
4353  DltUserControlMsgRegisterContext *usercontext = (DltUserControlMsgRegisterContext*) (dlt_user.resend_buffer+sizeof(DltUserHeader));
4354  if ((usercontext != 0) && (usercontext->apid[0]=='\0'))
4355  {
4356  dlt_set_id(usercontext->apid,dlt_user.appID);
4357  }
4358  break;
4359  }
4360  case DLT_USER_MESSAGE_LOG:
4361  {
4362  DltExtendedHeader * extendedHeader = (DltExtendedHeader *)(dlt_user.resend_buffer+sizeof(DltUserHeader)+
4363  sizeof(DltStandardHeader)+sizeof(DltStandardHeaderExtra));
4364  if ((extendedHeader) != 0 && (extendedHeader->apid[0]=='\0'))
4365  { // if application id is empty, add it
4366  dlt_set_id(extendedHeader->apid,dlt_user.appID);
4367  }
4368  break;
4369  }
4370  default:
4371  {
4372  break;
4373  }
4374  }
4375  }
4376 
4377 #ifdef DLT_SHM_ENABLE
4378  dlt_shm_push(&dlt_user.dlt_shm, dlt_user.resend_buffer+sizeof(DltUserHeader), size-sizeof(DltUserHeader), 0, 0, 0, 0);
4379 
4380  /* log to FIFO */
4381  ret = dlt_user_log_out3(dlt_user.dlt_log_handle, dlt_user.resend_buffer,sizeof(DltUserHeader), 0, 0, 0, 0);
4382 #else
4383  /* log to FIFO */
4384  ret = dlt_user_log_out3(dlt_user.dlt_log_handle, dlt_user.resend_buffer,size, 0, 0, 0, 0);
4385 #endif
4386 
4387  /* in case of error, keep message in ringbuffer */
4388  if (ret == DLT_RETURN_OK)
4389  {
4390  dlt_buffer_remove(&(dlt_user.startup_buffer));
4391  }
4392  else
4393  {
4394  /* keep message in ringbuffer */
4395  DLT_SEM_FREE();
4396  return ret;
4397  }
4398  }
4399  DLT_SEM_FREE();
4400  }
4401 
4402  return DLT_RETURN_OK;
4403 }
4404 
4406 {
4407  uint32_t num, reregistered = 0;
4408 
4409  DltContext handle;
4410  DltContextData log_new;
4411 
4412  if (dlt_user.dlt_log_handle<0)
4413  {
4414  dlt_user.dlt_log_handle=-1;
4415 
4416  /* try to open pipe to dlt daemon */
4417  dlt_user.dlt_log_handle = open(dlt_daemon_fifo, O_WRONLY | O_NONBLOCK);
4418  if (dlt_user.dlt_log_handle > 0)
4419  {
4420  if (dlt_user_log_init(&handle,&log_new) < DLT_RETURN_OK)
4421  {
4422  return;
4423  }
4424 
4425 #ifdef DLT_SHM_ENABLE
4426  /* init shared memory */
4427  if (dlt_shm_init_client(&dlt_user.dlt_shm,DLT_SHM_KEY) < 0)
4428  {
4429  dlt_vnlog(LOG_WARNING, DLT_USER_BUFFER_LENGTH, "Loging disabled, Shared memory %d cannot be created!\n", DLT_SHM_KEY);
4430  //return DLT_RETURN_OK;
4431  }
4432 #endif
4433 
4434  dlt_log(LOG_NOTICE, "Logging (re-)enabled!\n");
4435 
4436  /* Re-register application */
4438  {
4439  return;
4440  }
4441 
4442  DLT_SEM_LOCK();
4443 
4444  /* Re-register all stored contexts */
4445  for (num=0; num<dlt_user.dlt_ll_ts_num_entries; num++)
4446  {
4447  /* Re-register stored context */
4448  if ((dlt_user.appID[0]!='\0') && (dlt_user.dlt_ll_ts) && (dlt_user.dlt_ll_ts[num].contextID[0]!='\0'))
4449  {
4450  //dlt_set_id(log_new.appID, dlt_user.appID);
4451  dlt_set_id(handle.contextID, dlt_user.dlt_ll_ts[num].contextID);
4452  handle.log_level_pos = num;
4453  log_new.context_description = dlt_user.dlt_ll_ts[num].context_description;
4454 
4455  // Release the mutex for sending context registration:
4456  // function dlt_user_log_send_register_context() can take the mutex to write to the DLT buffer. => dead lock
4457  DLT_SEM_FREE();
4458 
4461 
4463  {
4464  return;
4465  }
4466 
4467  reregistered=1;
4468 
4469  // Lock again the mutex
4470  // it is necessary in the for(;;) test, in order to have coherent dlt_user data all over the critical section.
4471  DLT_SEM_LOCK();
4472 
4473  }
4474  }
4475 
4476  DLT_SEM_FREE();
4477 
4478  if (reregistered==1)
4479  {
4481  }
4482  }
4483  }
4484 }
4485 
4487 {
4488  DltUserHeader userheader;
4489  DltUserControlMsgBufferOverflow userpayload;
4490 
4491  /* set userheader */
4493  {
4494  return DLT_RETURN_ERROR;
4495  }
4496 
4497  if (dlt_user.dlt_is_file)
4498  {
4499  return DLT_RETURN_OK;
4500  }
4501 
4502  /* set user message parameters */
4503  userpayload.overflow_counter = dlt_user.overflow_counter;
4504  dlt_set_id(userpayload.apid,dlt_user.appID);
4505 
4506  /* log to FIFO */
4507  return dlt_user_log_out2(dlt_user.dlt_log_handle,
4508  &(userheader), sizeof(DltUserHeader),
4509  &(userpayload), sizeof(DltUserControlMsgBufferOverflow));
4510 }
4511 
4512 DltReturnValue dlt_user_check_buffer(int *total_size, int *used_size)
4513 {
4514  if(total_size == NULL || used_size == NULL)
4516 
4517  DLT_SEM_LOCK();
4518 
4519 #ifdef DLT_SHM_ENABLE
4520  *total_size = dlt_shm_get_total_size(&(dlt_user.dlt_shm));
4521  *used_size = dlt_shm_get_used_size(&(dlt_user.dlt_shm));
4522 #else
4523  *total_size = dlt_buffer_get_total_size(&(dlt_user.startup_buffer));
4524  *used_size = dlt_buffer_get_used_size(&(dlt_user.startup_buffer));
4525 #endif
4526 
4527  DLT_SEM_FREE();
4528  return DLT_RETURN_OK; /* ok */
4529 }
4530 
4531 #ifdef DLT_TEST_ENABLE
4532 void dlt_user_test_corrupt_user_header(int enable)
4533 {
4534  dlt_user.corrupt_user_header = enable;
4535 }
4536 void dlt_user_test_corrupt_message_size(int enable,int16_t size)
4537 {
4538  dlt_user.corrupt_message_size = enable;
4539  dlt_user.corrupt_message_size_size = size;
4540 }
4541 #endif
4542 
4543 
4545 {
4546  /* Start receiver thread */
4547  if (pthread_create(&(dlt_receiverthread_handle),
4548  0,
4550  0) != 0)
4551  {
4552  dlt_log(LOG_CRIT, "Can't create receiver thread!\n");
4553  return -1;
4554  }
4555 
4556  /* Start the segmented thread */
4557  if (pthread_create(&(dlt_user.dlt_segmented_nwt_handle), NULL,
4559  {
4560  dlt_log(LOG_CRIT, "Can't start segmented thread!\n");
4561  return -1;
4562  }
4563 
4564  return 0;
4565 }
4566 
4568 {
4569  int dlt_receiverthread_result = 0;
4570  int dlt_segmented_nwt_result = 0;
4572  {
4573  /* do not ignore return value */
4574  dlt_receiverthread_result = pthread_cancel(dlt_receiverthread_handle);
4575  if (dlt_receiverthread_result != 0)
4576  {
4577  snprintf(str, DLT_USER_BUFFER_LENGTH,
4578  "ERROR pthread_cancel(dlt_receiverthread_handle): %s\n",
4579  strerror(errno));
4580  dlt_log(LOG_ERR, str);
4581  }
4582  }
4583 
4584  if (dlt_user.dlt_segmented_nwt_handle)
4585  {
4586  dlt_segmented_nwt_result = pthread_cancel(dlt_user.dlt_segmented_nwt_handle);
4587  if (dlt_segmented_nwt_result != 0)
4588  {
4589  snprintf(str, DLT_USER_BUFFER_LENGTH,
4590  "ERROR pthread_cancel(dlt_user.dlt_segmented_nwt_handle): %s\n",
4591  strerror(errno));
4592  dlt_log(LOG_ERR, str);
4593  }
4594  }
4595 
4596  /* make sure that the threads really finished working */
4597  if ((dlt_receiverthread_result == 0) && dlt_receiverthread_handle)
4598  {
4599  int joined = pthread_join(dlt_receiverthread_handle, NULL);
4600  if (joined < 0)
4601  {
4602  snprintf(str, DLT_USER_BUFFER_LENGTH,
4603  "ERROR pthread_join(dlt_receiverthread_handle, NULL): %s\n",
4604  strerror(errno));
4605  dlt_log(LOG_ERR, str);
4606  }
4607  dlt_receiverthread_handle = 0; /* set to invalid */
4608  }
4609 
4610  if ((dlt_segmented_nwt_result == 0) && dlt_user.dlt_segmented_nwt_handle)
4611  {
4612  int joined = pthread_join(dlt_user.dlt_segmented_nwt_handle, NULL);
4613  if (joined < 0)
4614  {
4615  snprintf(str, DLT_USER_BUFFER_LENGTH,
4616  "ERROR pthread_join(dlt_user.dlt_segmented_nwt_handle, NULL): %s\n",
4617  strerror(errno));
4618  dlt_log(LOG_ERR, str);
4619  }
4620  dlt_user.dlt_segmented_nwt_handle = 0; /* set to invalid */
4621  }
4622 }
4623 
4625 {
4626  dlt_stop_threads();
4627 }
4628 
4630 {
4632  {
4633  if (dlt_start_threads() < 0)
4634  {
4635  snprintf(str, DLT_USER_BUFFER_LENGTH,
4636  "Logging disabled, failed re-start thread after fork(pid=%i)!\n",
4637  getpid());
4638  dlt_log(LOG_WARNING, str);
4639  /* cleanup is the only thing we can do here */
4640  dlt_log_free();
4641  dlt_free();
4642  }
4643  }
4644 }
4645 
4647 {
4649  {
4650  /* don't start anything else but cleanup everything and avoid blow-out of buffers*/
4651  dlt_log_free();
4652  dlt_free();
4653  /* the only thing that remains is the atexit-handler */
4654  }
4655 }
int32_t datasize
Definition: dlt_common.h:423
static int dlt_start_threads()
Definition: dlt_user.c:4544
void dlt_lock_mutex(pthread_mutex_t *mutex)
Definition: dlt_user.c:106
int dlt_set_resend_timeout_atexit(uint32_t timeout_in_milliseconds)
Definition: dlt_user.c:1301
#define DLT_USER_MESSAGE_LOG_MODE
#define DLT_HTYP_UEH
Definition: dlt_protocol.h:82
DltReturnValue dlt_user_log_write_float32(DltContextData *log, float32_t data)
Definition: dlt_user.c:1559
#define DLT_SCOD_UTF8
Definition: dlt_protocol.h:169
int8_t trace_status
Definition: dlt_user.h:148
DltReturnValue dlt_buffer_init_dynamic(DltBuffer *buf, uint32_t min_size, uint32_t max_size, uint32_t step_size)
Definition: dlt_common.c:2430
DltNetworkTraceType
Definition: dlt_types.h:145
#define DLT_USER_MESSAGE_UNREGISTER_APPLICATION
DltReturnValue dlt_user_log_write_int16(DltContextData *log, int16_t data)
Definition: dlt_user.c:2140
static void dlt_fork_child_fork_handler()
Definition: dlt_user.c:4646
DltReturnValue dlt_user_log_write_string(DltContextData *log, const char *text)
Definition: dlt_user.c:2280
DltLogLevelType
Definition: dlt_types.h:102
#define DLT_USER_MESSAGE_REGISTER_APPLICATION
int dlt_user_atexit_blow_out_user_buffer(void)
Definition: dlt_user.c:621
dlt_ll_ts_type * dlt_ll_ts
Definition: dlt_user.h:196
#define DLT_USER_CONTEXT_ALLOC_SIZE
Definition: dlt_user_cfg.h:93
DltReturnValue dlt_verbose_mode(void)
Definition: dlt_user.c:3178
#define DLT_ID_SIZE
Definition: dlt_common.h:204
#define DLT_USER_MESSAGE_MARKER
#define DLT_TYPE_INFO_SINT
Definition: dlt_protocol.h:150
#define DLT_HTOBE_16(x)
Definition: dlt_common.h:148
int check_buffer(void)
Definition: dlt_user.c:2501
DltStorageHeader * storageheader
Definition: dlt_common.h:432
uint32_t dlt_buffer_get_total_size(DltBuffer *buf)
Definition: dlt_common.c:2943
static DltReturnValue dlt_user_log_check_user_message(void)
Definition: dlt_user.c:4080
void(* log_level_changed_callback)(char context_id[DLT_ID_SIZE], uint8_t log_level, uint8_t trace_status)
Definition: dlt_user.h:137
static DltUser dlt_user
Definition: dlt_user.c:78
DltReturnValue
Definition: dlt_types.h:86
void dlt_check_envvar()
Definition: dlt_common.c:3867
int dlt_shm_get_total_size(DltShm *buf)
Definition: dlt_shm.c:193
DltReturnValue dlt_init_common(void)
Definition: dlt_user.c:443
#define DLT_USER_ENV_BUFFER_MAX_SIZE
Definition: dlt_user_cfg.h:85
#define DLT_USER_MESSAGE_LOG_LEVEL
#define DLT_TYLE_32BIT
Definition: dlt_protocol.h:164
static void dlt_fork_pre_fork_handler()
Definition: dlt_user.c:4624
#define DLT_HTYP_PROTOCOL_VERSION1
Definition: dlt_protocol.h:95
DltReturnValue dlt_user_log_write_int(DltContextData *log, int data)
Definition: dlt_user.c:2062
#define DLT_MESSAGE_QUEUE_NAME
Definition: dlt_user.c:99
mqd_t dlt_segmented_queue_read_handle
Definition: dlt_user.h:190
#define DLT_SEM_LOCK()
Definition: dlt_user.h:97
void dlt_get_minor_version(char *buf, size_t size)
Definition: dlt_common.c:3262
void dlt_set_id(char *id, const char *text)
Definition: dlt_common.c:324
DltReturnValue dlt_unregister_app(void)
Definition: dlt_user.c:1118
#define DLT_USER_MESSAGE_INJECTION
pthread_t dlt_segmented_nwt_handle
Definition: dlt_user.h:192
DltReturnValue dlt_register_context_ll_ts(DltContext *handle, const char *contextid, const char *description, int loglevel, int tracestatus)
Definition: dlt_user.c:911
#define DLT_HTYP_WEID
Definition: dlt_protocol.h:84
#define DLT_USER_RINGBUFFER_MAX_SIZE
Definition: dlt_user_cfg.h:80
#define DLT_USER_MESSAGE_OVERFLOW
static int dlt_user_freeing
Definition: dlt_user.c:80
#define DLT_USER_RECEIVE_DELAY
Definition: dlt_user_cfg.h:132
DltReturnValue dlt_user_log_out2(int handle, void *ptr1, size_t len1, void *ptr2, size_t len2)
uint32_t payload_len
Definition: dlt_user.c:134
DltContext * handle
Definition: dlt_user.h:117
#define DLT_USER_ENV_BUFFER_STEP_SIZE
Definition: dlt_user_cfg.h:86
DltReturnValue dlt_free(void)
Definition: dlt_user.c:676
DltTraceStatusType
Definition: dlt_types.h:133
DltUserLogMode
Definition: dlt_types.h:168
void dlt_log_free(void)
Definition: dlt_common.c:2022
DltReturnValue dlt_register_app(const char *appid, const char *description)
Definition: dlt_user.c:800
DltReturnValue dlt_user_trace_network_segmented_end(uint32_t id, DltContext *handle, DltNetworkTraceType nw_trace_type)
Definition: dlt_user.c:2635
#define DLT_STANDARD_HEADER_EXTRA_SIZE(htyp)
Definition: dlt_common.h:213
#define DLT_PM_FORCE_ON
Definition: dlt_user_cfg.h:154
Definition: dlt_shm.h:78
DltReturnValue dlt_buffer_free_dynamic(DltBuffer *buf)
Definition: dlt_common.c:2494
int dlt_user_handle
Definition: dlt_user.h:189
DltReturnValue dlt_register_context(DltContext *handle, const char *contextid, const char *description)
Definition: dlt_user.c:883
DltReturnValue dlt_user_log_out3(int handle, void *ptr1, size_t len1, void *ptr2, size_t len2, void *ptr3, size_t len3)
DltReturnValue dlt_user_log_write_uint64_formatted(DltContextData *log, uint64_t data, DltFormatType type)
Definition: dlt_user.c:1978
DltReturnValue dlt_receiver_remove(DltReceiver *receiver, int size)
Definition: dlt_common.c:2232
char * buf
Definition: dlt_common.h:678
DltReturnValue dlt_use_extended_header_for_non_verbose(int8_t use_extende_header_for_non_verbose)
Definition: dlt_user.c:3212
DltReturnValue dlt_user_log_write_int32(DltContextData *log, int32_t data)
Definition: dlt_user.c:2175
static DltReturnValue dlt_send_app_ll_ts_limit(const char *appid, DltLogLevelType loglevel, DltTraceStatusType tracestatus)
Definition: dlt_user.c:3930
int8_t with_timestamp
Definition: dlt_user.h:212
#define DLT_USER_MAX_LIB_VERSION_LENGTH
Definition: dlt_user_cfg.h:99
DltReturnValue dlt_with_session_id(int8_t with_session_id)
Definition: dlt_user.c:3229
char contextID[DLT_ID_SIZE]
Definition: dlt_user.h:134
DltReturnValue dlt_log(int prio, char *s)
Definition: dlt_common.c:2029
int dlt_user_check_userheader(DltUserHeader *userheader)
int dlt_env_adjust_ll_from_env(dlt_env_ll_set const *const ll_set, char const *const apid, char const *const ctid, int const ll)
adjust log-level based on values given through environment
Definition: dlt_env_ll.c:537
static DltReturnValue dlt_user_log_send_unregister_context(DltContextData *log)
Definition: dlt_user.c:3888
int(* injection_callback)(uint32_t service_id, void *data, uint32_t length)
Definition: dlt_user.h:129
DltReturnValue dlt_user_log_write_uint16_formatted(DltContextData *log, uint16_t data, DltFormatType type)
Definition: dlt_user.c:1874
DltContext * handle
Definition: dlt_user.c:129
DltReturnValue dlt_init_file(const char *name)
Definition: dlt_user.c:350
int8_t overflow
Definition: dlt_user.h:202
int dlt_receiver_receive_fd(DltReceiver *receiver)
Definition: dlt_common.c:2203
int dlt_shm_push(DltShm *buf, const unsigned char *data1, unsigned int size1, const unsigned char *data2, unsigned int size2, const unsigned char *data3, unsigned int size3)
Definition: dlt_shm.c:218
static DltReturnValue dlt_user_log_send_unregister_application(void)
Definition: dlt_user.c:3773
uint32_t dlt_ll_ts_max_num_entries
Definition: dlt_user.h:198
mqd_t dlt_segmented_queue_write_handle
Definition: dlt_user.h:191
DltReturnValue dlt_enable_local_print(void)
Definition: dlt_user.c:3280
char * context_description
Definition: dlt_user.h:150
DltReturnValue dlt_message_init(DltMessage *msg, int verbose)
Definition: dlt_common.c:666
DltReturnValue dlt_register_log_level_changed_callback(DltContext *handle, void(*dlt_log_level_changed_callback)(char context_id[DLT_ID_SIZE], uint8_t log_level, uint8_t trace_status))
Definition: dlt_user.c:2463
#define DLT_HTYP_MSBF
Definition: dlt_protocol.h:83
int32_t bytesRcvd
Definition: dlt_common.h:675
int32_t trace_status
Definition: dlt_user.h:121
DltReturnValue dlt_receiver_move_to_begin(DltReceiver *receiver)
Definition: dlt_common.c:2257
double float64_t
Definition: dlt_types.h:179
static DltReturnValue dlt_user_log_send_register_context(DltContextData *log)
Definition: dlt_user.c:3804
static void dlt_user_trace_network_segmented_thread(void *unused)
Definition: dlt_user.c:2673
DltExtendedHeader * extendedheader
Definition: dlt_common.h:435
DltReturnValue dlt_user_trace_network_segmented_start(uint32_t *id, DltContext *handle, DltNetworkTraceType nw_trace_type, uint16_t header_len, void *header, uint16_t payload_len)
Definition: dlt_user.c:2513
#define DLT_USER_MESSAGE_REGISTER_CONTEXT
static int atfork_registered
Definition: dlt_user.c:94
uint32_t header_len
Definition: dlt_user.c:132
#define DLT_USER_ATEXIT_RESEND_BUFFER_SLEEP
Definition: dlt_user_cfg.h:141
#define DLT_DELAYED_RESEND_INDICATOR_PATTERN
Definition: dlt_user.c:100
pthread_mutex_t mq_mutex
Definition: dlt_user.c:103
uint32_t overflow_counter
Definition: dlt_user.h:203
int32_t log_level
Definition: dlt_user.h:120
DltReturnValue dlt_message_print_ascii(DltMessage *message, char *text, uint32_t size, int verbose)
Definition: dlt_common.c:3325
int dlt_env_extract_ll_set(char **const env, dlt_env_ll_set *const ll_set)
extract all items out of string
Definition: dlt_env_ll.c:408
char * application_description
Definition: dlt_user.h:205
#define DLT_USER_MESSAGE_UNREGISTER_CONTEXT
#define DLT_PM_FORCE_OFF
Definition: dlt_user_cfg.h:155
int dlt_get_log_state()
Definition: dlt_user.c:1276
dlt_env_ll_set initial_ll_set
Definition: dlt_user.h:228
static DltReturnValue dlt_user_log_send_register_application(void)
Definition: dlt_user.c:3705
#define DLT_USER_RINGBUFFER_MIN_SIZE
Definition: dlt_user_cfg.h:79
#define DLT_MSIN_MTIN
Definition: dlt_protocol.h:102
#define DLT_TYLE_16BIT
Definition: dlt_protocol.h:163
int dlt_buffer_copy(DltBuffer *buf, unsigned char *data, int max_size)
Definition: dlt_common.c:2889
uint32_t timeout_at_exit_handler
Definition: dlt_user.h:227
static void dlt_user_log_reattach_to_daemon(void)
Definition: dlt_user.c:4405
static DltReturnValue dlt_user_log_send_log_mode(DltUserLogMode mode)
Definition: dlt_user.c:3988
static char * service_id[]
Definition: dlt_common.c:85
DltReturnValue dlt_check_library_version(const char *user_major_version, const char *user_minor_version)
Definition: dlt_user.c:795
int dlt_buffer_get_used_size(DltBuffer *buf)
Definition: dlt_common.c:2952
DltFormatType
Definition: dlt_types.h:118
DltReturnValue dlt_message_set_extraparameters(DltMessage *msg, int verbose)
Definition: dlt_common.c:1273
DltReturnValue dlt_log_uint(DltContext *handle, DltLogLevelType loglevel, unsigned int data)
Definition: dlt_user.c:3092
static char data[kDataSize]
Definition: city-test.cc:40
#define DLT_MSIN_MTIN_SHIFT
Definition: dlt_protocol.h:105
DltReturnValue dlt_user_log_write_raw_formatted(DltContextData *log, void *data, uint16_t length, DltFormatType type)
Definition: dlt_user.c:1495
uint8_t resend_buffer[DLT_USER_RESENDBUF_MAX_SIZE]
Definition: dlt_user.h:225
static char dlt_daemon_fifo[NAME_MAX+1]
Definition: dlt_user.c:83
static void dlt_fork_parent_fork_handler()
Definition: dlt_user.c:4629
int8_t log_state
Definition: dlt_user.h:218
char * nw_trace_type[]
Definition: dlt_common.c:83
int8_t log_level
Definition: dlt_user.h:146
static DltReturnValue dlt_user_log_init(DltContext *handle, DltContextData *log)
Definition: dlt_user.c:3332
DltReturnValue dlt_set_storageheader(DltStorageHeader *storageheader, const char *ecu)
Definition: dlt_common.c:2315
int32_t databuffersize
Definition: dlt_common.h:429
int8_t enable_local_print
Definition: dlt_user.h:215
DltReturnValue dlt_receiver_init(DltReceiver *receiver, int fd, int buffersize)
Definition: dlt_common.c:2126
DltReturnValue dlt_user_log_write_ptr(DltContextData *log, void *data)
Definition: dlt_user.c:2030
DltReturnValue dlt_shm_init_client(DltShm *buf, int key)
Definition: dlt_shm.c:144
#define DLT_IS_HTYP_UEH(htyp)
Definition: dlt_protocol.h:89
void(* log_level_changed_callback)(char context_id[DLT_ID_SIZE], uint8_t log_level, uint8_t trace_status)
Definition: dlt_user.h:155
static void dlt_user_atexit_handler(void)
Definition: dlt_user.c:596
static void dlt_stop_threads()
Definition: dlt_user.c:4567
DltReturnValue dlt_user_log_write_utf8_string(DltContextData *log, const char *text)
Definition: dlt_user.c:2332
#define DLT_USER_TEXT_LENGTH
Definition: dlt_user_cfg.h:102
DltReturnValue dlt_user_check_buffer(int *total_size, int *used_size)
Definition: dlt_user.c:4512
#define DLT_HTYP_WTMS
Definition: dlt_protocol.h:86
#define DLT_TYPE_NW_TRACE
Definition: dlt_protocol.h:116
DltReturnValue dlt_user_log_write_int64(DltContextData *log, int64_t data)
Definition: dlt_user.c:2210
int8_t * log_level_ptr
Definition: dlt_user.h:147
DltReturnValue dlt_user_trace_network_segmented_segment(uint32_t id, DltContext *handle, DltNetworkTraceType nw_trace_type, int sequence, uint16_t payload_len, void *payload)
Definition: dlt_user.c:2581
int dlt_mkdir_recursive(const char *dir)
Definition: dlt_common.c:3905
DltReturnValue dlt_init(void)
Definition: dlt_user.c:188
#define DLT_BETOH_16(x)
Definition: dlt_common.h:150
DltReturnValue dlt_user_log_write_uint8(DltContextData *log, uint8_t data)
Definition: dlt_user.c:1682
uint32_t dlt_uptime(void)
Definition: dlt_common.c:3274
int dlt_shm_get_used_size(DltShm *buf)
Definition: dlt_shm.c:198
int8_t dlt_is_file
Definition: dlt_user.h:194
#define DLT_USER_ATEXIT_RESEND_BUFFER_EXIT_TIMEOUT
Definition: dlt_user_cfg.h:138
#define DLT_USER_DEFAULT_ECU_ID
Definition: dlt_user_cfg.h:108
#define DLT_PM_UNSET
Definition: dlt_user_cfg.h:152
int8_t local_print_mode
Definition: dlt_user.h:216
int32_t headersize
Definition: dlt_common.h:422
#define DLT_USER_MAX_FILENAME_LENGTH
Definition: dlt_user_cfg.h:96
DltReturnValue dlt_log_int(DltContext *handle, DltLogLevelType loglevel, int data)
Definition: dlt_user.c:3056
#define DLT_USER_RCVBUF_MAX_SIZE
Definition: dlt_user_cfg.h:76
DltReturnValue dlt_user_log_write_uint32_formatted(DltContextData *log, uint32_t data, DltFormatType type)
Definition: dlt_user.c:1926
DltReturnValue dlt_disable_local_print(void)
Definition: dlt_user.c:3296
DltReturnValue dlt_user_set_userheader(DltUserHeader *userheader, uint32_t mtype)
static sem_t dlt_mutex
Definition: dlt_user.c:87
#define DLT_TYPE_INFO_FLOA
Definition: dlt_protocol.h:152
#define DLT_HTYP_WSID
Definition: dlt_protocol.h:85
#define DLT_USER_INITIAL_LOG_LEVEL
Definition: dlt_user_cfg.h:111
uint8_t headerbuffer[sizeof(DltStorageHeader)+sizeof(DltStandardHeader)+sizeof(DltStandardHeaderExtra)+sizeof(DltExtendedHeader)]
Definition: dlt_common.h:427
DltNetworkTraceType nw_trace_type
Definition: dlt_user.c:131
int dlt_buffer_remove(DltBuffer *buf)
Definition: dlt_common.c:2894
#define DLT_USER_MESSAGE_LOG_STATE
#define DLT_TYPE_INFO_STRG
Definition: dlt_protocol.h:154
int dlt_buffer_get_message_count(DltBuffer *buf)
Definition: dlt_common.c:2977
DltStandardHeaderExtra headerextra
Definition: dlt_common.h:434
char appID[DLT_ID_SIZE]
Definition: dlt_user.h:187
char ecuID[DLT_ID_SIZE]
Definition: dlt_user.h:186
DltReturnValue dlt_user_log_write_uint(DltContextData *log, unsigned int data)
Definition: dlt_user.c:1639
#define DLT_USER_ENV_BUFFER_MIN_SIZE
Definition: dlt_user_cfg.h:84
static char dlt_user_dir[NAME_MAX+1]
Definition: dlt_user.c:82
DltReturnValue dlt_user_log_write_uint32(DltContextData *log, uint32_t data)
Definition: dlt_user.c:1752
DltReturnValue dlt_user_trace_network_segmented(DltContext *handle, DltNetworkTraceType nw_trace_type, uint16_t header_len, void *header, uint16_t payload_len, void *payload)
Definition: dlt_user.c:2770
int8_t with_session_id
Definition: dlt_user.h:211
#define DLT_USER_MESSAGE_APP_LL_TS
unsigned char buffer[DLT_USER_BUF_MAX_SIZE]
Definition: dlt_user.h:118
int8_t use_extende_header_for_non_verbose
Definition: dlt_user.h:210
#define DLT_TYPE_LOG
Definition: dlt_protocol.h:114
DltReturnValue dlt_user_log_write_start_id(DltContext *handle, DltContextData *log, DltLogLevelType loglevel, uint32_t messageid)
Definition: dlt_user.c:1433
#define DLT_SCOD_BIN
Definition: dlt_protocol.h:171
DltReturnValue dlt_user_check_library_version(const char *user_major_version, const char *user_minor_version)
Definition: dlt_user.c:165
#define DLT_USER_INJECTION_MIN
Definition: dlt_user_cfg.h:149
#define DLT_SCOD_ASCII
Definition: dlt_protocol.h:168
#define DLT_TYPE_CONTROL
Definition: dlt_protocol.h:117
char dltFifoBaseDir[PATH_MAX+1]
Definition: dlt_common.c:72
#define DLT_MSIN_MSTP_SHIFT
Definition: dlt_protocol.h:104
void * payload
Definition: dlt_user.c:135
uint32_t nrcallbacks
Definition: dlt_user.h:152
DltReturnValue 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)
Definition: dlt_user.c:2855
#define DLT_USER_RINGBUFFER_STEP_SIZE
Definition: dlt_user_cfg.h:81
DltStandardHeader * standardheader
Definition: dlt_common.h:433
DltReturnValue dlt_vnlog(int prio, size_t size, const char *format,...)
Definition: dlt_common.c:2099
void dlt_unlock_mutex(pthread_mutex_t *mutex)
Definition: dlt_user.c:121
static bool dlt_user_initialised
Definition: dlt_user.c:79
pthread_cond_t mq_init_condition
Definition: dlt_user.c:104
#define DLT_TYPE_INFO_BOOL
Definition: dlt_protocol.h:149
DltReturnValue dlt_log_string(DltContext *handle, DltLogLevelType loglevel, const char *text)
Definition: dlt_user.c:2940
DltReturnValue dlt_with_timestamp(int8_t with_timestamp)
Definition: dlt_user.c:3246
DltReturnValue dlt_set_application_ll_ts_limit(DltLogLevelType loglevel, DltTraceStatusType tracestatus)
Definition: dlt_user.c:1208
#define DLT_MSIN_VERB
Definition: dlt_protocol.h:100
static DltReturnValue dlt_user_queue_resend(void)
Definition: dlt_user.c:3351
int32_t size
Definition: dlt_user.h:119
static pthread_t dlt_receiverthread_handle
Definition: dlt_user.c:88
DltReturnValue dlt_log_string_int(DltContext *handle, DltLogLevelType loglevel, const char *text, int data)
Definition: dlt_user.c:2976
uint32_t id
Definition: dlt_user.c:130
int8_t with_ecu_id
Definition: dlt_user.h:213
#define DLT_TYPE_INFO_RAWD
Definition: dlt_protocol.h:155
static DltReturnValue dlt_user_log_send_marker()
Definition: dlt_user.c:4019
#define DLT_USER_MESSAGE_LOG
DltReturnValue dlt_shm_free_client(DltShm *buf)
Definition: dlt_shm.c:303
int8_t * log_level_ptr
Definition: dlt_user.h:107
int dlt_buffer_push3(DltBuffer *buf, const unsigned char *data1, unsigned int size1, const unsigned char *data2, unsigned int size2, const unsigned char *data3, unsigned int size3)
Definition: dlt_common.c:2691
#define DLT_USER_BUFFER_LENGTH
Definition: dlt_user_cfg.h:89
char contextID[DLT_ID_SIZE]
Definition: dlt_user.h:145
void dlt_env_free_ll_set(dlt_env_ll_set *const ll_set)
release ll_set
Definition: dlt_env_ll.c:350
#define DLT_SEM_FREE()
Definition: dlt_user.h:98
#define DLT_SHM_KEY
Definition: dlt_shm.h:64
DltReturnValue dlt_user_log_write_int8(DltContextData *log, int8_t data)
Definition: dlt_user.c:2105
char contextID[DLT_ID_SIZE]
Definition: dlt_user.h:105
DltReturnValue dlt_log_marker()
Definition: dlt_user.c:3164
static DltReturnValue dlt_user_is_logLevel_enabled(DltContext *handle, DltLogLevelType loglevel)
Definition: dlt_user.h:788
#define DLT_USER_BUF_MAX_SIZE
Definition: dlt_user.h:92
DltReturnValue dlt_init_message_queue(void)
Definition: dlt_user.c:378
DltReturnValue dlt_user_log_write_uint8_formatted(DltContextData *log, uint8_t data, DltFormatType type)
Definition: dlt_user.c:1822
#define DLT_TYPE_INFO_UINT
Definition: dlt_protocol.h:151
static char str[DLT_USER_BUFFER_LENGTH]
Definition: dlt_user.c:85
DltReturnValue dlt_log_string_uint(DltContext *handle, DltLogLevelType loglevel, const char *text, unsigned int data)
Definition: dlt_user.c:3016
DltReturnValue dlt_register_injection_callback(DltContext *handle, uint32_t service_id, int(*dlt_injection_callback)(uint32_t service_id, void *data, uint32_t length))
Definition: dlt_user.c:2377
#define DLT_MAX_TRACE_SEGMENT_SIZE
Definition: dlt_user.c:98
int8_t * trace_status_ptr
Definition: dlt_user.h:149
DltReceiver receiver
Definition: dlt_user.h:207
#define DLT_USER_DEFAULT_MSGID
Definition: dlt_user_cfg.h:129
uint8_t mcnt
Definition: dlt_user.h:109
#define DLT_USER_WITH_TIMESTAMP
Definition: dlt_user_cfg.h:123
#define DLT_SCOD_HEX
Definition: dlt_protocol.h:170
DltReturnValue dlt_set_log_mode(DltUserLogMode mode)
Definition: dlt_user.c:1281
DltReturnValue dlt_user_log_write_uint64(DltContextData *log, uint64_t data)
Definition: dlt_user.c:1787
#define DLT_FD_INIT
Definition: dlt_common.h:196
DltReturnValue dlt_user_log_write_uint16(DltContextData *log, uint16_t data)
Definition: dlt_user.c:1717
uint8_t * databuffer
Definition: dlt_common.h:428
DltReturnValue dlt_nonverbose_mode(void)
Definition: dlt_user.c:3195
char * context_description
Definition: dlt_user.h:123
static void dlt_user_trace_network_segmented_thread_segmenter(s_segmented_data *data)
Definition: dlt_user.c:2735
DltReturnValue dlt_message_get_extraparameters(DltMessage *msg, int verbose)
Definition: dlt_common.c:1241
uint32_t dlt_ll_ts_num_entries
Definition: dlt_user.h:200
DltReturnValue dlt_user_log_write_constant_string(DltContextData *log, const char *text)
Definition: dlt_user.c:2326
int32_t log_level_pos
Definition: dlt_user.h:106
#define DLT_USER_WITH_ECU_ID
Definition: dlt_user_cfg.h:126
#define DLT_USER_WITH_SESSION_ID
Definition: dlt_user_cfg.h:120
static DltReturnValue dlt_user_print_msg(DltMessage *msg, DltContextData *log)
Definition: dlt_user.c:4039
static void dlt_user_receiverthread_function(void *ptr)
static DltReturnValue dlt_user_log_send_log(DltContextData *log, int mtype)
Definition: dlt_user.c:3407
#define DLT_USER_MESSAGE_LOG_SHM
DltReturnValue dlt_user_trace_network(DltContext *handle, DltNetworkTraceType nw_trace_type, uint16_t header_len, void *header, uint16_t payload_len, void *payload)
Definition: dlt_user.c:2850
#define DLT_USER_TRACE_STATUS_NOT_SET
DltReturnValue dlt_unregister_context(DltContext *handle)
Definition: dlt_user.c:1148
#define DLT_LOG_FATAL_RESET_TRAP(LOGLEVEL)
Definition: dlt_user.c:75
#define DLT_USER_LOG_LEVEL_NOT_SET
DltReturnValue dlt_vlog(int prio, const char *format,...)
Definition: dlt_common.c:2078
int8_t verbose_mode
Definition: dlt_user.h:209
DltReturnValue dlt_log_raw(DltContext *handle, DltLogLevelType loglevel, void *data, uint16_t length)
Definition: dlt_user.c:3128
void dlt_get_major_version(char *buf, size_t size)
Definition: dlt_common.c:3251
DltUserInjectionCallback * injection_table
Definition: dlt_user.h:151
#define DLT_TYLE_8BIT
Definition: dlt_protocol.h:162
DltReturnValue dlt_user_log_write_bool(DltContextData *log, uint8_t data)
Definition: dlt_user.c:2245
#define DLT_USER_INITIAL_TRACE_STATUS
Definition: dlt_user_cfg.h:114
DltReturnValue dlt_user_log_write_raw(DltContextData *log, void *data, uint16_t length)
Definition: dlt_user.c:1490
#define DLT_PM_AUTOMATIC
Definition: dlt_user_cfg.h:153
DltReturnValue dlt_user_log_write_finish(DltContextData *log)
Definition: dlt_user.c:1482
DltReturnValue dlt_user_log_write_float64(DltContextData *log, float64_t data)
Definition: dlt_user.c:1599
#define DLT_USER_ENV_LOCAL_PRINT_MODE
Definition: dlt_user_cfg.h:135
#define DLT_TYLE_64BIT
Definition: dlt_protocol.h:165
float float32_t
Definition: dlt_types.h:178
int dlt_log_handle
Definition: dlt_user.h:188
DltReturnValue dlt_user_log_resend_buffer(void)
Definition: dlt_user.c:4321
#define NULL
Definition: dlt_common.h:232
static int atexit_registered
Definition: dlt_user.c:91
DltReturnValue dlt_with_ecu_id(int8_t with_ecu_id)
Definition: dlt_user.c:3263
#define DLT_USER_USE_EXTENDED_HEADER_FOR_NONVERBOSE
Definition: dlt_user_cfg.h:117
DltReturnValue dlt_user_log_write_start(DltContext *handle, DltContextData *log, DltLogLevelType loglevel)
Definition: dlt_user.c:1428
static DltReturnValue dlt_user_log_send_overflow(void)
Definition: dlt_user.c:4486
int8_t * trace_status_ptr
Definition: dlt_user.h:108
DltReturnValue dlt_receiver_free(DltReceiver *receiver)
Definition: dlt_common.c:2153
int32_t args_num
Definition: dlt_user.h:122
DltReturnValue dlt_forward_msg(void *msgdata, size_t size)
Definition: dlt_user.c:1315
DltBuffer startup_buffer
Definition: dlt_user.h:223