Added define statement for initial value of file descriptor and (-1). Updated the...
[profile/ivi/dlt-daemon.git] / src / lib / dlt_user.c
1 /**
2  * @licence app begin@
3  * Copyright (C) 2012  BMW AG
4  *
5  * This file is part of GENIVI Project Dlt - Diagnostic Log and Trace console apps.
6  *
7  * Contributions are licensed to the GENIVI Alliance under one or more
8  * Contribution License Agreements.
9  *
10  * \copyright
11  * This Source Code Form is subject to the terms of the
12  * Mozilla Public License, v. 2.0. If a  copy of the MPL was not distributed with
13  * this file, You can obtain one at http://mozilla.org/MPL/2.0/.
14  *
15  *
16  * \author Alexander Wenzel <alexander.aw.wenzel@bmw.de> BMW 2011-2012
17  *
18  * \file dlt_user.c
19  * For further information see http://www.genivi.org/.
20  * @licence end@
21  */
22
23
24 /*******************************************************************************
25 **                                                                            **
26 **  SRC-MODULE: dlt_user.c                                                    **
27 **                                                                            **
28 **  TARGET    : linux                                                         **
29 **                                                                            **
30 **  PROJECT   : DLT                                                           **
31 **                                                                            **
32 **  AUTHOR    : Alexander Wenzel Alexander.AW.Wenzel@bmw.de                   **
33 **              Markus Klein                                                  **
34 **                                                                            **
35 **  PURPOSE   :                                                               **
36 **                                                                            **
37 **  REMARKS   :                                                               **
38 **                                                                            **
39 **  PLATFORM DEPENDANT [yes/no]: yes                                          **
40 **                                                                            **
41 **  TO BE CHANGED BY USER [yes/no]: no                                        **
42 **                                                                            **
43 *******************************************************************************/
44
45 /*******************************************************************************
46 **                      Author Identity                                       **
47 ********************************************************************************
48 **                                                                            **
49 ** Initials     Name                       Company                            **
50 ** --------     -------------------------  ---------------------------------- **
51 **  aw          Alexander Wenzel           BMW                                **
52 **  mk          Markus Klein               Fraunhofer ESK                     **
53 *******************************************************************************/
54
55 /*******************************************************************************
56 **                      Revision Control History                              **
57 *******************************************************************************/
58
59 /*
60  * $LastChangedRevision: 1670 $
61  * $LastChangedDate: 2011-04-08 15:12:06 +0200 (Fr, 08. Apr 2011) $
62  * $LastChangedBy$
63  Initials    Date         Comment
64  aw          13.01.2010   initial
65  */
66
67 #include <stdlib.h> /* for getenv(), free(), atexit() */
68 #include <string.h> /* for strcmp(), strncmp(), strlen(), memset(), memcpy() */
69 #include <signal.h> /* for signal(), SIGPIPE, SIG_IGN */
70
71 #if !defined (__WIN32__)
72 #include <syslog.h> /* for LOG_... */
73 #include <semaphore.h>
74 #include <pthread.h>    /* POSIX Threads */
75 #endif
76
77 #include <sys/stat.h>
78 #include <fcntl.h>
79 #include <errno.h>
80
81 #include <sys/uio.h> /* writev() */
82
83 #include "dlt_user.h"
84 #include "dlt_user_shared.h"
85 #include "dlt_user_shared_cfg.h"
86 #include "dlt_user_cfg.h"
87
88 static DltUser dlt_user;
89 static int dlt_user_initialised = 0;
90
91 static char str[DLT_USER_BUFFER_LENGTH];
92
93 static sem_t dlt_mutex;
94 static pthread_t dlt_receiverthread_handle;
95 static pthread_attr_t dlt_receiverthread_attr;
96
97 /* Function prototypes for internally used functions */
98 static void dlt_user_receiverthread_function(void *ptr);
99 static void dlt_user_atexit_handler(void);
100 static int dlt_user_log_init(DltContext *handle, DltContextData *log);
101 static int dlt_user_log_send_log(DltContextData *log, int mtype);
102 static int dlt_user_log_send_register_application(void);
103 static int dlt_user_log_send_unregister_application(void);
104 static int dlt_user_log_send_register_context(DltContextData *log);
105 static int dlt_user_log_send_unregister_context(DltContextData *log);
106 static int dlt_send_app_ll_ts_limit(const char *appid, DltLogLevelType loglevel, DltTraceStatusType tracestatus);
107 static int dlt_user_log_send_log_mode(DltUserLogMode mode);
108 static int dlt_user_print_msg(DltMessage *msg, DltContextData *log);
109 static int dlt_user_log_check_user_message(void);
110 static int dlt_user_log_resend_buffer(void);
111 static void dlt_user_log_reattach_to_daemon(void);
112 static int dlt_user_log_send_overflow(void);
113
114 int dlt_user_check_library_version(const char *user_major_version,const char *user_minor_version){
115
116         char str[200];
117         char lib_major_version[DLT_USER_MAX_LIB_VERSION_LENGTH];
118         char lib_minor_version[DLT_USER_MAX_LIB_VERSION_LENGTH];
119
120         dlt_get_major_version( lib_major_version);
121         dlt_get_minor_version( lib_minor_version);
122
123         if( (strcmp(lib_major_version,user_major_version)!=0) || (strcmp(lib_minor_version,user_minor_version)!=0))
124         {
125                 sprintf(str,"DLT Library version check failed! Installed DLT library version is %s.%s - Application using DLT library version %s.%s\n",lib_major_version,lib_minor_version,user_major_version,user_minor_version);
126                 dlt_log(LOG_WARNING, str);
127                 return -1;
128         }
129         return 0;
130 }
131
132 int dlt_init(void)
133 {
134     char filename[DLT_USER_MAX_FILENAME_LENGTH];
135     int ret;
136
137     dlt_user_initialised = 1;
138
139     /* Initialize common part of dlt_init()/dlt_init_file() */
140     if (dlt_init_common()==-1)
141     {
142         dlt_user_initialised = 0;
143         return -1;
144     }
145
146     dlt_user.dlt_is_file = 0;
147     dlt_user.overflow = 0;
148 #ifdef DLT_SHM_ENABLE
149         memset(&(dlt_user.dlt_shm),0,sizeof(DltShm));
150 #endif
151
152     /* create and open DLT user FIFO */
153     sprintf(filename,"%s/dlt%d",DLT_USER_DIR,getpid());
154      
155     /* Try to delete existing pipe, ignore result of unlink */
156     unlink(filename);
157     
158     ret=mkfifo(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH  | S_IWOTH );
159     if (ret==-1)
160     {
161         sprintf(str,"Loging disabled, FIFO user %s cannot be created!\n",filename);
162         dlt_log(LOG_WARNING, str);
163         /* return 0; */ /* removed to prevent error, when FIFO already exists */
164     }
165
166     dlt_user.dlt_user_handle = open(filename, O_RDWR | O_CLOEXEC);
167     if (dlt_user.dlt_user_handle == DLT_FD_INIT)
168     {
169         sprintf(str,"Loging disabled, FIFO user %s cannot be opened!\n",filename);
170         dlt_log(LOG_WARNING, str);
171         unlink(filename);
172         return 0;
173     }
174
175     /* open DLT output FIFO */
176     dlt_user.dlt_log_handle = open(DLT_USER_FIFO, O_WRONLY | O_NONBLOCK | O_CLOEXEC );
177     if (dlt_user.dlt_log_handle==-1)
178     {
179         sprintf(str,"Loging disabled, FIFO %s cannot be opened with open()!\n",DLT_USER_FIFO);
180         dlt_log(LOG_WARNING, str);
181         //return 0;
182     }
183         else
184         {
185 #ifdef DLT_SHM_ENABLE
186                 /* init shared memory */
187                 if (dlt_shm_init_client(&(dlt_user.dlt_shm),DLT_SHM_KEY) < 0)
188                 {
189                         sprintf(str,"Loging disabled, Shared memory %d cannot be created!\n",DLT_SHM_KEY);
190                         dlt_log(LOG_WARNING, str);
191                         //return 0; 
192                 }   
193 #endif
194         }
195                 
196
197     if (dlt_receiver_init(&(dlt_user.receiver),dlt_user.dlt_user_handle, DLT_USER_RCVBUF_MAX_SIZE)==-1)
198         {
199         dlt_user_initialised = 0;
200         return -1;
201     }
202
203     /* Start receiver thread */
204     if (pthread_create(&(dlt_receiverthread_handle),
205                        0,
206                        (void *) &dlt_user_receiverthread_function,
207                        0)!=0)
208         {
209                 if (pthread_attr_destroy(&dlt_receiverthread_attr)!=0)
210                 {
211                         dlt_log(LOG_WARNING, "Can't destroy thread attributes!\n");
212                 }
213
214                 dlt_log(LOG_CRIT, "Can't create receiver thread!\n");
215                 dlt_user_initialised = 0;
216         return -1;
217         }
218
219     if (pthread_attr_destroy(&dlt_receiverthread_attr)!=0)
220         {
221                 dlt_log(LOG_WARNING, "Can't destroy thread attributes!\n");
222         }
223
224     return 0;
225 }
226
227 int dlt_init_file(const char *name)
228 {
229     dlt_user_initialised = 1;
230
231     /* Initialize common part of dlt_init()/dlt_init_file() */
232     if (dlt_init_common()==-1)
233     {
234         dlt_user_initialised = 0;
235         return -1;
236     }
237
238     dlt_user.dlt_is_file = 1;
239
240     /* open DLT output file */
241     dlt_user.dlt_log_handle = open(name,O_WRONLY|O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); /* mode: wb */
242     if (dlt_user.dlt_log_handle == -1)
243     {
244         sprintf(str,"Log file %s cannot be opened!\n",name);
245         dlt_log(LOG_ERR, str);
246         return -1;
247     }
248
249     return 0;
250 }
251
252 int dlt_init_common(void)
253 {
254     char *env_local_print;
255
256     /* Binary semaphore for threads */
257     if (sem_init(&dlt_mutex, 0, 1)==-1)
258     {
259         dlt_user_initialised = 0;
260         return -1;
261     }
262
263         /* set to unknown state of connected client */
264         dlt_user.log_state = -1;
265
266     dlt_user.dlt_log_handle=-1;
267     dlt_user.dlt_user_handle=DLT_FD_INIT;
268
269     dlt_set_id(dlt_user.ecuID,DLT_USER_DEFAULT_ECU_ID);
270     dlt_set_id(dlt_user.appID,"");
271
272     dlt_user.application_description = 0;
273
274     /* Verbose mode is enabled by default */
275     dlt_user.verbose_mode = 1;
276
277     /* Local print is disabled by default */
278     dlt_user.enable_local_print = 0;
279
280     dlt_user.local_print_mode = DLT_PM_UNSET;
281
282     env_local_print = getenv(DLT_USER_ENV_LOCAL_PRINT_MODE);
283     if (env_local_print)
284     {
285         if (strcmp(env_local_print,"AUTOMATIC")==0)
286         {
287             dlt_user.local_print_mode = DLT_PM_AUTOMATIC;
288         }
289         else if (strcmp(env_local_print,"FORCE_ON")==0)
290         {
291             dlt_user.local_print_mode = DLT_PM_FORCE_ON;
292         }
293         else if (strcmp(env_local_print,"FORCE_OFF")==0)
294         {
295             dlt_user.local_print_mode = DLT_PM_FORCE_OFF;
296         }
297     }
298
299     /* Initialize LogLevel/TraceStatus field */
300     dlt_user.dlt_ll_ts = 0;
301     dlt_user.dlt_ll_ts_max_num_entries = 0;
302     dlt_user.dlt_ll_ts_num_entries = 0;
303
304     if (dlt_buffer_init_dynamic(&(dlt_user.startup_buffer), DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)==-1)
305     {
306                 dlt_user_initialised = 0;
307         return -1;
308     }
309
310     signal(SIGPIPE,SIG_IGN);                  /* ignore pipe signals */
311
312     atexit(dlt_user_atexit_handler);
313
314 #ifdef DLT_TEST_ENABLE
315     dlt_user.corrupt_user_header = 0;
316     dlt_user.corrupt_message_size = 0;
317     dlt_user.corrupt_message_size_size = 0;
318 #endif
319
320     return 0;
321 }
322
323 void dlt_user_atexit_handler(void)
324 {
325
326         /* Try to resend potential log messages in the user buffer */
327         int count = dlt_user_atexit_blow_out_user_buffer();
328
329         if(count != 0){
330                 char tmp[256];
331                 sprintf(tmp,"Lost log messages in user buffer when exiting: %i\n",count);
332                 dlt_log(LOG_ERR, tmp);
333         }
334
335     /* Unregister app (this also unregisters all contexts in daemon) */
336     /* Ignore return value */
337     dlt_unregister_app();
338
339     /* Cleanup */
340     /* Ignore return value */
341     dlt_free();
342 }
343
344 int dlt_user_atexit_blow_out_user_buffer(void){
345
346         int count,ret;
347
348         uint32_t exitTime = dlt_uptime() + DLT_USER_ATEXIT_RESEND_BUFFER_EXIT_TIMEOUT;
349
350         while(dlt_uptime() < exitTime ){
351
352                 ret = dlt_user_log_resend_buffer();
353
354                 if(ret == 0)
355                 {
356                                 return 0;
357                 }
358
359                 usleep(DLT_USER_ATEXIT_RESEND_BUFFER_SLEEP);
360         }
361
362         DLT_SEM_LOCK();
363         count = dlt_buffer_get_message_count(&(dlt_user.startup_buffer));
364         DLT_SEM_FREE();
365
366         return count;
367 }
368
369 int dlt_free(void)
370 {
371     uint32_t i;
372         char filename[DLT_USER_MAX_FILENAME_LENGTH];
373
374     if (dlt_user_initialised==0)
375     {
376         return -1;
377     }
378
379     if (dlt_receiverthread_handle)
380     {
381         /* Ignore return value */
382         pthread_cancel(dlt_receiverthread_handle);
383     }
384
385     if (dlt_user.dlt_user_handle!=DLT_FD_INIT)
386     {
387         sprintf(filename,"%s/dlt%d",DLT_USER_DIR,getpid());
388
389         close(dlt_user.dlt_user_handle);
390         dlt_user.dlt_user_handle=DLT_FD_INIT;
391
392         unlink(filename);
393     }
394
395 #ifdef DLT_SHM_ENABLE
396         /* free shared memory */
397         dlt_shm_free_client(&dlt_user.dlt_shm);
398 #endif
399
400     if (dlt_user.dlt_log_handle!=-1)
401     {
402         /* close log file/output fifo to daemon */
403         close(dlt_user.dlt_log_handle);
404         dlt_user.dlt_log_handle = -1;
405     }
406
407         /* Ignore return value */
408     dlt_receiver_free(&(dlt_user.receiver));
409
410         /* Ignore return value */
411     dlt_buffer_free_dynamic(&(dlt_user.startup_buffer));
412
413     if (dlt_user.dlt_ll_ts)
414     {
415         for (i=0;i<dlt_user.dlt_ll_ts_max_num_entries;i++)
416         {
417             if (dlt_user.dlt_ll_ts[i].injection_table!=0)
418             {
419                 free(dlt_user.dlt_ll_ts[i].injection_table);
420                 dlt_user.dlt_ll_ts[i].injection_table = 0;
421             }
422             dlt_user.dlt_ll_ts[i].nrcallbacks     = 0;
423         }
424
425         free(dlt_user.dlt_ll_ts);
426         dlt_user.dlt_ll_ts = 0;
427         dlt_user.dlt_ll_ts_max_num_entries = 0;
428         dlt_user.dlt_ll_ts_num_entries = 0;
429     }
430
431     dlt_user_initialised = 0;
432
433     return 0;
434 }
435
436 int dlt_check_library_version(const char * user_major_version,const char * user_minor_version)
437 {
438         return dlt_user_check_library_version(user_major_version, user_minor_version);
439 }
440
441 int dlt_register_app(const char *appid, const char * description)
442 {
443     int ret;
444
445     if (dlt_user_initialised==0)
446     {
447         if (dlt_init()<0)
448         {
449             return -1;
450         }
451     }
452
453     if ((appid==0) || (appid[0]=='\0'))
454     {
455         return -1;
456     }
457
458     DLT_SEM_LOCK();
459
460     /* Store locally application id and application description */
461     dlt_set_id(dlt_user.appID, appid);
462
463     if (dlt_user.application_description!=0)
464     {
465         free(dlt_user.application_description);
466     }
467
468     dlt_user.application_description = 0;
469
470     if (description!=0)
471     {
472         size_t desc_len = strlen(description);
473         dlt_user.application_description= malloc(desc_len+1);
474         if (dlt_user.application_description){
475             strncpy(dlt_user.application_description, description, desc_len);
476
477             /* Terminate transmitted string with 0 */
478             dlt_user.application_description[desc_len]='\0';
479         }
480         else
481         {
482                 DLT_SEM_FREE();
483                 return -1;
484         }
485     }
486
487     DLT_SEM_FREE();
488
489     ret = dlt_user_log_send_register_application();
490
491     return ret;
492 }
493 int dlt_register_context(DltContext *handle, const char *contextid, const char * description)
494 {
495     if (dlt_user_initialised==0)
496     {
497         if (dlt_init()<0)
498         {
499             return -1;
500         }
501     }
502
503     DLT_SEM_LOCK();
504
505     if (dlt_user.appID[0]=='\0')
506     {
507         dlt_log(LOG_ERR, "no application registered!\n");
508
509         DLT_SEM_FREE();
510         return -1;
511     }
512
513     if ((contextid==0) || (contextid[0]=='\0'))
514     {
515         DLT_SEM_FREE();
516         return -1;
517     }
518
519     DLT_SEM_FREE();
520
521     return dlt_register_context_ll_ts(handle, contextid, description, DLT_USER_LOG_LEVEL_NOT_SET, DLT_USER_TRACE_STATUS_NOT_SET);
522 }
523
524 int dlt_register_context_ll_ts(DltContext *handle, const char *contextid, const char * description, int loglevel, int tracestatus)
525 {
526     DltContextData log;
527     uint32_t i;
528     int registered,ret;
529     char ctid[DLT_ID_SIZE+1];
530
531     if (dlt_user_initialised==0)
532     {
533         if (dlt_init()<0)
534         {
535             return -1;
536         }
537     }
538
539     DLT_SEM_LOCK();
540
541     if (dlt_user.appID[0]=='\0')
542     {
543         dlt_log(LOG_ERR, "no application registered!\n");
544
545         DLT_SEM_FREE();
546         return -1;
547     }
548
549     DLT_SEM_FREE();
550
551     if ((contextid==0) || (contextid[0]=='\0'))
552     {
553         return -1;
554     }
555
556     if ((loglevel<DLT_USER_LOG_LEVEL_NOT_SET) || (loglevel>DLT_LOG_VERBOSE) || (loglevel==DLT_LOG_DEFAULT))
557     {
558         return -1;
559     }
560
561     if ((tracestatus<DLT_USER_TRACE_STATUS_NOT_SET) || (tracestatus>DLT_TRACE_STATUS_ON) || (tracestatus==DLT_TRACE_STATUS_DEFAULT))
562     {
563         return -1;
564     }
565
566     if (dlt_user_log_init(handle, &log)==-1)
567     {
568         return -1;
569     }
570
571     /* Reset message counter */
572     handle->mcnt = 0;
573
574     /* Store context id in log level/trace status field */
575
576     /* Check if already registered, else register context */
577     DLT_SEM_LOCK();
578
579     registered=0;
580     for (i=0;i<dlt_user.dlt_ll_ts_num_entries;i++)
581     {
582         if (dlt_user.dlt_ll_ts)
583         {
584             if (memcmp(dlt_user.dlt_ll_ts[i].contextID, contextid,DLT_ID_SIZE)==0)
585             {
586                 registered=1;
587
588                 memset(ctid,0,(DLT_ID_SIZE+1));
589                 dlt_print_id(ctid, contextid);
590
591                 sprintf(str,"context '%s' already registered!\n",ctid);
592                 dlt_log(LOG_WARNING, str);
593
594                 break;
595             }
596         }
597     }
598
599     if (registered==0)
600     {
601         /* Allocate or expand context array */
602         if (dlt_user.dlt_ll_ts == 0)
603         {
604             dlt_user.dlt_ll_ts = (dlt_ll_ts_type*) malloc(sizeof(dlt_ll_ts_type)*DLT_USER_CONTEXT_ALLOC_SIZE);
605             if (dlt_user.dlt_ll_ts==0)
606             {
607                 DLT_SEM_FREE();
608                 return -1;
609             }
610
611             dlt_user.dlt_ll_ts_max_num_entries = DLT_USER_CONTEXT_ALLOC_SIZE;
612
613             /* Initialize new entries */
614             for (i=0;i<dlt_user.dlt_ll_ts_max_num_entries;i++)
615             {
616                 dlt_set_id(dlt_user.dlt_ll_ts[i].contextID,"");
617
618                 /* At startup, logging and tracing is locally enabled */
619                 /* the correct log level/status is set after received from daemon */
620                 dlt_user.dlt_ll_ts[i].log_level    = DLT_USER_INITIAL_LOG_LEVEL;
621                 dlt_user.dlt_ll_ts[i].trace_status = DLT_USER_INITIAL_TRACE_STATUS;
622
623                 dlt_user.dlt_ll_ts[i].context_description = 0;
624
625                 dlt_user.dlt_ll_ts[i].injection_table = 0;
626                 dlt_user.dlt_ll_ts[i].nrcallbacks     = 0;
627             }
628         }
629         else
630         {
631             if ((dlt_user.dlt_ll_ts_num_entries%DLT_USER_CONTEXT_ALLOC_SIZE)==0)
632             {
633                 /* allocate memory in steps of DLT_USER_CONTEXT_ALLOC_SIZE, e.g. 500 */
634                 dlt_ll_ts_type *old_ll_ts;
635                 uint32_t old_max_entries;
636
637                 old_ll_ts = dlt_user.dlt_ll_ts;
638                 old_max_entries = dlt_user.dlt_ll_ts_max_num_entries;
639
640                 dlt_user.dlt_ll_ts_max_num_entries = ((dlt_user.dlt_ll_ts_num_entries/DLT_USER_CONTEXT_ALLOC_SIZE)+1)*DLT_USER_CONTEXT_ALLOC_SIZE;
641                 dlt_user.dlt_ll_ts = (dlt_ll_ts_type*) malloc(sizeof(dlt_ll_ts_type)*
642                                      dlt_user.dlt_ll_ts_max_num_entries);
643                 if (dlt_user.dlt_ll_ts==0)
644                 {
645                         dlt_user.dlt_ll_ts = old_ll_ts;
646                         dlt_user.dlt_ll_ts_max_num_entries = old_max_entries;
647                     DLT_SEM_FREE();
648                     return -1;
649                 }
650
651                 memcpy(dlt_user.dlt_ll_ts,old_ll_ts,sizeof(dlt_ll_ts_type)*dlt_user.dlt_ll_ts_num_entries);
652                 free(old_ll_ts);
653
654                 /* Initialize new entries */
655                 for (i=dlt_user.dlt_ll_ts_num_entries;i<dlt_user.dlt_ll_ts_max_num_entries;i++)
656                 {
657                     dlt_set_id(dlt_user.dlt_ll_ts[i].contextID,"");
658
659                     /* At startup, logging and tracing is locally enabled */
660                     /* the correct log level/status is set after received from daemon */
661                     dlt_user.dlt_ll_ts[i].log_level    = DLT_USER_INITIAL_LOG_LEVEL;
662                     dlt_user.dlt_ll_ts[i].trace_status = DLT_USER_INITIAL_TRACE_STATUS;
663
664                     dlt_user.dlt_ll_ts[i].context_description = 0;
665
666                     dlt_user.dlt_ll_ts[i].injection_table = 0;
667                     dlt_user.dlt_ll_ts[i].nrcallbacks     = 0;
668                 }
669             }
670         }
671
672         /* Store locally context id and context description */
673         dlt_set_id(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].contextID, contextid);
674
675         if (dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description!=0)
676         {
677             free(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description);
678         }
679
680         dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description = 0;
681
682         if (description!=0)
683         {
684                 size_t desc_len = strlen(description);
685             dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description = malloc(desc_len+1);
686             if(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description == 0)
687             {
688                 DLT_SEM_FREE();
689                 return -1;
690             }
691
692             strncpy(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description, description, desc_len);
693
694             /* Terminate transmitted string with 0 */
695             dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description[desc_len]='\0';
696         }
697
698         if (loglevel!=DLT_USER_LOG_LEVEL_NOT_SET)
699         {
700             dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].log_level = loglevel;
701         }
702
703         if (tracestatus!=DLT_USER_TRACE_STATUS_NOT_SET)
704         {
705             dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].trace_status = tracestatus;
706         }
707
708         /* Prepare transfer struct */
709         //dlt_set_id(log->appID, dlt_user.appID);
710         dlt_set_id(handle->contextID, contextid);
711         handle->log_level_pos = dlt_user.dlt_ll_ts_num_entries;
712
713         log.context_description = dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description;
714
715         if (loglevel!=DLT_USER_LOG_LEVEL_NOT_SET)
716         {
717             log.log_level = loglevel;
718         }
719         else
720         {
721             log.log_level = DLT_USER_LOG_LEVEL_NOT_SET;
722         }
723
724         if (tracestatus!=DLT_USER_TRACE_STATUS_NOT_SET)
725         {
726             log.trace_status = tracestatus;
727         }
728         else
729         {
730             log.trace_status = DLT_USER_TRACE_STATUS_NOT_SET;
731         }
732
733         dlt_user.dlt_ll_ts_num_entries++;
734
735         DLT_SEM_FREE();
736
737         ret=dlt_user_log_send_register_context(&log);
738     }
739     else
740     {
741         DLT_SEM_FREE();
742
743         ret=-1;
744     }
745
746     return ret;
747 }
748
749 int dlt_unregister_app(void)
750 {
751     int ret;
752
753     if (dlt_user_initialised==0)
754     {
755         return -1;
756     }
757
758     /* Inform daemon to unregister application and all of its contexts */
759     ret = dlt_user_log_send_unregister_application();
760
761     DLT_SEM_LOCK();
762
763     /* Clear and free local stored application information */
764     dlt_set_id(dlt_user.appID, "");
765
766     if (dlt_user.application_description!=0)
767     {
768         free(dlt_user.application_description);
769     }
770
771     dlt_user.application_description = 0;
772
773     DLT_SEM_FREE();
774
775     return ret;
776 }
777
778 int dlt_unregister_context(DltContext *handle)
779 {
780     DltContextData log;
781     int ret;
782
783     if (dlt_user_initialised==0)
784     {
785         return -1;
786     }
787
788     if (dlt_user_log_init(handle, &log) == -1)
789     {
790                 return -1;
791     }
792
793     DLT_SEM_LOCK();
794
795     if (dlt_user.dlt_ll_ts)
796     {
797         /* Clear and free local stored context information */
798         dlt_set_id(dlt_user.dlt_ll_ts[handle->log_level_pos].contextID, "");
799
800         dlt_user.dlt_ll_ts[handle->log_level_pos].log_level = DLT_USER_INITIAL_LOG_LEVEL;
801         dlt_user.dlt_ll_ts[handle->log_level_pos].trace_status = DLT_USER_INITIAL_TRACE_STATUS;
802
803         if (dlt_user.dlt_ll_ts[handle->log_level_pos].context_description!=0)
804         {
805             free(dlt_user.dlt_ll_ts[handle->log_level_pos].context_description);
806         }
807
808         dlt_user.dlt_ll_ts[handle->log_level_pos].context_description = 0;
809
810         if (dlt_user.dlt_ll_ts[handle->log_level_pos].injection_table)
811         {
812             free(dlt_user.dlt_ll_ts[handle->log_level_pos].injection_table);
813             dlt_user.dlt_ll_ts[handle->log_level_pos].injection_table = 0;
814         }
815
816         dlt_user.dlt_ll_ts[handle->log_level_pos].nrcallbacks     = 0;
817     }
818
819     DLT_SEM_FREE();
820
821     /* Inform daemon to unregister context */
822     ret = dlt_user_log_send_unregister_context(&log);
823
824     return ret;
825 }
826
827 int dlt_set_application_ll_ts_limit(DltLogLevelType loglevel, DltTraceStatusType tracestatus)
828 {
829     uint32_t i;
830     int ret;
831
832     if (dlt_user_initialised==0)
833     {
834         if (dlt_init()<0)
835         {
836             return -1;
837         }
838     }
839
840     /* Removed because of DltLogLevelType and DltTraceStatusType
841
842     if ((loglevel<DLT_LOG_DEFAULT) || (loglevel>DLT_LOG_VERBOSE))
843     {
844         return -1;
845     }
846
847     if ((tracestatus<DLT_TRACE_STATUS_DEFAULT) || (tracestatus>DLT_TRACE_STATUS_ON))
848     {
849         return -1;
850     }
851
852     if (dlt_user.dlt_ll_ts==0)
853     {
854         return -1;
855     }
856
857     */
858
859     DLT_SEM_LOCK();
860
861     /* Update local structures */
862     for (i=0; i<dlt_user.dlt_ll_ts_num_entries;i++)
863     {
864         dlt_user.dlt_ll_ts[i].log_level = loglevel;
865         dlt_user.dlt_ll_ts[i].trace_status = tracestatus;
866     }
867
868     DLT_SEM_FREE();
869
870     /* Inform DLT server about update */
871     ret = dlt_send_app_ll_ts_limit(dlt_user.appID, loglevel, tracestatus);
872
873     return ret;
874 }
875
876 int dlt_get_log_state()
877 {
878         return dlt_user.log_state;
879 }
880
881 int dlt_set_log_mode(DltUserLogMode mode)
882 {
883     if (dlt_user_initialised==0)
884     {
885         if (dlt_init()<0)
886         {
887             return -1;
888         }
889     }
890
891         return dlt_user_log_send_log_mode(mode);
892 }
893
894 int dlt_forward_msg(void *msgdata,size_t size)
895 {
896     DltUserHeader userheader;
897     DltReturnValue ret;
898
899     if ((msgdata==0) || (size==0))
900     {
901         return -1;
902     }
903
904     if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG)==-1)
905     {
906         /* Type of internal user message; same value for Trace messages */
907         return -1;
908     }
909
910     if (dlt_user.dlt_is_file)
911     {
912         /* log to file */
913         ret = dlt_user_log_out2(dlt_user.dlt_log_handle, msgdata, size, 0, 0);
914         return ((ret==DLT_RETURN_OK)?0:-1);
915     }
916     else
917     {
918         /* Reattach to daemon if neccesary */
919         dlt_user_log_reattach_to_daemon();
920
921         if (dlt_user.overflow)
922         {
923             if (dlt_user_log_send_overflow()==0)
924             {
925                 dlt_user.overflow=0;
926             }
927         }
928
929         /* log to FIFO */
930         ret = dlt_user_log_out3(dlt_user.dlt_log_handle,
931                                 &(userheader), sizeof(DltUserHeader),
932                                 msgdata, size, 0, 0);
933
934         /* store message in ringbuffer, if an error has occured */
935         if (ret!=DLT_RETURN_OK)
936         {
937             DLT_SEM_LOCK();
938
939             if (dlt_buffer_push3(&(dlt_user.startup_buffer),
940                                 (unsigned char *)&(userheader), sizeof(DltUserHeader),
941                                  msgdata, size, 0, 0)==-1)
942                         {
943                                 dlt_log(LOG_ERR,"Storing message to history buffer failed! Message discarded.\n");
944                         }
945
946             DLT_SEM_FREE();
947         }
948
949         switch (ret)
950         {
951         case DLT_RETURN_PIPE_FULL:
952         {
953             /* data could not be written */
954             dlt_user.overflow = 1;
955             return -1;
956         }
957         case DLT_RETURN_PIPE_ERROR:
958         {
959             /* handle not open or pipe error */
960             close(dlt_user.dlt_log_handle);
961             dlt_user.dlt_log_handle = -1;
962
963             return -1;
964         }
965         case DLT_RETURN_ERROR:
966         {
967             /* other error condition */
968             return -1;
969         }
970         case DLT_RETURN_OK:
971         {
972                 return 0;
973         }
974                 default:
975                 {
976                         /* This case should not occur */
977                         return -1;
978                 }
979         }
980     }
981
982     return 0;
983 }
984
985 /* ********************************************************************************************* */
986
987 inline int dlt_user_log_write_start(DltContext *handle, DltContextData *log,DltLogLevelType loglevel)
988 {
989     return dlt_user_log_write_start_id(handle,log,loglevel,DLT_USER_DEFAULT_MSGID);
990 }
991
992 int dlt_user_log_write_start_id(DltContext *handle, DltContextData *log,DltLogLevelType loglevel, uint32_t messageid)
993 {
994         if(dlt_user_initialised==0)
995         {
996                 if (dlt_init()<0)
997                 {
998                         return -1;
999                 }
1000         }
1001     if (log==0)
1002     {
1003         return -1;
1004     }
1005
1006     if (dlt_user_log_init(handle, log)==-1)
1007     {
1008                 return -1;
1009     }
1010
1011     if (dlt_user.dlt_ll_ts==0)
1012     {
1013         return -1;
1014     }
1015
1016     DLT_SEM_LOCK();
1017
1018     if ((loglevel<=(int)(dlt_user.dlt_ll_ts[handle->log_level_pos].log_level) ) && (loglevel!=0))
1019     {
1020         DLT_SEM_FREE();
1021                 log->args_num = 0;
1022         log->log_level = loglevel;
1023
1024         /* In non-verbose mode, insert message id */
1025         if (dlt_user.verbose_mode==0)
1026         {
1027             if ((sizeof(uint32_t))>DLT_USER_BUF_MAX_SIZE)
1028             {
1029                 return -1;
1030             }
1031             /* Write message id */
1032             memcpy(log->buffer,&(messageid),sizeof(uint32_t));
1033             log->size = sizeof(uint32_t);
1034
1035             /* as the message id is part of each message in non-verbose mode,
1036                it doesn't increment the argument counter in extended header (if used) */
1037         }
1038         else log->size=0;
1039         return 1;
1040     }
1041     else
1042     {
1043         DLT_SEM_FREE();
1044         return 0;
1045     }
1046
1047     return -1;
1048 }
1049
1050 int dlt_user_log_write_finish(DltContextData *log)
1051 {
1052     if (log==0)
1053     {
1054         return -1;
1055     }
1056
1057     return dlt_user_log_send_log(log, DLT_TYPE_LOG);
1058 }
1059
1060 int dlt_user_log_write_raw(DltContextData *log,void *data,uint16_t length)
1061 {
1062     uint16_t arg_size;
1063     uint32_t type_info;
1064
1065     if (log==0)
1066     {
1067         return -1;
1068     }
1069
1070     if ((log->size+length+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1071     {
1072         return -1;
1073     }
1074
1075     if (dlt_user.verbose_mode)
1076     {
1077         if ((log->size+length+sizeof(uint32_t)+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1078         {
1079             return -1;
1080         }
1081
1082         /* Transmit type information */
1083         type_info = DLT_TYPE_INFO_RAWD;
1084
1085         memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1086         log->size += sizeof(uint32_t);
1087
1088     }
1089
1090     /* First transmit length of raw data, then the raw data itself */
1091     arg_size = (uint16_t)length;
1092
1093     memcpy((log->buffer)+log->size,&(arg_size),sizeof(uint16_t));
1094     log->size += sizeof(uint16_t);
1095
1096     memcpy((log->buffer)+log->size,data,arg_size);
1097     log->size += arg_size;
1098
1099     log->args_num ++;
1100
1101     return 0;
1102 }
1103
1104 int dlt_user_log_write_float32(DltContextData *log, float32_t data)
1105 {
1106     uint32_t type_info;
1107
1108     if (log==0)
1109     {
1110         return -1;
1111     }
1112
1113     if (sizeof(float32_t)!=4)
1114     {
1115         return -1;
1116     }
1117
1118     if ((log->size+sizeof(float32_t))>DLT_USER_BUF_MAX_SIZE)
1119     {
1120         return -1;
1121     }
1122
1123     if (dlt_user.verbose_mode)
1124     {
1125         if ((log->size+sizeof(uint32_t)+sizeof(float32_t))>DLT_USER_BUF_MAX_SIZE)
1126         {
1127             return -1;
1128         }
1129
1130         type_info = DLT_TYPE_INFO_FLOA | DLT_TYLE_32BIT;
1131
1132         memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1133         log->size += sizeof(uint32_t);
1134     }
1135
1136     memcpy((log->buffer)+log->size,&data, sizeof(float32_t));
1137     log->size += sizeof(float32_t);
1138
1139     log->args_num ++;
1140
1141     return 0;
1142 }
1143
1144 int dlt_user_log_write_float64(DltContextData *log, float64_t data)
1145 {
1146     uint32_t type_info;
1147
1148     if (log==0)
1149     {
1150         return -1;
1151     }
1152
1153     if (sizeof(float64_t)!=8)
1154     {
1155         return -1;
1156     }
1157
1158     if ((log->size+sizeof(float64_t))>DLT_USER_BUF_MAX_SIZE)
1159     {
1160         return -1;
1161     }
1162
1163     if (dlt_user.verbose_mode)
1164     {
1165         if ((log->size+sizeof(uint32_t)+sizeof(float64_t))>DLT_USER_BUF_MAX_SIZE)
1166         {
1167             return -1;
1168         }
1169
1170         type_info = DLT_TYPE_INFO_FLOA | DLT_TYLE_64BIT;
1171
1172         memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1173         log->size += sizeof(uint32_t);
1174     }
1175
1176     memcpy((log->buffer)+log->size,&data, sizeof(float64_t));
1177     log->size += sizeof(float64_t);
1178
1179     log->args_num ++;
1180
1181     return 0;
1182 }
1183
1184 int dlt_user_log_write_uint( DltContextData *log, unsigned int data)
1185 {
1186     if (log==0)
1187     {
1188         return -1;
1189     }
1190
1191     switch (sizeof(unsigned int))
1192     {
1193     case 1:
1194     {
1195         return dlt_user_log_write_uint8(log, (uint8_t)data);
1196         break;
1197     }
1198     case 2:
1199     {
1200         return dlt_user_log_write_uint16(log, (uint16_t)data);
1201         break;
1202     }
1203     case 4:
1204     {
1205         return dlt_user_log_write_uint32(log, (uint32_t)data);
1206         break;
1207     }
1208     case 8:
1209     {
1210         return dlt_user_log_write_uint64(log, (uint64_t)data);
1211                 break;
1212     }
1213     default:
1214     {
1215         return -1;
1216         break;
1217     }
1218     }
1219
1220     return 0;
1221 }
1222
1223 int dlt_user_log_write_uint8(DltContextData *log, uint8_t data)
1224 {
1225     uint32_t type_info;
1226
1227     if (log==0)
1228     {
1229         return -1;
1230     }
1231
1232     if ((log->size+sizeof(uint8_t))>DLT_USER_BUF_MAX_SIZE)
1233     {
1234         return -1;
1235     }
1236
1237     if (dlt_user.verbose_mode)
1238     {
1239         if ((log->size+sizeof(uint32_t)+sizeof(uint8_t))>DLT_USER_BUF_MAX_SIZE)
1240         {
1241             return -1;
1242         }
1243
1244         type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_8BIT;
1245
1246         memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1247         log->size += sizeof(uint32_t);
1248     }
1249
1250     memcpy((log->buffer)+log->size,&data,sizeof(uint8_t));
1251     log->size += sizeof(uint8_t);
1252
1253     log->args_num ++;
1254
1255     return 0;
1256 }
1257
1258 int dlt_user_log_write_uint16(DltContextData *log, uint16_t data)
1259 {
1260     uint32_t type_info;
1261
1262     if (log==0)
1263     {
1264         return -1;
1265     }
1266
1267     if ((log->size+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1268     {
1269         return -1;
1270     }
1271
1272     if (dlt_user.verbose_mode)
1273     {
1274         if ((log->size+sizeof(uint32_t)+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1275         {
1276             return -1;
1277         }
1278
1279         type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_16BIT;
1280
1281         memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1282         log->size += sizeof(uint32_t);
1283     }
1284
1285     memcpy((log->buffer)+log->size,&data,sizeof(uint16_t));
1286     log->size += sizeof(uint16_t);
1287
1288     log->args_num ++;
1289
1290     return 0;
1291 }
1292
1293 int dlt_user_log_write_uint32(DltContextData *log, uint32_t data)
1294 {
1295     uint32_t type_info;
1296
1297     if (log==0)
1298     {
1299         return -1;
1300     }
1301
1302     if ((log->size+sizeof(uint32_t))>DLT_USER_BUF_MAX_SIZE)
1303     {
1304         return -1;
1305     }
1306
1307     if (dlt_user.verbose_mode)
1308     {
1309         if ((log->size+sizeof(uint32_t)+sizeof(uint32_t))>DLT_USER_BUF_MAX_SIZE)
1310         {
1311             return -1;
1312         }
1313
1314         type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_32BIT;
1315
1316         memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1317         log->size += sizeof(uint32_t);
1318     }
1319
1320     memcpy((log->buffer)+log->size,&data, sizeof(uint32_t));
1321     log->size += sizeof(uint32_t);
1322
1323     log->args_num ++;
1324
1325     return 0;
1326 }
1327
1328 int dlt_user_log_write_uint64(DltContextData *log, uint64_t data)
1329 {
1330     uint32_t type_info;
1331
1332     if (log==0)
1333     {
1334         return -1;
1335     }
1336
1337     if ((log->size+sizeof(uint64_t))>DLT_USER_BUF_MAX_SIZE)
1338     {
1339         return -1;
1340     }
1341
1342     if (dlt_user.verbose_mode)
1343     {
1344         if ((log->size+sizeof(uint32_t)+sizeof(uint64_t))>DLT_USER_BUF_MAX_SIZE)
1345         {
1346             return -1;
1347         }
1348
1349         type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_64BIT;
1350
1351         memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1352         log->size +=sizeof(uint32_t);
1353     }
1354
1355     memcpy((log->buffer)+log->size,&data,sizeof(uint64_t));
1356     log->size += sizeof(uint64_t);
1357
1358     log->args_num ++;
1359
1360     return 0;
1361 }
1362
1363 int dlt_user_log_write_int(DltContextData *log, int data)
1364 {
1365     if (log==0)
1366     {
1367         return -1;
1368     }
1369
1370     switch (sizeof(int))
1371     {
1372     case 1:
1373     {
1374         return dlt_user_log_write_int8(log, (int8_t)data);
1375         break;
1376     }
1377     case 2:
1378     {
1379         return dlt_user_log_write_int16(log, (int16_t)data);
1380         break;
1381     }
1382     case 4:
1383     {
1384         return dlt_user_log_write_int32(log, (int32_t)data);
1385         break;
1386     }
1387     case 8:
1388     {
1389         return dlt_user_log_write_int64(log, (int64_t)data);
1390                 break;
1391     }
1392     default:
1393     {
1394         return -1;
1395         break;
1396     }
1397     }
1398
1399     return 0;
1400 }
1401
1402 int dlt_user_log_write_int8(DltContextData *log, int8_t data)
1403 {
1404     uint32_t type_info;
1405
1406     if (log==0)
1407     {
1408         return -1;
1409     }
1410
1411     if ((log->size+sizeof(int8_t))>DLT_USER_BUF_MAX_SIZE)
1412     {
1413         return -1;
1414     }
1415
1416     if (dlt_user.verbose_mode)
1417     {
1418         if ((log->size+sizeof(uint32_t)+sizeof(int8_t))>DLT_USER_BUF_MAX_SIZE)
1419         {
1420             return -1;
1421         }
1422
1423         type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_8BIT;
1424
1425         memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1426         log->size += sizeof(uint32_t);
1427     }
1428
1429     memcpy((log->buffer)+log->size,&data,sizeof(int8_t));
1430     log->size += sizeof(int8_t);
1431
1432     log->args_num ++;
1433
1434     return 0;
1435 }
1436
1437 int dlt_user_log_write_int16(DltContextData *log, int16_t data)
1438 {
1439     uint32_t type_info;
1440
1441     if (log==0)
1442     {
1443         return -1;
1444     }
1445
1446     if ((log->size+sizeof(int16_t))>DLT_USER_BUF_MAX_SIZE)
1447     {
1448         return -1;
1449     }
1450
1451     if (dlt_user.verbose_mode)
1452     {
1453         if ((log->size+sizeof(uint32_t)+sizeof(int16_t))>DLT_USER_BUF_MAX_SIZE)
1454                 {
1455             return -1;
1456                 }
1457
1458         type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_16BIT;
1459
1460         memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1461         log->size += sizeof(uint32_t);
1462     }
1463
1464     memcpy((log->buffer)+log->size,&data,sizeof(int16_t));
1465     log->size += sizeof(int16_t);
1466
1467     log->args_num ++;
1468
1469     return 0;
1470 }
1471
1472 int dlt_user_log_write_int32(DltContextData *log, int32_t data)
1473 {
1474     uint32_t type_info;
1475
1476     if (log==0)
1477     {
1478         return -1;
1479     }
1480
1481     if ((log->size+sizeof(int32_t))>DLT_USER_BUF_MAX_SIZE)
1482     {
1483         return -1;
1484     }
1485
1486     if (dlt_user.verbose_mode)
1487     {
1488         if ((log->size+sizeof(uint32_t)+sizeof(int32_t))>DLT_USER_BUF_MAX_SIZE)
1489         {
1490             return -1;
1491         }
1492
1493         type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_32BIT;
1494
1495         memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1496         log->size += sizeof(uint32_t);
1497     }
1498
1499     memcpy((log->buffer)+log->size,&data, sizeof(int32_t));
1500     log->size += sizeof(int32_t);
1501
1502     log->args_num ++;
1503
1504     return 0;
1505 }
1506
1507 int dlt_user_log_write_int64(DltContextData *log, int64_t data)
1508 {
1509     uint32_t type_info;
1510
1511     if (log==0)
1512     {
1513         return -1;
1514     }
1515
1516     if ((log->size+sizeof(int64_t))>DLT_USER_BUF_MAX_SIZE)
1517     {
1518         return -1;
1519     }
1520
1521     if (dlt_user.verbose_mode)
1522     {
1523         if ((log->size+sizeof(uint32_t)+sizeof(int64_t))>DLT_USER_BUF_MAX_SIZE)
1524         {
1525             return -1;
1526         }
1527
1528         type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_64BIT;
1529
1530         memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1531         log->size += sizeof(uint32_t);
1532     }
1533
1534     memcpy((log->buffer)+log->size,&data,sizeof(int64_t));
1535     log->size += sizeof(int64_t);
1536
1537     log->args_num ++;
1538
1539     return 0;
1540 }
1541
1542 int dlt_user_log_write_bool(DltContextData *log, uint8_t data)
1543 {
1544     uint32_t type_info;
1545
1546     if (log==0)
1547     {
1548         return -1;
1549     }
1550
1551     if ((log->size+sizeof(uint8_t))>DLT_USER_BUF_MAX_SIZE)
1552     {
1553         return -1;
1554     }
1555
1556     if (dlt_user.verbose_mode)
1557     {
1558         if ((log->size+sizeof(uint32_t)+sizeof(uint8_t))>DLT_USER_BUF_MAX_SIZE)
1559         {
1560             return -1;
1561         }
1562
1563         type_info = DLT_TYPE_INFO_BOOL;
1564
1565         memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1566         log->size += sizeof(uint32_t);
1567     }
1568
1569     memcpy((log->buffer)+log->size,&data,sizeof(uint8_t));
1570     log->size += sizeof(uint8_t);
1571
1572     log->args_num ++;
1573
1574     return 0;
1575 }
1576
1577 int dlt_user_log_write_string(DltContextData *log, const char *text)
1578 {
1579     uint16_t arg_size;
1580     uint32_t type_info;
1581
1582     if ((log==0) || (text==0))
1583     {
1584         return -1;
1585     }
1586
1587     if ((log->size+(strlen(text)+1)+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1588     {
1589         return -1;
1590     }
1591
1592     if (dlt_user.verbose_mode)
1593     {
1594         if ((log->size+(strlen(text)+1)+sizeof(uint32_t)+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1595         {
1596             return -1;
1597         }
1598
1599         type_info = DLT_TYPE_INFO_STRG;
1600
1601         memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1602         log->size += sizeof(uint32_t);
1603     }
1604
1605     arg_size = strlen(text) + 1;
1606
1607     memcpy((log->buffer)+log->size,&(arg_size),sizeof(uint16_t));
1608     log->size += sizeof(uint16_t);
1609
1610     memcpy((log->buffer)+log->size,text,arg_size);
1611     log->size += arg_size;
1612
1613     log->args_num ++;
1614
1615     return 0;
1616 }
1617
1618 int dlt_register_injection_callback(DltContext *handle, uint32_t service_id,
1619                                     int (*dlt_injection_callback)(uint32_t service_id, void *data, uint32_t length))
1620 {
1621     DltContextData log;
1622     uint32_t i,j,k;
1623     int found = 0;
1624
1625         DltUserInjectionCallback *old;
1626
1627     if (handle==0)
1628     {
1629         return -1;
1630     }
1631
1632     if (dlt_user_log_init(handle, &log)==-1)
1633     {
1634                 return -1;
1635     }
1636
1637     if (service_id<DLT_USER_INJECTION_MIN)
1638     {
1639         return -1;
1640     }
1641     /* This function doesn't make sense storing to local file is choosen;
1642        so terminate this function */
1643     if (dlt_user.dlt_is_file)
1644     {
1645         return 0;
1646     }
1647
1648     DLT_SEM_LOCK();
1649
1650     if (dlt_user.dlt_ll_ts==0)
1651     {
1652         DLT_SEM_FREE();
1653         return 0;
1654     }
1655
1656     /* Insert callback in corresponding table */
1657     i=handle->log_level_pos;
1658
1659     /* Insert each service_id only once */
1660     for (k=0;k<dlt_user.dlt_ll_ts[i].nrcallbacks;k++)
1661     {
1662         if ((dlt_user.dlt_ll_ts[i].injection_table) &&
1663                 (dlt_user.dlt_ll_ts[i].injection_table[k].service_id == service_id))
1664         {
1665             found = 1;
1666             break;
1667         }
1668     }
1669
1670     if (found)
1671     {
1672         j = k;
1673     }
1674     else
1675     {
1676         j=dlt_user.dlt_ll_ts[i].nrcallbacks;
1677
1678         /* Allocate or expand injection table */
1679         if (dlt_user.dlt_ll_ts[i].injection_table == 0)
1680         {
1681             dlt_user.dlt_ll_ts[i].injection_table = (DltUserInjectionCallback*) malloc(sizeof(DltUserInjectionCallback));
1682             if(dlt_user.dlt_ll_ts[i].injection_table == 0)
1683             {
1684                 DLT_SEM_FREE();
1685                 return -1;
1686             }
1687         }
1688         else
1689         {
1690             old = dlt_user.dlt_ll_ts[i].injection_table;
1691             dlt_user.dlt_ll_ts[i].injection_table = (DltUserInjectionCallback*) malloc(sizeof(DltUserInjectionCallback)*(j+1));
1692             if(dlt_user.dlt_ll_ts[i].injection_table == 0)
1693             {
1694                 dlt_user.dlt_ll_ts[i].injection_table = old;
1695                 DLT_SEM_FREE();
1696                 return -1;
1697             }
1698             memcpy(dlt_user.dlt_ll_ts[i].injection_table,old,sizeof(DltUserInjectionCallback)*j);
1699             free(old);
1700         }
1701
1702         dlt_user.dlt_ll_ts[i].nrcallbacks++;
1703     }
1704
1705     /* Store service_id and corresponding function pointer for callback function */
1706     dlt_user.dlt_ll_ts[i].injection_table[j].service_id = service_id;
1707     dlt_user.dlt_ll_ts[i].injection_table[j].injection_callback = dlt_injection_callback;
1708
1709     DLT_SEM_FREE();
1710     return 0;
1711 }
1712
1713 int dlt_user_trace_network(DltContext *handle, DltNetworkTraceType nw_trace_type, uint16_t header_len, void *header, uint16_t payload_len, void *payload)
1714 {
1715     DltContextData log;
1716
1717     if (dlt_user_initialised==0)
1718     {
1719         if (dlt_init()<0)
1720         {
1721             return -1;
1722         }
1723     }
1724
1725     if (dlt_user_log_init(handle, &log)==-1)
1726     {
1727                 return -1;
1728     }
1729
1730     if (handle==0)
1731     {
1732         return -1;
1733     }
1734
1735     /* Commented out because of DltNetworkTraceType:
1736
1737     if ((nw_trace_type<=0) || (nw_trace_type>0x15))
1738     {
1739         return -1;
1740     }
1741
1742     */
1743
1744     DLT_SEM_LOCK();
1745
1746     if (dlt_user.dlt_ll_ts==0)
1747     {
1748         DLT_SEM_FREE();
1749         return -1;
1750     }
1751
1752     if (dlt_user.dlt_ll_ts[handle->log_level_pos].trace_status==DLT_TRACE_STATUS_ON)
1753     {
1754         DLT_SEM_FREE();
1755
1756         log.args_num = 0;
1757         log.trace_status = nw_trace_type;
1758         log.size = 0;
1759
1760         if (header==0)
1761         {
1762             header_len=0;
1763         }
1764
1765         /* Write header and its length */
1766         if (dlt_user_log_write_raw(&log, header, header_len)==-1)
1767         {
1768                 return -1;
1769         }
1770
1771         if (payload==0)
1772         {
1773             payload_len=0;
1774         }
1775
1776         /* Write payload and its length */
1777         if (dlt_user_log_write_raw(&log, payload, payload_len)==-1)
1778         {
1779                         return -1;
1780         }
1781
1782         /* Send log */
1783         return dlt_user_log_send_log(&log, DLT_TYPE_NW_TRACE);
1784     }
1785     else
1786     {
1787         DLT_SEM_FREE();
1788     }
1789
1790     return 0;
1791 }
1792
1793 int dlt_log_string(DltContext *handle,DltLogLevelType loglevel, const char *text)
1794 {
1795     DltContextData log;
1796
1797     if (dlt_user.verbose_mode==0)
1798     {
1799         return -1;
1800     }
1801
1802     if ((handle==0) || (text==0))
1803     {
1804         return -1;
1805     }
1806
1807     if (dlt_user_log_write_start(handle,&log,loglevel)>0)
1808     {
1809         if (dlt_user_log_write_string(&log,text)==-1)
1810         {
1811                         return -1;
1812         }
1813         if (dlt_user_log_write_finish(&log)==-1)
1814         {
1815                 return -1;
1816         }
1817     }
1818
1819     return 0;
1820 }
1821
1822 int dlt_log_string_int(DltContext *handle,DltLogLevelType loglevel, const char *text, int data)
1823 {
1824     DltContextData log;
1825
1826     if (dlt_user.verbose_mode==0)
1827     {
1828         return -1;
1829     }
1830
1831     if ((handle==0) || (text==0))
1832     {
1833         return -1;
1834     }
1835
1836     if (dlt_user_log_write_start(handle,&log,loglevel)>0)
1837     {
1838         if (dlt_user_log_write_string(&log,text)==-1)
1839         {
1840                         return -1;
1841         }
1842         if (dlt_user_log_write_int(&log,data)==-1)
1843         {
1844                         return -1;
1845         }
1846         if (dlt_user_log_write_finish(&log)==-1)
1847         {
1848                         return -1;
1849         }
1850     }
1851
1852     return 0;
1853 }
1854
1855 int dlt_log_string_uint(DltContext *handle,DltLogLevelType loglevel, const char *text, unsigned int data)
1856 {
1857     DltContextData log;
1858
1859     if (dlt_user.verbose_mode==0)
1860     {
1861         return -1;
1862     }
1863
1864     if ((handle==0) || (text==0))
1865     {
1866         return -1;
1867     }
1868
1869     if (dlt_user_log_write_start(handle,&log,loglevel)>0)
1870     {
1871         if (dlt_user_log_write_string(&log,text)==-1)
1872         {
1873                         return -1;
1874         }
1875         if (dlt_user_log_write_uint(&log,data)==-1)
1876         {
1877                         return -1;
1878         }
1879         if (dlt_user_log_write_finish(&log)==-1)
1880         {
1881                         return -1;
1882         }
1883     }
1884
1885     return 0;
1886 }
1887
1888 int dlt_log_int(DltContext *handle,DltLogLevelType loglevel, int data)
1889 {
1890     DltContextData log;
1891
1892     if (dlt_user.verbose_mode==0)
1893     {
1894         return -1;
1895     }
1896
1897     if (handle==0)
1898     {
1899         return -1;
1900     }
1901
1902     if (dlt_user_log_write_start(handle,&log,loglevel)>0)
1903     {
1904         if (dlt_user_log_write_int(&log,data)==-1)
1905         {
1906                         return -1;
1907         }
1908         if (dlt_user_log_write_finish(&log)==-1)
1909         {
1910                         return -1;
1911         }
1912     }
1913
1914     return 0;
1915 }
1916
1917 int dlt_log_uint(DltContext *handle,DltLogLevelType loglevel, unsigned int data)
1918 {
1919     DltContextData log;
1920
1921     if (dlt_user.verbose_mode==0)
1922     {
1923         return -1;
1924     }
1925
1926     if (handle==0)
1927     {
1928         return -1;
1929     }
1930
1931     if (dlt_user_log_write_start(handle,&log,loglevel)>0)
1932     {
1933         if (dlt_user_log_write_uint(&log,data)==-1)
1934         {
1935                         return -1;
1936         }
1937         if (dlt_user_log_write_finish(&log)==-1)
1938         {
1939                         return -1;
1940         }
1941     }
1942
1943     return 0;
1944 }
1945
1946 int dlt_log_raw(DltContext *handle,DltLogLevelType loglevel, void *data,uint16_t length)
1947 {
1948     DltContextData log;
1949
1950     if (dlt_user.verbose_mode==0)
1951     {
1952         return -1;
1953     }
1954
1955     if (handle==0)
1956     {
1957         return -1;
1958     }
1959
1960     if (dlt_user_log_write_start(handle,&log,loglevel)>0)
1961     {
1962         if (dlt_user_log_write_raw(&log,data,length)==-1)
1963         {
1964                         return -1;
1965         }
1966         if (dlt_user_log_write_finish(&log)==-1)
1967         {
1968                         return -1;
1969         }
1970     }
1971
1972     return 0;
1973 }
1974
1975 int dlt_verbose_mode(void)
1976 {
1977     if (dlt_user_initialised==0)
1978     {
1979         if (dlt_init()<0)
1980         {
1981             return -1;
1982         }
1983     }
1984
1985     /* Switch to verbose mode */
1986     dlt_user.verbose_mode = 1;
1987
1988     return 0;
1989 }
1990
1991 int dlt_nonverbose_mode(void)
1992 {
1993     if (dlt_user_initialised==0)
1994     {
1995         if (dlt_init()<0)
1996         {
1997             return -1;
1998         }
1999     }
2000
2001     /* Switch to non-verbose mode */
2002     dlt_user.verbose_mode = 0;
2003
2004     return 0;
2005 }
2006
2007 int dlt_enable_local_print(void)
2008 {
2009     if (dlt_user_initialised==0)
2010     {
2011         if (dlt_init()<0)
2012         {
2013             return -1;
2014         }
2015     }
2016
2017     dlt_user.enable_local_print = 1;
2018
2019     return 0;
2020 }
2021
2022 int dlt_disable_local_print(void)
2023 {
2024     if (dlt_user_initialised==0)
2025     {
2026         if (dlt_init()<0)
2027         {
2028             return -1;
2029         }
2030     }
2031
2032     dlt_user.enable_local_print = 0;
2033
2034     return 0;
2035 }
2036
2037 void dlt_user_receiverthread_function(void *ptr)
2038 {
2039     while (1)
2040     {
2041         /* Check for new messages from DLT daemon */
2042         if (dlt_user_log_check_user_message()==-1)
2043         {
2044                         /* Critical error */
2045                         dlt_log(LOG_CRIT,"Receiver thread encountered error condition\n");
2046         }
2047
2048         usleep(DLT_USER_RECEIVE_DELAY); /* delay */
2049     }
2050 }
2051
2052 /* Private functions of user library */
2053
2054 int dlt_user_log_init(DltContext *handle, DltContextData *log)
2055 {
2056     if (dlt_user_initialised==0)
2057     {
2058         if (dlt_init()<0)
2059         {
2060             return -1;
2061         }
2062     }
2063
2064     log->handle = handle;
2065
2066     return 0;
2067 }
2068
2069 int dlt_user_log_send_log(DltContextData *log, int mtype)
2070 {
2071     DltMessage msg;
2072     DltUserHeader userheader;
2073     int32_t len;
2074
2075     DltReturnValue ret = 0;
2076
2077     if (log==0)
2078     {
2079         return -1;
2080     }
2081
2082     if (log->handle==0)
2083     {
2084         return -1;
2085     }
2086
2087     if (dlt_user.appID[0]=='\0')
2088     {
2089         return -1;
2090     }
2091
2092     if (log->handle->contextID[0]=='\0')
2093     {
2094         return -1;
2095     }
2096
2097     if ((mtype<DLT_TYPE_LOG) || (mtype>DLT_TYPE_CONTROL))
2098     {
2099         return -1;
2100     }
2101
2102     /* also for Trace messages */
2103 #ifdef DLT_SHM_ENABLE
2104     if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG_SHM)==-1)
2105 #else
2106     if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG)==-1)
2107 #endif
2108     {
2109                 return -1;
2110     }
2111
2112     if (dlt_message_init(&msg,0)==-1)
2113     {
2114         return -1;
2115     }
2116
2117     msg.storageheader = (DltStorageHeader*)msg.headerbuffer;
2118
2119     if (dlt_set_storageheader(msg.storageheader,dlt_user.ecuID)==-1)
2120     {
2121                 return -1;
2122     }
2123
2124     msg.standardheader = (DltStandardHeader*)(msg.headerbuffer + sizeof(DltStorageHeader));
2125     msg.standardheader->htyp = DLT_HTYP_WEID | DLT_HTYP_WTMS | DLT_HTYP_PROTOCOL_VERSION1 ;
2126
2127     if (dlt_user.verbose_mode)
2128     {
2129         /* In verbose mode, send extended header */
2130         msg.standardheader->htyp = (msg.standardheader->htyp | DLT_HTYP_UEH );
2131     }
2132     else
2133     {
2134         /* In non-verbose, send extended header if desired */
2135 #if (DLT_USER_USE_EXTENDED_HEADER_FOR_NONVERBOSE==1)
2136         msg.standardheader->htyp = (msg.standardheader->htyp | DLT_HTYP_UEH );
2137 #endif
2138     }
2139
2140 #if (BYTE_ORDER==BIG_ENDIAN)
2141     msg.standardheader->htyp = (msg.standardheader->htyp | DLT_HTYP_MSBF);
2142 #endif
2143
2144     msg.standardheader->mcnt = log->handle->mcnt++;
2145
2146     /* Set header extra parameters */
2147     dlt_set_id(msg.headerextra.ecu,dlt_user.ecuID);
2148     //msg.headerextra.seid = 0;
2149     msg.headerextra.tmsp = dlt_uptime();
2150
2151     if (dlt_message_set_extraparameters(&msg,0)==-1)
2152     {
2153         return -1;
2154     }
2155
2156     /* Fill out extended header, if extended header should be provided */
2157     if (DLT_IS_HTYP_UEH(msg.standardheader->htyp))
2158     {
2159         /* with extended header */
2160         msg.extendedheader = (DltExtendedHeader*)(msg.headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp)  );
2161
2162         switch (mtype)
2163         {
2164         case DLT_TYPE_LOG:
2165         {
2166             msg.extendedheader->msin = (DLT_TYPE_LOG << DLT_MSIN_MSTP_SHIFT) | ((log->log_level << DLT_MSIN_MTIN_SHIFT) & DLT_MSIN_MTIN) ; /* messsage info */
2167             break;
2168         }
2169         case DLT_TYPE_NW_TRACE:
2170         {
2171             msg.extendedheader->msin = (DLT_TYPE_NW_TRACE << DLT_MSIN_MSTP_SHIFT) | ((log->trace_status << DLT_MSIN_MTIN_SHIFT) & DLT_MSIN_MTIN) ; /* messsage info */
2172             break;
2173         }
2174         default:
2175         {
2176                     /* This case should not occur */
2177             return -1;
2178             break;
2179         }
2180         }
2181
2182         /* If in verbose mode, set flag in header for verbose mode */
2183         if (dlt_user.verbose_mode)
2184         {
2185             msg.extendedheader->msin |= DLT_MSIN_VERB;
2186         }
2187
2188         msg.extendedheader->noar = log->args_num;              /* number of arguments */
2189         dlt_set_id(msg.extendedheader->apid,dlt_user.appID);       /* application id */
2190         dlt_set_id(msg.extendedheader->ctid,log->handle->contextID);   /* context id */
2191
2192         msg.headersize = sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + sizeof(DltExtendedHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp);
2193     }
2194     else
2195     {
2196         /* without extended header */
2197         msg.headersize = sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp);
2198     }
2199
2200     len=msg.headersize - sizeof(DltStorageHeader) +log->size;
2201     if (len>UINT16_MAX)
2202     {
2203         dlt_log(LOG_CRIT,"Huge message discarded!\n");
2204         return -1;
2205     }
2206
2207     msg.standardheader->len = DLT_HTOBE_16(len);
2208
2209     /* print to std out, if enabled */
2210     if ((dlt_user.local_print_mode != DLT_PM_FORCE_OFF) &&
2211             (dlt_user.local_print_mode != DLT_PM_AUTOMATIC))
2212     {
2213         if ((dlt_user.enable_local_print) || (dlt_user.local_print_mode == DLT_PM_FORCE_ON))
2214         {
2215             if (dlt_user_print_msg(&msg, log)==-1)
2216             {
2217                                 return -1;
2218             }
2219         }
2220     }
2221
2222     if (dlt_user.dlt_is_file)
2223     {
2224         /* log to file */
2225         ret=dlt_user_log_out2(dlt_user.dlt_log_handle, msg.headerbuffer, msg.headersize, log->buffer, log->size);
2226         return ((ret==DLT_RETURN_OK)?0:-1);
2227     }
2228     else
2229     {
2230         /* Reattach to daemon if neccesary */
2231         dlt_user_log_reattach_to_daemon();
2232
2233         if (dlt_user.overflow)
2234         {
2235             if (dlt_user_log_send_overflow()==0)
2236             {
2237                 dlt_user.overflow=0;
2238             }
2239         }
2240
2241                 /* try to resent old data first */
2242                 ret = 0;
2243                 if(dlt_user.dlt_log_handle!=-1)
2244                         ret = dlt_user_log_resend_buffer();
2245                 if(ret==0) 
2246                 {
2247                         /* resend ok or nothing to resent */
2248 #ifdef DLT_SHM_ENABLE
2249                         if(dlt_user.dlt_log_handle!=-1)
2250                                 dlt_shm_push(&dlt_user.dlt_shm,msg.headerbuffer+sizeof(DltStorageHeader), msg.headersize-sizeof(DltStorageHeader),
2251                                                                                         log->buffer, log->size,0,0);                   
2252
2253                         /* log to FIFO */
2254                         ret = dlt_user_log_out3(dlt_user.dlt_log_handle,
2255                                                                         &(userheader), sizeof(DltUserHeader),
2256                                                                         0, 0,
2257                                                                         0, 0);
2258 #else
2259                         /* log to FIFO */
2260 #ifdef DLT_TEST_ENABLE
2261                         if(dlt_user.corrupt_user_header) {
2262                                 userheader.pattern[0]=0xff;
2263                                 userheader.pattern[1]=0xff;
2264                                 userheader.pattern[2]=0xff;
2265                                 userheader.pattern[3]=0xff;
2266                         }
2267                         if(dlt_user.corrupt_message_size) {
2268                                 msg.standardheader->len = DLT_HTOBE_16(dlt_user.corrupt_message_size_size);
2269                         }
2270 #endif
2271                         ret = dlt_user_log_out3(dlt_user.dlt_log_handle,
2272                                                                         &(userheader), sizeof(DltUserHeader),
2273                                                                         msg.headerbuffer+sizeof(DltStorageHeader), msg.headersize-sizeof(DltStorageHeader),
2274                                                                         log->buffer, log->size);                
2275 #endif                  
2276                 }
2277                 
2278         /* store message in ringbuffer, if an error has occured */
2279         if (ret!=DLT_RETURN_OK)
2280         {
2281             DLT_SEM_LOCK();
2282
2283             if (dlt_buffer_push3(&(dlt_user.startup_buffer),
2284                                 (unsigned char *)&(userheader), sizeof(DltUserHeader),
2285                                 msg.headerbuffer+sizeof(DltStorageHeader), msg.headersize-sizeof(DltStorageHeader),
2286                                 log->buffer, log->size)==-1)
2287                         {
2288                                 dlt_log(LOG_ERR,"Storing message to history buffer failed! Message discarded.\n");
2289                         }
2290
2291             DLT_SEM_FREE();
2292         }
2293
2294         switch (ret)
2295         {
2296         case DLT_RETURN_PIPE_FULL:
2297         {
2298             /* data could not be written */
2299             dlt_user.overflow = 1;
2300             return -1;
2301         }
2302         case DLT_RETURN_PIPE_ERROR:
2303         {
2304             /* handle not open or pipe error */
2305             close(dlt_user.dlt_log_handle);
2306             dlt_user.dlt_log_handle = -1;
2307
2308 #ifdef DLT_SHM_ENABLE
2309                         /* free shared memory */
2310                         dlt_shm_free_client(&dlt_user.dlt_shm);
2311 #endif
2312
2313             if (dlt_user.local_print_mode == DLT_PM_AUTOMATIC)
2314             {
2315                 dlt_user_print_msg(&msg, log);
2316             }
2317
2318             return -1;
2319         }
2320         case DLT_RETURN_ERROR:
2321         {
2322             /* other error condition */
2323             return -1;
2324         }
2325                 case DLT_RETURN_OK:
2326         {
2327                 return 0;
2328         }
2329                 default:
2330                 {
2331                         /* This case should never occur. */
2332                         return -1;
2333                 }
2334         }
2335     }
2336
2337     return 0;
2338 }
2339
2340 int dlt_user_log_send_register_application(void)
2341 {
2342     DltUserHeader userheader;
2343     DltUserControlMsgRegisterApplication usercontext;
2344
2345     DltReturnValue ret;
2346
2347     if (dlt_user.appID[0]=='\0')
2348     {
2349         return -1;
2350     }
2351
2352     /* set userheader */
2353     if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_REGISTER_APPLICATION)==-1)
2354     {
2355                 return -1;
2356     }
2357
2358     /* set usercontext */
2359     dlt_set_id(usercontext.apid,dlt_user.appID);       /* application id */
2360     usercontext.pid = getpid();
2361
2362     if (dlt_user.application_description!=0)
2363     {
2364         usercontext.description_length = strlen(dlt_user.application_description);
2365     }
2366     else
2367     {
2368         usercontext.description_length = 0;
2369     }
2370
2371     if (dlt_user.dlt_is_file)
2372     {
2373         return 0;
2374     }
2375
2376     /* log to FIFO */
2377     ret=dlt_user_log_out3(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgRegisterApplication),dlt_user.application_description,usercontext.description_length);
2378         return ((ret==DLT_RETURN_OK)?0:-1);
2379 }
2380
2381 int dlt_user_log_send_unregister_application(void)
2382 {
2383     DltUserHeader userheader;
2384     DltUserControlMsgUnregisterApplication usercontext;
2385
2386     DltReturnValue ret;
2387
2388     if (dlt_user.appID[0]=='\0')
2389     {
2390         return -1;
2391     }
2392
2393     /* set userheader */
2394     if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_UNREGISTER_APPLICATION)==-1)
2395     {
2396         return -1;
2397     }
2398
2399     /* set usercontext */
2400     dlt_set_id(usercontext.apid,dlt_user.appID);       /* application id */
2401     usercontext.pid = getpid();
2402
2403     if (dlt_user.dlt_is_file)
2404     {
2405         return 0;
2406     }
2407
2408     /* log to FIFO */
2409     ret=dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgUnregisterApplication));
2410     return ((ret==DLT_RETURN_OK)?0:-1);
2411 }
2412
2413 int dlt_user_log_send_register_context(DltContextData *log)
2414 {
2415     DltUserHeader userheader;
2416     DltUserControlMsgRegisterContext usercontext;
2417     DltReturnValue ret;
2418
2419     if (log==0)
2420     {
2421                 return -1;
2422     }
2423
2424     if (log->handle==0)
2425     {
2426         return -1;
2427     }
2428
2429     if ((dlt_user.appID[0]=='\0') || (log->handle->contextID=='\0'))
2430     {
2431         return -1;
2432     }
2433
2434     /* set userheader */
2435     if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_REGISTER_CONTEXT)==-1)
2436     {
2437                 return -1;
2438     }
2439
2440     /* set usercontext */
2441     dlt_set_id(usercontext.apid,dlt_user.appID);       /* application id */
2442     dlt_set_id(usercontext.ctid,log->handle->contextID);       /* context id */
2443     usercontext.log_level_pos = log->handle->log_level_pos;
2444     usercontext.pid = getpid();
2445
2446     usercontext.log_level = (int8_t)log->log_level;
2447     usercontext.trace_status = (int8_t)log->trace_status;
2448
2449     if (log->context_description!=0)
2450     {
2451         usercontext.description_length = strlen(log->context_description);
2452     }
2453     else
2454     {
2455                 usercontext.description_length = 0;
2456     }
2457
2458     if (dlt_user.dlt_is_file)
2459     {
2460         return 0;
2461     }
2462
2463     /* log to FIFO */
2464     ret=dlt_user_log_out3(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgRegisterContext),log->context_description,usercontext.description_length);
2465     return ((ret==DLT_RETURN_OK)?0:-1);
2466 }
2467
2468 int dlt_user_log_send_unregister_context(DltContextData *log)
2469 {
2470     DltUserHeader userheader;
2471     DltUserControlMsgUnregisterContext usercontext;
2472     DltReturnValue ret;
2473
2474     if (log==0)
2475     {
2476         return -1;
2477     }
2478
2479     if (log->handle==0)
2480     {
2481         return -1;
2482     }
2483
2484     if ((dlt_user.appID[0]=='\0') || (log->handle->contextID=='\0'))
2485     {
2486         return -1;
2487     }
2488
2489     /* set userheader */
2490     if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_UNREGISTER_CONTEXT)==-1)
2491     {
2492                 return -1;
2493     }
2494
2495     /* set usercontext */
2496     dlt_set_id(usercontext.apid,dlt_user.appID);       /* application id */
2497     dlt_set_id(usercontext.ctid,log->handle->contextID);       /* context id */
2498     usercontext.pid = getpid();
2499
2500     if (dlt_user.dlt_is_file)
2501     {
2502         return 0;
2503     }
2504
2505     /* log to FIFO */
2506     ret=dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgUnregisterContext));
2507         return ((ret==DLT_RETURN_OK)?0:-1);
2508 }
2509
2510 int dlt_send_app_ll_ts_limit(const char *appid, DltLogLevelType loglevel, DltTraceStatusType tracestatus)
2511 {
2512     DltUserHeader userheader;
2513     DltUserControlMsgAppLogLevelTraceStatus usercontext;
2514         DltReturnValue ret;
2515
2516     if ((appid==0) || (appid[0]=='\0'))
2517     {
2518         return -1;
2519     }
2520
2521     /* Removed because of DltLogLevelType and DltTraceStatusType
2522
2523     if ((loglevel<DLT_LOG_DEFAULT) || (loglevel>DLT_LOG_VERBOSE))
2524     {
2525         return -1;
2526     }
2527
2528     if ((tracestatus<DLT_TRACE_STATUS_DEFAULT) || (tracestatus>DLT_TRACE_STATUS_ON))
2529     {
2530         return -1;
2531     }
2532
2533     */
2534
2535     /* set userheader */
2536     if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_APP_LL_TS)==-1)
2537     {
2538                 return -1;
2539     }
2540
2541     /* set usercontext */
2542     dlt_set_id(usercontext.apid,appid);       /* application id */
2543     usercontext.log_level = loglevel;
2544     usercontext.trace_status = tracestatus;
2545
2546     if (dlt_user.dlt_is_file)
2547     {
2548         return 0;
2549     }
2550
2551     /* log to FIFO */
2552     ret=dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgAppLogLevelTraceStatus));
2553     return ((ret==DLT_RETURN_OK)?0:-1);
2554 }
2555
2556 int dlt_user_log_send_log_mode(DltUserLogMode mode)
2557 {
2558     DltUserHeader userheader;
2559     DltUserControlMsgLogMode logmode;
2560
2561     DltReturnValue ret;
2562
2563     /* set userheader */
2564     if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG_MODE)==-1)
2565     {
2566         return -1;
2567     }
2568
2569     /* set data */
2570     logmode.log_mode = (unsigned char) mode;
2571
2572     if (dlt_user.dlt_is_file)
2573     {
2574         return 0;
2575     }
2576
2577     /* log to FIFO */
2578     ret=dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(logmode), sizeof(DltUserControlMsgLogMode));
2579     return ((ret==DLT_RETURN_OK)?0:-1);
2580 }
2581
2582 int dlt_user_print_msg(DltMessage *msg, DltContextData *log)
2583 {
2584     uint8_t *databuffer_tmp;
2585     int32_t datasize_tmp;
2586     int32_t databuffersize_tmp;
2587     static char text[DLT_USER_TEXT_LENGTH];
2588
2589     if ((msg==0) || (log==0))
2590     {
2591         return -1;
2592     }
2593
2594     /* Save variables before print */
2595     databuffer_tmp = msg->databuffer;
2596     datasize_tmp = msg->datasize;
2597     databuffersize_tmp = msg->databuffersize;
2598
2599     /* Act like a receiver, convert header back to host format */
2600     msg->standardheader->len = DLT_BETOH_16(msg->standardheader->len);
2601     dlt_message_get_extraparameters(msg,0);
2602
2603     msg->databuffer = log->buffer;
2604     msg->datasize = log->size;
2605     msg->databuffersize = log->size;
2606
2607     /* Print message as ASCII */
2608     if (dlt_message_print_ascii(msg,text,DLT_USER_TEXT_LENGTH,0)==-1)
2609     {
2610                 return -1;
2611     }
2612
2613     /* Restore variables and set len to BE*/
2614     msg->databuffer = databuffer_tmp;
2615     msg->databuffersize = databuffersize_tmp;
2616     msg->datasize =  datasize_tmp;
2617
2618     msg->standardheader->len = DLT_HTOBE_16(msg->standardheader->len);
2619
2620     return 0;
2621 }
2622
2623 int dlt_user_log_check_user_message(void)
2624 {
2625     int offset=0;
2626     int leave_while=0;
2627
2628     uint32_t i;
2629
2630     DltUserHeader *userheader;
2631     DltReceiver *receiver = &(dlt_user.receiver);
2632
2633     DltUserControlMsgLogLevel *usercontextll;
2634     DltUserControlMsgInjection *usercontextinj;
2635     DltUserControlMsgLogState *userlogstate;
2636     unsigned char *userbuffer;
2637
2638     /* For delayed calling of injection callback, to avoid deadlock */
2639     DltUserInjectionCallback    delayed_injection_callback;
2640     unsigned char                               *delayed_inject_buffer = 0;
2641     uint32_t                                    delayed_inject_data_length = 0;
2642
2643     /* Ensure that callback is null before searching for it */
2644     delayed_injection_callback.injection_callback = 0;
2645     delayed_injection_callback.service_id = 0;
2646
2647     if (dlt_user.dlt_user_handle!=DLT_FD_INIT)
2648     {
2649         while (1)
2650         {
2651             if (dlt_receiver_receive_fd(receiver)<=0)
2652             {
2653                 /* No new message available */
2654                 return 0;
2655             }
2656
2657             /* look through buffer as long as data is in there */
2658             while (1)
2659             {
2660                 if (receiver->bytesRcvd < (int32_t)sizeof(DltUserHeader))
2661                 {
2662                     break;
2663                 }
2664
2665                 /* resync if necessary */
2666                 offset=0;
2667                 do
2668                 {
2669                     userheader = (DltUserHeader*) (receiver->buf+offset);
2670
2671                     /* Check for user header pattern */
2672                     if (dlt_user_check_userheader(userheader))
2673                     {
2674                         break;
2675                     }
2676                     offset++;
2677
2678                 }
2679                 while ((int32_t)(sizeof(DltUserHeader)+offset)<=receiver->bytesRcvd);
2680
2681                 /* Check for user header pattern */
2682                 if (dlt_user_check_userheader(userheader)==0)
2683                 {
2684                     break;
2685                 }
2686
2687                 /* Set new start offset */
2688                 if (offset>0)
2689                 {
2690                     receiver->buf+=offset;
2691                     receiver->bytesRcvd-=offset;
2692                 }
2693
2694                 switch (userheader->message)
2695                 {
2696                 case DLT_USER_MESSAGE_LOG_LEVEL:
2697                 {
2698                     if (receiver->bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogLevel)))
2699                     {
2700                         leave_while=1;
2701                         break;
2702                     }
2703
2704                     usercontextll = (DltUserControlMsgLogLevel*) (receiver->buf+sizeof(DltUserHeader));
2705
2706                     /* Update log level and trace status */
2707                     if (usercontextll!=0)
2708                     {
2709                         DLT_SEM_LOCK();
2710
2711                         if ((usercontextll->log_level_pos >= 0) && (usercontextll->log_level_pos < (int32_t)dlt_user.dlt_ll_ts_num_entries))
2712                         {
2713                             // printf("Store ll, ts\n");
2714                             if (dlt_user.dlt_ll_ts)
2715                             {
2716                                 dlt_user.dlt_ll_ts[usercontextll->log_level_pos].log_level = usercontextll->log_level;
2717                                 dlt_user.dlt_ll_ts[usercontextll->log_level_pos].trace_status = usercontextll->trace_status;
2718                             }
2719                         }
2720
2721                         DLT_SEM_FREE();
2722                     }
2723
2724                     /* keep not read data in buffer */
2725                     if (dlt_receiver_remove(receiver,sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogLevel))==-1)
2726                     {
2727                         return -1;
2728                     }
2729                 }
2730                 break;
2731                 case DLT_USER_MESSAGE_INJECTION:
2732                 {
2733                     /* At least, user header, user context, and service id and data_length of injected message is available */
2734                     if (receiver->bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgInjection)))
2735                     {
2736                         leave_while = 1;
2737                         break;
2738                     }
2739
2740                     usercontextinj = (DltUserControlMsgInjection*) (receiver->buf+sizeof(DltUserHeader));
2741                     userbuffer = (unsigned char*) (receiver->buf+sizeof(DltUserHeader)+sizeof(DltUserControlMsgInjection));
2742
2743                     if (userbuffer!=0)
2744                     {
2745
2746                         if (receiver->bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgInjection)+usercontextinj->data_length_inject))
2747                         {
2748                             leave_while = 1;
2749                             break;
2750                         }
2751
2752                         DLT_SEM_LOCK();
2753
2754                         if ((usercontextinj->data_length_inject>0) && (dlt_user.dlt_ll_ts))
2755                         {
2756                             /* Check if injection callback is registered for this context */
2757                             for (i=0; i<dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].nrcallbacks;i++)
2758                             {
2759                                 if ((dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table) &&
2760                                         (dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table[i].service_id == usercontextinj->service_id))
2761                                 {
2762                                         /* Prepare delayed injection callback call */
2763                                                                         if (dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table[i].injection_callback!=0)
2764                                                                         {
2765                                                                                 delayed_injection_callback.injection_callback = dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table[i].injection_callback;
2766                                                                                 delayed_injection_callback.service_id = usercontextinj->service_id;
2767                                                                                 delayed_inject_data_length = usercontextinj->data_length_inject;
2768                                                                                 delayed_inject_buffer = malloc(delayed_inject_data_length);
2769                                                                                 if(delayed_inject_buffer != 0) {
2770                                                                                         memcpy(delayed_inject_buffer, userbuffer, delayed_inject_data_length);
2771                                                                                 }
2772
2773                                                                         }
2774                                     break;
2775                                 }
2776                             }
2777                         }
2778
2779                         DLT_SEM_FREE();
2780
2781                         /* Delayed injection callback call */
2782                         if(delayed_inject_buffer != 0 && delayed_injection_callback.injection_callback != 0) {
2783                                 delayed_injection_callback.injection_callback(delayed_injection_callback.service_id, delayed_inject_buffer, delayed_inject_data_length);
2784                                 free(delayed_inject_buffer);
2785                         }
2786
2787                         /* keep not read data in buffer */
2788                         if (dlt_receiver_remove(receiver,(sizeof(DltUserHeader)+sizeof(DltUserControlMsgInjection)+usercontextinj->data_length_inject))==-1)
2789                                                 {
2790                                                         return -1;
2791                                                 }
2792                     }
2793                 }
2794                 break;
2795                 case DLT_USER_MESSAGE_LOG_STATE:
2796                 {
2797                     /* At least, user header, user context, and service id and data_length of injected message is available */
2798                     if (receiver->bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogState)))
2799                     {
2800                         leave_while = 1;
2801                         break;
2802                     }
2803
2804                     userlogstate = (DltUserControlMsgLogState*) (receiver->buf+sizeof(DltUserHeader));
2805                                         dlt_user.log_state = userlogstate->log_state;
2806
2807                                         /* keep not read data in buffer */
2808                                         if (dlt_receiver_remove(receiver,(sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogState)))==-1)
2809                                         {
2810                                                 return -1;
2811                                         }
2812                 }
2813                 break;
2814                 default:
2815                 {
2816                     dlt_log(LOG_ERR,"Invalid user message type received!\n");
2817                     /* Ignore result */
2818                     dlt_receiver_remove(receiver,sizeof(DltUserHeader));
2819                                         /* In next invocation of while loop, a resync will be triggered if additional data was received */
2820                 }
2821                 break;
2822                 } /* switch() */
2823
2824                 if (leave_while==1)
2825                 {
2826                     leave_while=0;
2827                     break;
2828                 }
2829
2830             } /* while buffer*/
2831
2832             if (dlt_receiver_move_to_begin(receiver)==-1)
2833             {
2834                                 return -1;
2835             }
2836         } /* while receive */
2837     } /* if */
2838
2839     return DLT_RETURN_OK;
2840 }
2841
2842 int dlt_user_log_resend_buffer(void)
2843 {
2844         int num,count;
2845     uint8_t buf[DLT_USER_RCVBUF_MAX_SIZE];
2846     int size;
2847         DltReturnValue ret;
2848         
2849         /* Send content of ringbuffer */
2850         DLT_SEM_LOCK();
2851         count = dlt_buffer_get_message_count(&(dlt_user.startup_buffer));
2852         DLT_SEM_FREE();
2853
2854         for (num=0;num<count;num++)
2855         {
2856
2857                 DLT_SEM_LOCK();
2858                 size = dlt_buffer_copy(&(dlt_user.startup_buffer),buf,sizeof(buf));
2859
2860                 if (size>0)
2861                 {
2862 #ifdef DLT_SHM_ENABLE                                           
2863                         dlt_shm_push(&dlt_user.dlt_shm,buf+sizeof(DltUserHeader),size-sizeof(DltUserHeader),0,0,0,0);                   
2864
2865                         /* log to FIFO */
2866                         ret = dlt_user_log_out3(dlt_user.dlt_log_handle, buf,sizeof(DltUserHeader),0,0,0,0);
2867 #else
2868                         /* log to FIFO */
2869                         ret = dlt_user_log_out3(dlt_user.dlt_log_handle, buf,size,0,0,0,0);
2870 #endif
2871
2872                         /* in case of error, keep message in ringbuffer */                        
2873                         if (ret==DLT_RETURN_OK)
2874                         {
2875                                 dlt_buffer_remove(&(dlt_user.startup_buffer));
2876                                 /*
2877                                 DLT_SEM_LOCK();
2878                                 if (dlt_buffer_push(&(dlt_user.startup_buffer), buf, size)==-1)
2879                                 {
2880                                         dlt_log(LOG_ERR,"Error pushing back message to history buffer. Message discarded.\n");
2881                                 }
2882                                 DLT_SEM_FREE();
2883
2884                                 // In case of: data could not be written, set overflow flag
2885                                 if (ret==DLT_RETURN_PIPE_FULL)
2886                                 {
2887                                         dlt_user.overflow = 1;
2888                                 }
2889                                 */
2890                         }
2891                         else
2892                         {
2893                                 /* keep message in ringbuffer */   
2894                                 DLT_SEM_FREE();
2895                                 return -1;
2896                         }
2897                 }
2898                 DLT_SEM_FREE();
2899         }
2900         
2901         return 0;
2902 }
2903
2904 void dlt_user_log_reattach_to_daemon(void)
2905 {
2906         uint32_t num,reregistered=0;
2907
2908         DltContext handle;
2909         DltContextData log_new;
2910
2911     if (dlt_user.dlt_log_handle<0)
2912     {
2913         dlt_user.dlt_log_handle=-1;
2914
2915         /* try to open pipe to dlt daemon */
2916         dlt_user.dlt_log_handle = open(DLT_USER_FIFO, O_WRONLY | O_NONBLOCK);
2917         if (dlt_user.dlt_log_handle > 0)
2918         {
2919             if (dlt_user_log_init(&handle,&log_new)==-1)
2920             {
2921                 return;
2922             }
2923
2924 #ifdef DLT_SHM_ENABLE
2925                         /* init shared memory */
2926                         if (dlt_shm_init_client(&dlt_user.dlt_shm,DLT_SHM_KEY) < 0)
2927                         {
2928                                 sprintf(str,"Loging disabled, Shared memory %d cannot be created!\n",DLT_SHM_KEY);
2929                                 dlt_log(LOG_WARNING, str);
2930                                 //return 0; 
2931                         }   
2932 #endif
2933
2934             dlt_log(LOG_NOTICE, "Logging re-enabled!\n");
2935
2936             /* Re-register application */
2937             if (dlt_user_log_send_register_application()==-1)
2938             {
2939                 return;
2940             }
2941
2942             DLT_SEM_LOCK();
2943
2944             /* Re-register all stored contexts */
2945             for (num=0; num<dlt_user.dlt_ll_ts_num_entries; num++)
2946             {
2947                 /* Re-register stored context */
2948                 if ((dlt_user.appID[0]!='\0') && (dlt_user.dlt_ll_ts[num].contextID[0]!='\0') && (dlt_user.dlt_ll_ts))
2949                 {
2950                     //dlt_set_id(log_new.appID, dlt_user.appID);
2951                     dlt_set_id(handle.contextID, dlt_user.dlt_ll_ts[num].contextID);
2952                     handle.log_level_pos = num;
2953                     log_new.context_description = dlt_user.dlt_ll_ts[num].context_description;
2954
2955                     log_new.log_level = DLT_USER_LOG_LEVEL_NOT_SET;
2956                     log_new.trace_status = DLT_USER_TRACE_STATUS_NOT_SET;
2957
2958                     if (dlt_user_log_send_register_context(&log_new)==-1)
2959                     {
2960                         DLT_SEM_FREE();
2961                         return;
2962                     }
2963
2964                     reregistered=1;
2965                 }
2966             }
2967
2968             DLT_SEM_FREE();
2969
2970             if (reregistered==1)
2971             {
2972                                 dlt_user_log_resend_buffer();
2973             }
2974         }
2975     }
2976 }
2977
2978 int dlt_user_log_send_overflow(void)
2979 {
2980     DltUserHeader userheader;
2981     DltReturnValue ret;
2982
2983     /* set userheader */
2984     if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_OVERFLOW)==-1)
2985     {
2986         return -1;
2987     }
2988
2989     if (dlt_user.dlt_is_file)
2990     {
2991         return 0;
2992     }
2993
2994     /* log to FIFO */
2995     ret=dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), 0, 0);
2996     return ((ret==DLT_RETURN_OK)?0:-1);
2997 }
2998
2999 int dlt_user_check_buffer(int *total_size, int *used_size)
3000 {
3001 #ifdef DLT_SHM_ENABLE
3002         *total_size = dlt_shm_get_total_size(&(dlt_user.dlt_shm));
3003         *used_size = dlt_shm_get_used_size(&(dlt_user.dlt_shm));
3004 #else
3005         *total_size = dlt_buffer_get_total_size(&(dlt_user.startup_buffer));
3006         *used_size = dlt_buffer_get_used_size(&(dlt_user.startup_buffer));
3007 #endif
3008         
3009         return 0; /* ok */
3010 }
3011
3012 #ifdef DLT_TEST_ENABLE
3013 void dlt_user_test_corrupt_user_header(int enable)
3014 {
3015     dlt_user.corrupt_user_header = enable;
3016 }
3017 void dlt_user_test_corrupt_message_size(int enable,int16_t size)
3018 {
3019     dlt_user.corrupt_message_size = enable;
3020     dlt_user.corrupt_message_size_size = size;
3021 }
3022 #endif
3023
3024