afacf036a809a3c030835f3709098b8c24494a02
[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 #include <stdlib.h> /* for getenv(), free(), atexit() */
67 #include <string.h> /* for strcmp(), strncmp(), strlen(), memset(), memcpy() */
68 #include <signal.h> /* for signal(), SIGPIPE, SIG_IGN */
69
70 #if !defined (__WIN32__)
71 #include <syslog.h> /* for LOG_... */
72 #include <semaphore.h>
73 #include <pthread.h>    /* POSIX Threads */
74 #endif
75
76 #include <sys/time.h>
77 #include <math.h>
78
79 #include <sys/stat.h>
80 #include <fcntl.h>
81 #include <errno.h>
82
83 #include <sys/uio.h> /* writev() */
84
85 #include <limits.h>
86
87 #include "dlt_user.h"
88 #include "dlt_user_shared.h"
89 #include "dlt_user_shared_cfg.h"
90 #include "dlt_user_cfg.h"
91
92 static DltUser dlt_user;
93 static int dlt_user_initialised = 0;
94
95 static char str[DLT_USER_BUFFER_LENGTH];
96
97 static sem_t dlt_mutex;
98 static pthread_t dlt_receiverthread_handle;
99 static pthread_attr_t dlt_receiverthread_attr;
100
101 /* Segmented Network Trace */
102 #define DLT_MAX_TRACE_SEGMENT_SIZE 1024
103 #define DLT_MESSAGE_QUEUE_NAME "/dlt_message_queue"
104 #define DLT_DELAYED_RESEND_INDICATOR_PATTERN 0xFFFF
105
106 /* Mutex to wait on while message queue is not initialized */
107 pthread_mutex_t mq_mutex;
108 pthread_cond_t  mq_init_condition;
109
110 /* Structure to pass data to segmented thread */
111 typedef struct {
112         DltContext                      *handle;
113         uint16_t                        id;
114         DltNetworkTraceType     nw_trace_type;
115         uint16_t                        header_len;
116         void                            *header;
117         uint16_t                        payload_len;
118         void                            *payload;
119 } s_segmented_data;
120
121 /* Function prototypes for internally used functions */
122 static void dlt_user_receiverthread_function(void *ptr);
123 static void dlt_user_atexit_handler(void);
124 static int dlt_user_log_init(DltContext *handle, DltContextData *log);
125 static DltReturnValue dlt_user_log_send_log(DltContextData *log, int mtype);
126 static int dlt_user_log_send_register_application(void);
127 static int dlt_user_log_send_unregister_application(void);
128 static int dlt_user_log_send_register_context(DltContextData *log);
129 static int dlt_user_log_send_unregister_context(DltContextData *log);
130 static int dlt_send_app_ll_ts_limit(const char *appid, DltLogLevelType loglevel, DltTraceStatusType tracestatus);
131 static int dlt_user_log_send_log_mode(DltUserLogMode mode);
132 static int dlt_user_print_msg(DltMessage *msg, DltContextData *log);
133 static int dlt_user_log_check_user_message(void);
134 static void dlt_user_log_reattach_to_daemon(void);
135 static int dlt_user_log_send_overflow(void);
136 static void dlt_user_trace_network_segmented_thread(void *unused);
137 static void dlt_user_trace_network_segmented_thread_segmenter(s_segmented_data *data);
138 static int dlt_user_queue_resend(void);
139
140 int dlt_user_check_library_version(const char *user_major_version,const char *user_minor_version){
141
142         char str[200];
143         char lib_major_version[DLT_USER_MAX_LIB_VERSION_LENGTH];
144         char lib_minor_version[DLT_USER_MAX_LIB_VERSION_LENGTH];
145
146         dlt_get_major_version( lib_major_version);
147         dlt_get_minor_version( lib_minor_version);
148
149         if( (strcmp(lib_major_version,user_major_version)!=0) || (strcmp(lib_minor_version,user_minor_version)!=0))
150         {
151                 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);
152                 dlt_log(LOG_WARNING, str);
153                 return -1;
154         }
155         return 0;
156 }
157
158 int dlt_init(void)
159 {
160     char filename[DLT_USER_MAX_FILENAME_LENGTH];
161     int ret;
162
163     dlt_user_initialised = 1;
164
165     /* Initialize common part of dlt_init()/dlt_init_file() */
166     if (dlt_init_common()==-1)
167     {
168         dlt_user_initialised = 0;
169         return -1;
170     }
171
172     dlt_user.dlt_is_file = 0;
173     dlt_user.overflow = 0;
174 #ifdef DLT_SHM_ENABLE
175         memset(&(dlt_user.dlt_shm),0,sizeof(DltShm));
176 #endif
177
178     /* create and open DLT user FIFO */
179     sprintf(filename,"%s/dlt%d",DLT_USER_DIR,getpid());
180      
181     /* Try to delete existing pipe, ignore result of unlink */
182     unlink(filename);
183     
184     ret=mkfifo(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH  | S_IWOTH );
185     if (ret==-1)
186     {
187         sprintf(str,"Loging disabled, FIFO user %s cannot be created!\n",filename);
188         dlt_log(LOG_WARNING, str);
189         /* return 0; */ /* removed to prevent error, when FIFO already exists */
190     }
191
192     dlt_user.dlt_user_handle = open(filename, O_RDWR | O_CLOEXEC);
193     if (dlt_user.dlt_user_handle == DLT_FD_INIT)
194     {
195         sprintf(str,"Loging disabled, FIFO user %s cannot be opened!\n",filename);
196         dlt_log(LOG_WARNING, str);
197         unlink(filename);
198         return 0;
199     }
200
201     /* open DLT output FIFO */
202     dlt_user.dlt_log_handle = open(DLT_USER_FIFO, O_WRONLY | O_NONBLOCK | O_CLOEXEC );
203     if (dlt_user.dlt_log_handle==-1)
204     {
205         sprintf(str,"Loging disabled, FIFO %s cannot be opened with open()!\n",DLT_USER_FIFO);
206         dlt_log(LOG_WARNING, str);
207         //return 0;
208     }
209         else
210         {
211 #ifdef DLT_SHM_ENABLE
212                 /* init shared memory */
213                 if (dlt_shm_init_client(&(dlt_user.dlt_shm),DLT_SHM_KEY) < 0)
214                 {
215                         sprintf(str,"Loging disabled, Shared memory %d cannot be created!\n",DLT_SHM_KEY);
216                         dlt_log(LOG_WARNING, str);
217                         //return 0; 
218                 }   
219 #endif
220         }
221                 
222
223     if (dlt_receiver_init(&(dlt_user.receiver),dlt_user.dlt_user_handle, DLT_USER_RCVBUF_MAX_SIZE)==-1)
224         {
225         dlt_user_initialised = 0;
226         return -1;
227     }
228
229     /* Start receiver thread */
230     if (pthread_create(&(dlt_receiverthread_handle),
231                        0,
232                        (void *) &dlt_user_receiverthread_function,
233                        0)!=0)
234         {
235                 if (pthread_attr_destroy(&dlt_receiverthread_attr)!=0)
236                 {
237                         dlt_log(LOG_WARNING, "Can't destroy thread attributes!\n");
238                 }
239
240                 dlt_log(LOG_CRIT, "Can't create receiver thread!\n");
241                 dlt_user_initialised = 0;
242         return -1;
243         }
244
245     if (pthread_attr_destroy(&dlt_receiverthread_attr)!=0)
246         {
247                 dlt_log(LOG_WARNING, "Can't destroy thread attributes!\n");
248         }
249
250     /* These will be lazy initialized only when needed */
251     dlt_user.dlt_segmented_queue_read_handle = -1;
252     dlt_user.dlt_segmented_queue_write_handle = -1;
253
254     /* Wait mutext for segmented thread */
255     pthread_mutex_init(&mq_mutex, NULL);
256     pthread_cond_init(&mq_init_condition, NULL);
257
258     /* Start the segmented thread */
259         if(pthread_create(&(dlt_user.dlt_segmented_nwt_handle), NULL,
260            (void *)dlt_user_trace_network_segmented_thread, NULL))
261         {
262         dlt_log(LOG_CRIT, "Can't start segmented thread!\n");
263         return -1;
264         }
265
266         return 0;
267 }
268
269 int dlt_init_file(const char *name)
270 {
271     dlt_user_initialised = 1;
272
273     /* Initialize common part of dlt_init()/dlt_init_file() */
274     if (dlt_init_common()==-1)
275     {
276         dlt_user_initialised = 0;
277         return -1;
278     }
279
280     dlt_user.dlt_is_file = 1;
281
282     /* open DLT output file */
283     dlt_user.dlt_log_handle = open(name,O_WRONLY|O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); /* mode: wb */
284     if (dlt_user.dlt_log_handle == -1)
285     {
286         sprintf(str,"Log file %s cannot be opened!\n",name);
287         dlt_log(LOG_ERR, str);
288         return -1;
289     }
290
291     return 0;
292 }
293
294 int dlt_init_message_queue(void)
295 {
296         pthread_mutex_lock(&mq_mutex);
297         if(dlt_user.dlt_segmented_queue_read_handle >= 0 &&
298            dlt_user.dlt_segmented_queue_write_handle >= 0)
299         {
300                 // Already intialized
301                 pthread_mutex_unlock(&mq_mutex);
302                 return 0;
303         }
304
305     /* Generate per process name for queue */
306     char queue_name[NAME_MAX];
307     sprintf(queue_name, "%s.%d", DLT_MESSAGE_QUEUE_NAME, getpid());
308
309     /* Maximum queue size is 10, limit to size of pointers */
310     struct mq_attr mqatr;
311     mqatr.mq_flags              = 0;
312     mqatr.mq_maxmsg             = 10;
313     mqatr.mq_msgsize    = sizeof(s_segmented_data *);
314     mqatr.mq_curmsgs    = 0;
315
316     /**
317      * Create the message queue. It must be newly created
318      * if old one was left by a crashing process.
319      * */
320     dlt_user.dlt_segmented_queue_read_handle = mq_open(queue_name, O_CREAT| O_RDONLY | O_EXCL,
321                 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, &mqatr);
322     if(dlt_user.dlt_segmented_queue_read_handle < 0)
323     {
324         if(errno == EEXIST)
325         {
326                 dlt_log(LOG_WARNING, "Old message queue exists, trying to delete.\n");
327                 if(mq_unlink(queue_name) < 0)
328                 {
329                         dlt_log(LOG_CRIT, "Could not delete existing message queue!\n");
330                         dlt_log(LOG_CRIT, strerror(errno));
331                 }
332                 else // Retry
333                 {
334                         dlt_user.dlt_segmented_queue_read_handle = mq_open(queue_name, O_CREAT| O_RDONLY | O_EXCL,
335                                         S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, &mqatr);
336                 }
337         }
338         if(dlt_user.dlt_segmented_queue_read_handle < 0)
339         {
340                 dlt_log(LOG_CRIT, "Can't create message queue read handle!\n");
341                 dlt_log(LOG_CRIT, strerror(errno));
342                 pthread_mutex_unlock(&mq_mutex);
343                 return -1;
344         }
345     }
346
347     dlt_user.dlt_segmented_queue_write_handle = mq_open(queue_name, O_WRONLY|O_NONBLOCK);
348     if(dlt_user.dlt_segmented_queue_write_handle < 0)
349     {
350         dlt_log(LOG_CRIT, "Can't open message queue write handle!\n");
351         dlt_log(LOG_CRIT, strerror(errno));
352         pthread_mutex_unlock(&mq_mutex);
353         return -1;
354     }
355
356     pthread_cond_signal(&mq_init_condition);
357     pthread_mutex_unlock(&mq_mutex);
358     return 0;
359 }
360
361 int dlt_init_common(void)
362 {
363     char *env_local_print;
364
365     /* Binary semaphore for threads */
366     if (sem_init(&dlt_mutex, 0, 1)==-1)
367     {
368         dlt_user_initialised = 0;
369         return -1;
370     }
371
372         /* set to unknown state of connected client */
373         dlt_user.log_state = -1;
374
375     dlt_user.dlt_log_handle=-1;
376     dlt_user.dlt_user_handle=DLT_FD_INIT;
377
378     dlt_set_id(dlt_user.ecuID,DLT_USER_DEFAULT_ECU_ID);
379     dlt_set_id(dlt_user.appID,"");
380
381     dlt_user.application_description = 0;
382
383     /* Verbose mode is enabled by default */
384     dlt_user.verbose_mode = 1;
385
386     /* Local print is disabled by default */
387     dlt_user.enable_local_print = 0;
388
389     dlt_user.local_print_mode = DLT_PM_UNSET;
390
391     env_local_print = getenv(DLT_USER_ENV_LOCAL_PRINT_MODE);
392     if (env_local_print)
393     {
394         if (strcmp(env_local_print,"AUTOMATIC")==0)
395         {
396             dlt_user.local_print_mode = DLT_PM_AUTOMATIC;
397         }
398         else if (strcmp(env_local_print,"FORCE_ON")==0)
399         {
400             dlt_user.local_print_mode = DLT_PM_FORCE_ON;
401         }
402         else if (strcmp(env_local_print,"FORCE_OFF")==0)
403         {
404             dlt_user.local_print_mode = DLT_PM_FORCE_OFF;
405         }
406     }
407
408     /* Initialize LogLevel/TraceStatus field */
409     DLT_SEM_LOCK();
410     dlt_user.dlt_ll_ts = 0;
411     dlt_user.dlt_ll_ts_max_num_entries = 0;
412     dlt_user.dlt_ll_ts_num_entries = 0;
413
414     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)
415     {
416                 dlt_user_initialised = 0;
417         DLT_SEM_FREE();
418         return -1;
419     }
420     DLT_SEM_FREE();
421
422     signal(SIGPIPE,SIG_IGN);                  /* ignore pipe signals */
423
424     atexit(dlt_user_atexit_handler);
425
426 #ifdef DLT_TEST_ENABLE
427     dlt_user.corrupt_user_header = 0;
428     dlt_user.corrupt_message_size = 0;
429     dlt_user.corrupt_message_size_size = 0;
430 #endif
431
432     return 0;
433 }
434
435 void dlt_user_atexit_handler(void)
436 {
437
438         /* Try to resend potential log messages in the user buffer */
439         int count = dlt_user_atexit_blow_out_user_buffer();
440
441         if(count != 0){
442                 char tmp[256];
443                 sprintf(tmp,"Lost log messages in user buffer when exiting: %i\n",count);
444                 dlt_log(LOG_ERR, tmp);
445         }
446
447     /* Unregister app (this also unregisters all contexts in daemon) */
448     /* Ignore return value */
449     dlt_unregister_app();
450
451     /* Cleanup */
452     /* Ignore return value */
453     dlt_free();
454 }
455
456 int dlt_user_atexit_blow_out_user_buffer(void){
457
458         int count,ret;
459
460         uint32_t exitTime = dlt_uptime() + DLT_USER_ATEXIT_RESEND_BUFFER_EXIT_TIMEOUT;
461
462         while(dlt_uptime() < exitTime ){
463
464                 ret = dlt_user_log_resend_buffer();
465
466                 if(ret == 0)
467                 {
468                                 return 0;
469                 }
470
471                 usleep(DLT_USER_ATEXIT_RESEND_BUFFER_SLEEP);
472         }
473
474         DLT_SEM_LOCK();
475         count = dlt_buffer_get_message_count(&(dlt_user.startup_buffer));
476         DLT_SEM_FREE();
477
478         return count;
479 }
480
481 int dlt_free(void)
482 {
483     uint32_t i;
484         char filename[DLT_USER_MAX_FILENAME_LENGTH];
485
486     if (dlt_user_initialised==0)
487     {
488         return -1;
489     }
490
491     if (dlt_receiverthread_handle)
492     {
493         /* Ignore return value */
494         pthread_cancel(dlt_receiverthread_handle);
495     }
496
497     if (dlt_user.dlt_user_handle!=DLT_FD_INIT)
498     {
499         sprintf(filename,"%s/dlt%d",DLT_USER_DIR,getpid());
500
501         close(dlt_user.dlt_user_handle);
502         dlt_user.dlt_user_handle=DLT_FD_INIT;
503
504         unlink(filename);
505     }
506
507 #ifdef DLT_SHM_ENABLE
508         /* free shared memory */
509         dlt_shm_free_client(&dlt_user.dlt_shm);
510 #endif
511
512     if (dlt_user.dlt_log_handle!=-1)
513     {
514         /* close log file/output fifo to daemon */
515         close(dlt_user.dlt_log_handle);
516         dlt_user.dlt_log_handle = -1;
517     }
518
519         /* Ignore return value */
520     dlt_receiver_free(&(dlt_user.receiver));
521
522         /* Ignore return value */
523     dlt_buffer_free_dynamic(&(dlt_user.startup_buffer));
524
525     DLT_SEM_LOCK();
526     if (dlt_user.dlt_ll_ts)
527     {
528         for (i=0;i<dlt_user.dlt_ll_ts_max_num_entries;i++)
529         {
530             if (dlt_user.dlt_ll_ts[i].injection_table!=0)
531             {
532                 free(dlt_user.dlt_ll_ts[i].injection_table);
533                 dlt_user.dlt_ll_ts[i].injection_table = 0;
534             }
535             dlt_user.dlt_ll_ts[i].nrcallbacks     = 0;
536         }
537
538         free(dlt_user.dlt_ll_ts);
539         dlt_user.dlt_ll_ts = 0;
540         dlt_user.dlt_ll_ts_max_num_entries = 0;
541         dlt_user.dlt_ll_ts_num_entries = 0;
542     }
543     DLT_SEM_FREE();
544
545     if (dlt_user.dlt_segmented_nwt_handle)
546     {
547         pthread_cancel(dlt_user.dlt_segmented_nwt_handle);
548     }
549
550     char queue_name[NAME_MAX];
551     sprintf(queue_name, "%s.%d", DLT_MESSAGE_QUEUE_NAME, getpid());
552
553     /**
554      * Ignore errors from these, to not to spam user if dlt_free
555      * is accidentally called multiple times.
556      */
557     mq_close(dlt_user.dlt_segmented_queue_write_handle);
558     mq_close(dlt_user.dlt_segmented_queue_read_handle);
559     mq_unlink(queue_name);
560
561     dlt_user_initialised = 0;
562
563     return 0;
564 }
565
566 int dlt_check_library_version(const char * user_major_version,const char * user_minor_version)
567 {
568         return dlt_user_check_library_version(user_major_version, user_minor_version);
569 }
570
571 int dlt_register_app(const char *appid, const char * description)
572 {
573     int ret;
574
575     if (dlt_user_initialised==0)
576     {
577         if (dlt_init()<0)
578         {
579             return -1;
580         }
581     }
582
583     if ((appid==0) || (appid[0]=='\0'))
584     {
585         return -1;
586     }
587
588     /* check if application already registered */
589     /* if yes do not register again */
590     if(appid[1]==0)
591     {
592        if(appid[0]==dlt_user.appID[0])
593              return 0;
594     }
595     else if(appid[2]==0)
596     {
597        if(appid[0]==dlt_user.appID[0] &&
598           appid[1]==dlt_user.appID[1])
599              return 0;
600     }
601     else if(appid[3]==0)
602     {
603        if(appid[0]==dlt_user.appID[0] &&
604           appid[1]==dlt_user.appID[1] &&
605           appid[2]==dlt_user.appID[2])
606              return 0;
607     }
608     else
609     {
610        if(appid[0]==dlt_user.appID[0] &&
611           appid[1]==dlt_user.appID[1] &&
612           appid[2]==dlt_user.appID[2] &&
613           appid[3]==dlt_user.appID[3])
614              return 0;
615     }
616
617     DLT_SEM_LOCK();
618
619     /* Store locally application id and application description */
620     dlt_set_id(dlt_user.appID, appid);
621
622     if (dlt_user.application_description!=0)
623     {
624         free(dlt_user.application_description);
625     }
626
627     dlt_user.application_description = 0;
628
629     if (description!=0)
630     {
631         size_t desc_len = strlen(description);
632         dlt_user.application_description= malloc(desc_len+1);
633         if (dlt_user.application_description){
634             strncpy(dlt_user.application_description, description, desc_len);
635
636             /* Terminate transmitted string with 0 */
637             dlt_user.application_description[desc_len]='\0';
638         }
639         else
640         {
641                 DLT_SEM_FREE();
642                 return -1;
643         }
644     }
645
646     DLT_SEM_FREE();
647
648     ret = dlt_user_log_send_register_application();
649
650     return ret;
651 }
652 int dlt_register_context(DltContext *handle, const char *contextid, const char * description)
653 {
654     if (dlt_user_initialised==0)
655     {
656         if (dlt_init()<0)
657         {
658             return -1;
659         }
660     }
661
662     DLT_SEM_LOCK();
663
664     if (dlt_user.appID[0]=='\0')
665     {
666         dlt_log(LOG_ERR, "no application registered!\n");
667
668         DLT_SEM_FREE();
669         return -1;
670     }
671
672     if ((contextid==0) || (contextid[0]=='\0'))
673     {
674         DLT_SEM_FREE();
675         return -1;
676     }
677
678     DLT_SEM_FREE();
679
680     return dlt_register_context_ll_ts(handle, contextid, description, DLT_USER_LOG_LEVEL_NOT_SET, DLT_USER_TRACE_STATUS_NOT_SET);
681 }
682
683 int dlt_register_context_ll_ts(DltContext *handle, const char *contextid, const char * description, int loglevel, int tracestatus)
684 {
685     DltContextData log;
686     uint32_t i;
687     int registered,ret;
688     char ctid[DLT_ID_SIZE+1];
689
690     if (dlt_user_initialised==0)
691     {
692         if (dlt_init()<0)
693         {
694             return -1;
695         }
696     }
697
698     DLT_SEM_LOCK();
699
700     if (dlt_user.appID[0]=='\0')
701     {
702         dlt_log(LOG_ERR, "no application registered!\n");
703
704         DLT_SEM_FREE();
705         return -1;
706     }
707
708     DLT_SEM_FREE();
709
710     if ((contextid==0) || (contextid[0]=='\0'))
711     {
712         return -1;
713     }
714
715     if ((loglevel<DLT_USER_LOG_LEVEL_NOT_SET) || (loglevel>DLT_LOG_VERBOSE) || (loglevel==DLT_LOG_DEFAULT))
716     {
717         return -1;
718     }
719
720     if ((tracestatus<DLT_USER_TRACE_STATUS_NOT_SET) || (tracestatus>DLT_TRACE_STATUS_ON) || (tracestatus==DLT_TRACE_STATUS_DEFAULT))
721     {
722         return -1;
723     }
724
725     if (dlt_user_log_init(handle, &log)==-1)
726     {
727         return -1;
728     }
729
730     /* Reset message counter */
731     handle->mcnt = 0;
732
733     /* Store context id in log level/trace status field */
734
735     /* Check if already registered, else register context */
736     DLT_SEM_LOCK();
737
738     registered=0;
739     for (i=0;i<dlt_user.dlt_ll_ts_num_entries;i++)
740     {
741         if (dlt_user.dlt_ll_ts)
742         {
743             if (memcmp(dlt_user.dlt_ll_ts[i].contextID, contextid,DLT_ID_SIZE)==0)
744             {
745                 registered=1;
746
747                 memset(ctid,0,(DLT_ID_SIZE+1));
748                 dlt_print_id(ctid, contextid);
749
750                 sprintf(str,"context '%s' already registered!\n",ctid);
751                 dlt_log(LOG_WARNING, str);
752
753                 break;
754             }
755         }
756     }
757
758     if (registered==0)
759     {
760         /* Allocate or expand context array */
761         if (dlt_user.dlt_ll_ts == 0)
762         {
763             dlt_user.dlt_ll_ts = (dlt_ll_ts_type*) malloc(sizeof(dlt_ll_ts_type)*DLT_USER_CONTEXT_ALLOC_SIZE);
764             if (dlt_user.dlt_ll_ts==0)
765             {
766                 DLT_SEM_FREE();
767                 return -1;
768             }
769
770             dlt_user.dlt_ll_ts_max_num_entries = DLT_USER_CONTEXT_ALLOC_SIZE;
771
772             /* Initialize new entries */
773             for (i=0;i<dlt_user.dlt_ll_ts_max_num_entries;i++)
774             {
775                 dlt_set_id(dlt_user.dlt_ll_ts[i].contextID,"");
776
777                 /* At startup, logging and tracing is locally enabled */
778                 /* the correct log level/status is set after received from daemon */
779                 dlt_user.dlt_ll_ts[i].log_level    = DLT_USER_INITIAL_LOG_LEVEL;
780                 dlt_user.dlt_ll_ts[i].trace_status = DLT_USER_INITIAL_TRACE_STATUS;
781
782                 dlt_user.dlt_ll_ts[i].context_description = 0;
783
784                 dlt_user.dlt_ll_ts[i].injection_table = 0;
785                 dlt_user.dlt_ll_ts[i].nrcallbacks     = 0;
786             }
787         }
788         else
789         {
790             if ((dlt_user.dlt_ll_ts_num_entries%DLT_USER_CONTEXT_ALLOC_SIZE)==0)
791             {
792                 /* allocate memory in steps of DLT_USER_CONTEXT_ALLOC_SIZE, e.g. 500 */
793                 dlt_ll_ts_type *old_ll_ts;
794                 uint32_t old_max_entries;
795
796                 old_ll_ts = dlt_user.dlt_ll_ts;
797                 old_max_entries = dlt_user.dlt_ll_ts_max_num_entries;
798
799                 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;
800                 dlt_user.dlt_ll_ts = (dlt_ll_ts_type*) malloc(sizeof(dlt_ll_ts_type)*
801                                      dlt_user.dlt_ll_ts_max_num_entries);
802                 if (dlt_user.dlt_ll_ts==0)
803                 {
804                         dlt_user.dlt_ll_ts = old_ll_ts;
805                         dlt_user.dlt_ll_ts_max_num_entries = old_max_entries;
806                     DLT_SEM_FREE();
807                     return -1;
808                 }
809
810                 memcpy(dlt_user.dlt_ll_ts,old_ll_ts,sizeof(dlt_ll_ts_type)*dlt_user.dlt_ll_ts_num_entries);
811                 free(old_ll_ts);
812
813                 /* Initialize new entries */
814                 for (i=dlt_user.dlt_ll_ts_num_entries;i<dlt_user.dlt_ll_ts_max_num_entries;i++)
815                 {
816                     dlt_set_id(dlt_user.dlt_ll_ts[i].contextID,"");
817
818                     /* At startup, logging and tracing is locally enabled */
819                     /* the correct log level/status is set after received from daemon */
820                     dlt_user.dlt_ll_ts[i].log_level    = DLT_USER_INITIAL_LOG_LEVEL;
821                     dlt_user.dlt_ll_ts[i].trace_status = DLT_USER_INITIAL_TRACE_STATUS;
822
823                     dlt_user.dlt_ll_ts[i].context_description = 0;
824
825                     dlt_user.dlt_ll_ts[i].injection_table = 0;
826                     dlt_user.dlt_ll_ts[i].nrcallbacks     = 0;
827                 }
828             }
829         }
830
831         /* Store locally context id and context description */
832         dlt_set_id(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].contextID, contextid);
833
834         if (dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description!=0)
835         {
836             free(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description);
837         }
838
839         dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description = 0;
840
841         if (description!=0)
842         {
843                 size_t desc_len = strlen(description);
844             dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description = malloc(desc_len+1);
845             if(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description == 0)
846             {
847                 DLT_SEM_FREE();
848                 return -1;
849             }
850
851             strncpy(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description, description, desc_len);
852
853             /* Terminate transmitted string with 0 */
854             dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description[desc_len]='\0';
855         }
856
857         if (loglevel!=DLT_USER_LOG_LEVEL_NOT_SET)
858         {
859             dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].log_level = loglevel;
860         }
861
862         if (tracestatus!=DLT_USER_TRACE_STATUS_NOT_SET)
863         {
864             dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].trace_status = tracestatus;
865         }
866
867         /* Prepare transfer struct */
868         //dlt_set_id(log->appID, dlt_user.appID);
869         dlt_set_id(handle->contextID, contextid);
870         handle->log_level_pos = dlt_user.dlt_ll_ts_num_entries;
871
872         log.context_description = dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description;
873
874         if (loglevel!=DLT_USER_LOG_LEVEL_NOT_SET)
875         {
876             log.log_level = loglevel;
877         }
878         else
879         {
880             log.log_level = DLT_USER_LOG_LEVEL_NOT_SET;
881         }
882
883         if (tracestatus!=DLT_USER_TRACE_STATUS_NOT_SET)
884         {
885             log.trace_status = tracestatus;
886         }
887         else
888         {
889             log.trace_status = DLT_USER_TRACE_STATUS_NOT_SET;
890         }
891
892         dlt_user.dlt_ll_ts_num_entries++;
893
894         DLT_SEM_FREE();
895
896         ret=dlt_user_log_send_register_context(&log);
897     }
898     else
899     {
900         DLT_SEM_FREE();
901
902         ret=-1;
903     }
904
905     return ret;
906 }
907
908 int dlt_unregister_app(void)
909 {
910     int ret;
911
912     if (dlt_user_initialised==0)
913     {
914         return -1;
915     }
916
917     /* Inform daemon to unregister application and all of its contexts */
918     ret = dlt_user_log_send_unregister_application();
919
920     DLT_SEM_LOCK();
921
922     /* Clear and free local stored application information */
923     dlt_set_id(dlt_user.appID, "");
924
925     if (dlt_user.application_description!=0)
926     {
927         free(dlt_user.application_description);
928     }
929
930     dlt_user.application_description = 0;
931
932     DLT_SEM_FREE();
933
934     return ret;
935 }
936
937 int dlt_unregister_context(DltContext *handle)
938 {
939     DltContextData log;
940     int ret;
941
942     if (dlt_user_initialised==0)
943     {
944         return -1;
945     }
946
947     if (dlt_user_log_init(handle, &log) == -1)
948     {
949                 return -1;
950     }
951
952     DLT_SEM_LOCK();
953
954     if (dlt_user.dlt_ll_ts)
955     {
956         /* Clear and free local stored context information */
957         dlt_set_id(dlt_user.dlt_ll_ts[handle->log_level_pos].contextID, "");
958
959         dlt_user.dlt_ll_ts[handle->log_level_pos].log_level = DLT_USER_INITIAL_LOG_LEVEL;
960         dlt_user.dlt_ll_ts[handle->log_level_pos].trace_status = DLT_USER_INITIAL_TRACE_STATUS;
961
962         if (dlt_user.dlt_ll_ts[handle->log_level_pos].context_description!=0)
963         {
964             free(dlt_user.dlt_ll_ts[handle->log_level_pos].context_description);
965         }
966
967         dlt_user.dlt_ll_ts[handle->log_level_pos].context_description = 0;
968
969         if (dlt_user.dlt_ll_ts[handle->log_level_pos].injection_table)
970         {
971             free(dlt_user.dlt_ll_ts[handle->log_level_pos].injection_table);
972             dlt_user.dlt_ll_ts[handle->log_level_pos].injection_table = 0;
973         }
974
975         dlt_user.dlt_ll_ts[handle->log_level_pos].nrcallbacks     = 0;
976     }
977
978     DLT_SEM_FREE();
979
980     /* Inform daemon to unregister context */
981     ret = dlt_user_log_send_unregister_context(&log);
982
983     return ret;
984 }
985
986 int dlt_set_application_ll_ts_limit(DltLogLevelType loglevel, DltTraceStatusType tracestatus)
987 {
988     uint32_t i;
989     int ret;
990
991     if (dlt_user_initialised==0)
992     {
993         if (dlt_init()<0)
994         {
995             return -1;
996         }
997     }
998
999     /* Removed because of DltLogLevelType and DltTraceStatusType
1000
1001     if ((loglevel<DLT_LOG_DEFAULT) || (loglevel>DLT_LOG_VERBOSE))
1002     {
1003         return -1;
1004     }
1005
1006     if ((tracestatus<DLT_TRACE_STATUS_DEFAULT) || (tracestatus>DLT_TRACE_STATUS_ON))
1007     {
1008         return -1;
1009     }
1010
1011     if (dlt_user.dlt_ll_ts==0)
1012     {
1013         return -1;
1014     }
1015
1016     */
1017
1018     DLT_SEM_LOCK();
1019
1020     /* Update local structures */
1021     for (i=0; i<dlt_user.dlt_ll_ts_num_entries;i++)
1022     {
1023         dlt_user.dlt_ll_ts[i].log_level = loglevel;
1024         dlt_user.dlt_ll_ts[i].trace_status = tracestatus;
1025     }
1026
1027     DLT_SEM_FREE();
1028
1029     /* Inform DLT server about update */
1030     ret = dlt_send_app_ll_ts_limit(dlt_user.appID, loglevel, tracestatus);
1031
1032     return ret;
1033 }
1034
1035 int dlt_get_log_state()
1036 {
1037         return dlt_user.log_state;
1038 }
1039
1040 int dlt_set_log_mode(DltUserLogMode mode)
1041 {
1042     if (dlt_user_initialised==0)
1043     {
1044         if (dlt_init()<0)
1045         {
1046             return -1;
1047         }
1048     }
1049
1050         return dlt_user_log_send_log_mode(mode);
1051 }
1052
1053 int dlt_forward_msg(void *msgdata,size_t size)
1054 {
1055     DltUserHeader userheader;
1056     DltReturnValue ret;
1057
1058     if ((msgdata==0) || (size==0))
1059     {
1060         return -1;
1061     }
1062
1063     if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG)==-1)
1064     {
1065         /* Type of internal user message; same value for Trace messages */
1066         return -1;
1067     }
1068
1069     if (dlt_user.dlt_is_file)
1070     {
1071         /* log to file */
1072         ret = dlt_user_log_out2(dlt_user.dlt_log_handle, msgdata, size, 0, 0);
1073         return ((ret==DLT_RETURN_OK)?0:-1);
1074     }
1075     else
1076     {
1077         /* Reattach to daemon if neccesary */
1078         dlt_user_log_reattach_to_daemon();
1079
1080         if (dlt_user.overflow)
1081         {
1082             if (dlt_user_log_send_overflow()==0)
1083             {
1084                 dlt_user.overflow=0;
1085             }
1086         }
1087
1088         /* log to FIFO */
1089         ret = dlt_user_log_out3(dlt_user.dlt_log_handle,
1090                                 &(userheader), sizeof(DltUserHeader),
1091                                 msgdata, size, 0, 0);
1092
1093         /* store message in ringbuffer, if an error has occured */
1094         if (ret!=DLT_RETURN_OK)
1095         {
1096             DLT_SEM_LOCK();
1097
1098             if (dlt_buffer_push3(&(dlt_user.startup_buffer),
1099                                 (unsigned char *)&(userheader), sizeof(DltUserHeader),
1100                                  msgdata, size, 0, 0)==-1)
1101                         {
1102                                 dlt_log(LOG_ERR,"Storing message to history buffer failed! Message discarded.\n");
1103                         }
1104
1105             DLT_SEM_FREE();
1106
1107             if(dlt_user_queue_resend() < 0 && dlt_user.dlt_log_handle >= 0)
1108             {
1109                 dlt_log(LOG_WARNING, "Failed to queue resending.\n");
1110             }
1111         }
1112
1113         switch (ret)
1114         {
1115         case DLT_RETURN_PIPE_FULL:
1116         {
1117             /* data could not be written */
1118             dlt_user.overflow = 1;
1119             return -1;
1120         }
1121         case DLT_RETURN_PIPE_ERROR:
1122         {
1123             /* handle not open or pipe error */
1124             close(dlt_user.dlt_log_handle);
1125             dlt_user.dlt_log_handle = -1;
1126
1127             return -1;
1128         }
1129         case DLT_RETURN_ERROR:
1130         {
1131             /* other error condition */
1132             return -1;
1133         }
1134         case DLT_RETURN_OK:
1135         {
1136                 return 0;
1137         }
1138                 default:
1139                 {
1140                         /* This case should not occur */
1141                         return -1;
1142                 }
1143         }
1144     }
1145
1146     return 0;
1147 }
1148
1149 /* ********************************************************************************************* */
1150
1151 inline int dlt_user_log_write_start(DltContext *handle, DltContextData *log,DltLogLevelType loglevel)
1152 {
1153     return dlt_user_log_write_start_id(handle,log,loglevel,DLT_USER_DEFAULT_MSGID);
1154 }
1155
1156 int dlt_user_log_write_start_id(DltContext *handle, DltContextData *log,DltLogLevelType loglevel, uint32_t messageid)
1157 {
1158         if(dlt_user_initialised==0)
1159         {
1160                 if (dlt_init()<0)
1161                 {
1162                         return -1;
1163                 }
1164         }
1165     if (log==0)
1166     {
1167         return -1;
1168     }
1169
1170     if (dlt_user_log_init(handle, log)==-1)
1171     {
1172                 return -1;
1173     }
1174
1175     if (dlt_user.dlt_ll_ts==0)
1176     {
1177         return -1;
1178     }
1179
1180     DLT_SEM_LOCK();
1181
1182     if ((loglevel<=(int)(dlt_user.dlt_ll_ts[handle->log_level_pos].log_level) ) && (loglevel!=0))
1183     {
1184         DLT_SEM_FREE();
1185                 log->args_num = 0;
1186         log->log_level = loglevel;
1187
1188         /* In non-verbose mode, insert message id */
1189         if (dlt_user.verbose_mode==0)
1190         {
1191             if ((sizeof(uint32_t))>DLT_USER_BUF_MAX_SIZE)
1192             {
1193                 return -1;
1194             }
1195             /* Write message id */
1196             memcpy(log->buffer,&(messageid),sizeof(uint32_t));
1197             log->size = sizeof(uint32_t);
1198
1199             /* as the message id is part of each message in non-verbose mode,
1200                it doesn't increment the argument counter in extended header (if used) */
1201         }
1202         else log->size=0;
1203         return 1;
1204     }
1205     else
1206     {
1207         DLT_SEM_FREE();
1208         return 0;
1209     }
1210
1211     return -1;
1212 }
1213
1214 int dlt_user_log_write_finish(DltContextData *log)
1215 {
1216     if (log==0)
1217     {
1218         return -1;
1219     }
1220
1221     return dlt_user_log_send_log(log, DLT_TYPE_LOG) < 0 ? -1 : 0;
1222 }
1223
1224 int dlt_user_log_write_raw(DltContextData *log,void *data,uint16_t length)
1225 {
1226     uint16_t arg_size;
1227     uint32_t type_info;
1228
1229     if (log==0)
1230     {
1231         return -1;
1232     }
1233
1234     if ((log->size+length+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1235     {
1236         return -1;
1237     }
1238
1239     if (dlt_user.verbose_mode)
1240     {
1241         if ((log->size+length+sizeof(uint32_t)+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1242         {
1243             return -1;
1244         }
1245
1246         /* Transmit type information */
1247         type_info = DLT_TYPE_INFO_RAWD;
1248
1249         memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1250         log->size += sizeof(uint32_t);
1251
1252     }
1253
1254     /* First transmit length of raw data, then the raw data itself */
1255     arg_size = (uint16_t)length;
1256
1257     memcpy((log->buffer)+log->size,&(arg_size),sizeof(uint16_t));
1258     log->size += sizeof(uint16_t);
1259
1260     memcpy((log->buffer)+log->size,data,arg_size);
1261     log->size += arg_size;
1262
1263     log->args_num ++;
1264
1265     return 0;
1266 }
1267
1268 int dlt_user_log_write_float32(DltContextData *log, float32_t data)
1269 {
1270     uint32_t type_info;
1271
1272     if (log==0)
1273     {
1274         return -1;
1275     }
1276
1277     if (sizeof(float32_t)!=4)
1278     {
1279         return -1;
1280     }
1281
1282     if ((log->size+sizeof(float32_t))>DLT_USER_BUF_MAX_SIZE)
1283     {
1284         return -1;
1285     }
1286
1287     if (dlt_user.verbose_mode)
1288     {
1289         if ((log->size+sizeof(uint32_t)+sizeof(float32_t))>DLT_USER_BUF_MAX_SIZE)
1290         {
1291             return -1;
1292         }
1293
1294         type_info = DLT_TYPE_INFO_FLOA | DLT_TYLE_32BIT;
1295
1296         memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1297         log->size += sizeof(uint32_t);
1298     }
1299
1300     memcpy((log->buffer)+log->size,&data, sizeof(float32_t));
1301     log->size += sizeof(float32_t);
1302
1303     log->args_num ++;
1304
1305     return 0;
1306 }
1307
1308 int dlt_user_log_write_float64(DltContextData *log, float64_t data)
1309 {
1310     uint32_t type_info;
1311
1312     if (log==0)
1313     {
1314         return -1;
1315     }
1316
1317     if (sizeof(float64_t)!=8)
1318     {
1319         return -1;
1320     }
1321
1322     if ((log->size+sizeof(float64_t))>DLT_USER_BUF_MAX_SIZE)
1323     {
1324         return -1;
1325     }
1326
1327     if (dlt_user.verbose_mode)
1328     {
1329         if ((log->size+sizeof(uint32_t)+sizeof(float64_t))>DLT_USER_BUF_MAX_SIZE)
1330         {
1331             return -1;
1332         }
1333
1334         type_info = DLT_TYPE_INFO_FLOA | DLT_TYLE_64BIT;
1335
1336         memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1337         log->size += sizeof(uint32_t);
1338     }
1339
1340     memcpy((log->buffer)+log->size,&data, sizeof(float64_t));
1341     log->size += sizeof(float64_t);
1342
1343     log->args_num ++;
1344
1345     return 0;
1346 }
1347
1348 int dlt_user_log_write_uint( DltContextData *log, unsigned int data)
1349 {
1350     if (log==0)
1351     {
1352         return -1;
1353     }
1354
1355     switch (sizeof(unsigned int))
1356     {
1357     case 1:
1358     {
1359         return dlt_user_log_write_uint8(log, (uint8_t)data);
1360         break;
1361     }
1362     case 2:
1363     {
1364         return dlt_user_log_write_uint16(log, (uint16_t)data);
1365         break;
1366     }
1367     case 4:
1368     {
1369         return dlt_user_log_write_uint32(log, (uint32_t)data);
1370         break;
1371     }
1372     case 8:
1373     {
1374         return dlt_user_log_write_uint64(log, (uint64_t)data);
1375                 break;
1376     }
1377     default:
1378     {
1379         return -1;
1380         break;
1381     }
1382     }
1383
1384     return 0;
1385 }
1386
1387 int dlt_user_log_write_uint8(DltContextData *log, uint8_t data)
1388 {
1389     uint32_t type_info;
1390
1391     if (log==0)
1392     {
1393         return -1;
1394     }
1395
1396     if ((log->size+sizeof(uint8_t))>DLT_USER_BUF_MAX_SIZE)
1397     {
1398         return -1;
1399     }
1400
1401     if (dlt_user.verbose_mode)
1402     {
1403         if ((log->size+sizeof(uint32_t)+sizeof(uint8_t))>DLT_USER_BUF_MAX_SIZE)
1404         {
1405             return -1;
1406         }
1407
1408         type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_8BIT;
1409
1410         memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1411         log->size += sizeof(uint32_t);
1412     }
1413
1414     memcpy((log->buffer)+log->size,&data,sizeof(uint8_t));
1415     log->size += sizeof(uint8_t);
1416
1417     log->args_num ++;
1418
1419     return 0;
1420 }
1421
1422 int dlt_user_log_write_uint16(DltContextData *log, uint16_t data)
1423 {
1424     uint32_t type_info;
1425
1426     if (log==0)
1427     {
1428         return -1;
1429     }
1430
1431     if ((log->size+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1432     {
1433         return -1;
1434     }
1435
1436     if (dlt_user.verbose_mode)
1437     {
1438         if ((log->size+sizeof(uint32_t)+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1439         {
1440             return -1;
1441         }
1442
1443         type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_16BIT;
1444
1445         memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1446         log->size += sizeof(uint32_t);
1447     }
1448
1449     memcpy((log->buffer)+log->size,&data,sizeof(uint16_t));
1450     log->size += sizeof(uint16_t);
1451
1452     log->args_num ++;
1453
1454     return 0;
1455 }
1456
1457 int dlt_user_log_write_uint32(DltContextData *log, uint32_t data)
1458 {
1459     uint32_t type_info;
1460
1461     if (log==0)
1462     {
1463         return -1;
1464     }
1465
1466     if ((log->size+sizeof(uint32_t))>DLT_USER_BUF_MAX_SIZE)
1467     {
1468         return -1;
1469     }
1470
1471     if (dlt_user.verbose_mode)
1472     {
1473         if ((log->size+sizeof(uint32_t)+sizeof(uint32_t))>DLT_USER_BUF_MAX_SIZE)
1474         {
1475             return -1;
1476         }
1477
1478         type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_32BIT;
1479
1480         memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1481         log->size += sizeof(uint32_t);
1482     }
1483
1484     memcpy((log->buffer)+log->size,&data, sizeof(uint32_t));
1485     log->size += sizeof(uint32_t);
1486
1487     log->args_num ++;
1488
1489     return 0;
1490 }
1491
1492 int dlt_user_log_write_uint64(DltContextData *log, uint64_t data)
1493 {
1494     uint32_t type_info;
1495
1496     if (log==0)
1497     {
1498         return -1;
1499     }
1500
1501     if ((log->size+sizeof(uint64_t))>DLT_USER_BUF_MAX_SIZE)
1502     {
1503         return -1;
1504     }
1505
1506     if (dlt_user.verbose_mode)
1507     {
1508         if ((log->size+sizeof(uint32_t)+sizeof(uint64_t))>DLT_USER_BUF_MAX_SIZE)
1509         {
1510             return -1;
1511         }
1512
1513         type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_64BIT;
1514
1515         memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1516         log->size +=sizeof(uint32_t);
1517     }
1518
1519     memcpy((log->buffer)+log->size,&data,sizeof(uint64_t));
1520     log->size += sizeof(uint64_t);
1521
1522     log->args_num ++;
1523
1524     return 0;
1525 }
1526
1527 int dlt_user_log_write_int(DltContextData *log, int data)
1528 {
1529     if (log==0)
1530     {
1531         return -1;
1532     }
1533
1534     switch (sizeof(int))
1535     {
1536     case 1:
1537     {
1538         return dlt_user_log_write_int8(log, (int8_t)data);
1539         break;
1540     }
1541     case 2:
1542     {
1543         return dlt_user_log_write_int16(log, (int16_t)data);
1544         break;
1545     }
1546     case 4:
1547     {
1548         return dlt_user_log_write_int32(log, (int32_t)data);
1549         break;
1550     }
1551     case 8:
1552     {
1553         return dlt_user_log_write_int64(log, (int64_t)data);
1554                 break;
1555     }
1556     default:
1557     {
1558         return -1;
1559         break;
1560     }
1561     }
1562
1563     return 0;
1564 }
1565
1566 int dlt_user_log_write_int8(DltContextData *log, int8_t data)
1567 {
1568     uint32_t type_info;
1569
1570     if (log==0)
1571     {
1572         return -1;
1573     }
1574
1575     if ((log->size+sizeof(int8_t))>DLT_USER_BUF_MAX_SIZE)
1576     {
1577         return -1;
1578     }
1579
1580     if (dlt_user.verbose_mode)
1581     {
1582         if ((log->size+sizeof(uint32_t)+sizeof(int8_t))>DLT_USER_BUF_MAX_SIZE)
1583         {
1584             return -1;
1585         }
1586
1587         type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_8BIT;
1588
1589         memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1590         log->size += sizeof(uint32_t);
1591     }
1592
1593     memcpy((log->buffer)+log->size,&data,sizeof(int8_t));
1594     log->size += sizeof(int8_t);
1595
1596     log->args_num ++;
1597
1598     return 0;
1599 }
1600
1601 int dlt_user_log_write_int16(DltContextData *log, int16_t data)
1602 {
1603     uint32_t type_info;
1604
1605     if (log==0)
1606     {
1607         return -1;
1608     }
1609
1610     if ((log->size+sizeof(int16_t))>DLT_USER_BUF_MAX_SIZE)
1611     {
1612         return -1;
1613     }
1614
1615     if (dlt_user.verbose_mode)
1616     {
1617         if ((log->size+sizeof(uint32_t)+sizeof(int16_t))>DLT_USER_BUF_MAX_SIZE)
1618                 {
1619             return -1;
1620                 }
1621
1622         type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_16BIT;
1623
1624         memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1625         log->size += sizeof(uint32_t);
1626     }
1627
1628     memcpy((log->buffer)+log->size,&data,sizeof(int16_t));
1629     log->size += sizeof(int16_t);
1630
1631     log->args_num ++;
1632
1633     return 0;
1634 }
1635
1636 int dlt_user_log_write_int32(DltContextData *log, int32_t data)
1637 {
1638     uint32_t type_info;
1639
1640     if (log==0)
1641     {
1642         return -1;
1643     }
1644
1645     if ((log->size+sizeof(int32_t))>DLT_USER_BUF_MAX_SIZE)
1646     {
1647         return -1;
1648     }
1649
1650     if (dlt_user.verbose_mode)
1651     {
1652         if ((log->size+sizeof(uint32_t)+sizeof(int32_t))>DLT_USER_BUF_MAX_SIZE)
1653         {
1654             return -1;
1655         }
1656
1657         type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_32BIT;
1658
1659         memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1660         log->size += sizeof(uint32_t);
1661     }
1662
1663     memcpy((log->buffer)+log->size,&data, sizeof(int32_t));
1664     log->size += sizeof(int32_t);
1665
1666     log->args_num ++;
1667
1668     return 0;
1669 }
1670
1671 int dlt_user_log_write_int64(DltContextData *log, int64_t data)
1672 {
1673     uint32_t type_info;
1674
1675     if (log==0)
1676     {
1677         return -1;
1678     }
1679
1680     if ((log->size+sizeof(int64_t))>DLT_USER_BUF_MAX_SIZE)
1681     {
1682         return -1;
1683     }
1684
1685     if (dlt_user.verbose_mode)
1686     {
1687         if ((log->size+sizeof(uint32_t)+sizeof(int64_t))>DLT_USER_BUF_MAX_SIZE)
1688         {
1689             return -1;
1690         }
1691
1692         type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_64BIT;
1693
1694         memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1695         log->size += sizeof(uint32_t);
1696     }
1697
1698     memcpy((log->buffer)+log->size,&data,sizeof(int64_t));
1699     log->size += sizeof(int64_t);
1700
1701     log->args_num ++;
1702
1703     return 0;
1704 }
1705
1706 int dlt_user_log_write_bool(DltContextData *log, uint8_t data)
1707 {
1708     uint32_t type_info;
1709
1710     if (log==0)
1711     {
1712         return -1;
1713     }
1714
1715     if ((log->size+sizeof(uint8_t))>DLT_USER_BUF_MAX_SIZE)
1716     {
1717         return -1;
1718     }
1719
1720     if (dlt_user.verbose_mode)
1721     {
1722         if ((log->size+sizeof(uint32_t)+sizeof(uint8_t))>DLT_USER_BUF_MAX_SIZE)
1723         {
1724             return -1;
1725         }
1726
1727         type_info = DLT_TYPE_INFO_BOOL;
1728
1729         memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1730         log->size += sizeof(uint32_t);
1731     }
1732
1733     memcpy((log->buffer)+log->size,&data,sizeof(uint8_t));
1734     log->size += sizeof(uint8_t);
1735
1736     log->args_num ++;
1737
1738     return 0;
1739 }
1740
1741 int dlt_user_log_write_string(DltContextData *log, const char *text)
1742 {
1743     uint16_t arg_size;
1744     uint32_t type_info;
1745
1746     if ((log==0) || (text==0))
1747     {
1748         return -1;
1749     }
1750
1751     if ((log->size+(strlen(text)+1)+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1752     {
1753         return -1;
1754     }
1755
1756     if (dlt_user.verbose_mode)
1757     {
1758         if ((log->size+(strlen(text)+1)+sizeof(uint32_t)+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1759         {
1760             return -1;
1761         }
1762
1763         type_info = DLT_TYPE_INFO_STRG;
1764
1765         memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1766         log->size += sizeof(uint32_t);
1767     }
1768
1769     arg_size = strlen(text) + 1;
1770
1771     memcpy((log->buffer)+log->size,&(arg_size),sizeof(uint16_t));
1772     log->size += sizeof(uint16_t);
1773
1774     memcpy((log->buffer)+log->size,text,arg_size);
1775     log->size += arg_size;
1776
1777     log->args_num ++;
1778
1779     return 0;
1780 }
1781
1782 int dlt_register_injection_callback(DltContext *handle, uint32_t service_id,
1783                                     int (*dlt_injection_callback)(uint32_t service_id, void *data, uint32_t length))
1784 {
1785     DltContextData log;
1786     uint32_t i,j,k;
1787     int found = 0;
1788
1789         DltUserInjectionCallback *old;
1790
1791     if (handle==0)
1792     {
1793         return -1;
1794     }
1795
1796     if (dlt_user_log_init(handle, &log)==-1)
1797     {
1798                 return -1;
1799     }
1800
1801     if (service_id<DLT_USER_INJECTION_MIN)
1802     {
1803         return -1;
1804     }
1805     /* This function doesn't make sense storing to local file is choosen;
1806        so terminate this function */
1807     if (dlt_user.dlt_is_file)
1808     {
1809         return 0;
1810     }
1811
1812     DLT_SEM_LOCK();
1813
1814     if (dlt_user.dlt_ll_ts==0)
1815     {
1816         DLT_SEM_FREE();
1817         return 0;
1818     }
1819
1820     /* Insert callback in corresponding table */
1821     i=handle->log_level_pos;
1822
1823     /* Insert each service_id only once */
1824     for (k=0;k<dlt_user.dlt_ll_ts[i].nrcallbacks;k++)
1825     {
1826         if ((dlt_user.dlt_ll_ts[i].injection_table) &&
1827                 (dlt_user.dlt_ll_ts[i].injection_table[k].service_id == service_id))
1828         {
1829             found = 1;
1830             break;
1831         }
1832     }
1833
1834     if (found)
1835     {
1836         j = k;
1837     }
1838     else
1839     {
1840         j=dlt_user.dlt_ll_ts[i].nrcallbacks;
1841
1842         /* Allocate or expand injection table */
1843         if (dlt_user.dlt_ll_ts[i].injection_table == 0)
1844         {
1845             dlt_user.dlt_ll_ts[i].injection_table = (DltUserInjectionCallback*) malloc(sizeof(DltUserInjectionCallback));
1846             if(dlt_user.dlt_ll_ts[i].injection_table == 0)
1847             {
1848                 DLT_SEM_FREE();
1849                 return -1;
1850             }
1851         }
1852         else
1853         {
1854             old = dlt_user.dlt_ll_ts[i].injection_table;
1855             dlt_user.dlt_ll_ts[i].injection_table = (DltUserInjectionCallback*) malloc(sizeof(DltUserInjectionCallback)*(j+1));
1856             if(dlt_user.dlt_ll_ts[i].injection_table == 0)
1857             {
1858                 dlt_user.dlt_ll_ts[i].injection_table = old;
1859                 DLT_SEM_FREE();
1860                 return -1;
1861             }
1862             memcpy(dlt_user.dlt_ll_ts[i].injection_table,old,sizeof(DltUserInjectionCallback)*j);
1863             free(old);
1864         }
1865
1866         dlt_user.dlt_ll_ts[i].nrcallbacks++;
1867     }
1868
1869     /* Store service_id and corresponding function pointer for callback function */
1870     dlt_user.dlt_ll_ts[i].injection_table[j].service_id = service_id;
1871     dlt_user.dlt_ll_ts[i].injection_table[j].injection_callback = dlt_injection_callback;
1872
1873     DLT_SEM_FREE();
1874     return 0;
1875 }
1876
1877 /**
1878  * NW Trace related
1879  */
1880
1881
1882 int check_buffer()
1883 {
1884         int total_size, used_size;
1885         dlt_user_check_buffer(&total_size, &used_size);
1886
1887         if((total_size - used_size) < (total_size/2))
1888         {
1889                 return -1;
1890         }
1891         return 1;
1892 }
1893
1894 /**
1895  * Send the start of a segment chain.
1896  * Returns -1 on failure
1897  */
1898 int dlt_user_trace_network_segmented_start(uint16_t *id, DltContext *handle, DltNetworkTraceType nw_trace_type, uint16_t header_len, void *header, uint16_t payload_len)
1899 {
1900
1901     DltContextData log;
1902         struct timeval tv;
1903
1904     if (handle==NULL)
1905     {
1906         return -1;
1907     }
1908
1909     if (dlt_user_log_init(handle, &log)==-1)
1910     {
1911                 return -1;
1912     }
1913
1914     DLT_SEM_LOCK();
1915
1916     if (dlt_user.dlt_ll_ts==0)
1917     {
1918         DLT_SEM_FREE();
1919         return -1;
1920     }
1921
1922     if (dlt_user.dlt_ll_ts[handle->log_level_pos].trace_status==DLT_TRACE_STATUS_ON)
1923     {
1924         DLT_SEM_FREE();
1925
1926         log.args_num = 0;
1927         log.trace_status = nw_trace_type;
1928         log.size = 0;
1929
1930         gettimeofday(&tv, NULL);
1931         *id = tv.tv_usec;
1932
1933         /* Write identifier */
1934         if(dlt_user_log_write_string(&log, "NWST") < 0)
1935         {
1936                 return -1;
1937         }
1938
1939         /* Write stream handle */
1940         if(dlt_user_log_write_uint16(&log, *id) < 0)
1941         {
1942                 return -1;
1943         }
1944
1945         /* Write header */
1946         if(dlt_user_log_write_raw(&log, header, header_len) < 0)
1947         {
1948                 return -1;
1949         }
1950
1951         /* Write size of payload */
1952         if(dlt_user_log_write_uint16(&log, payload_len) < 0)
1953         {
1954                 return -1;
1955         }
1956
1957         /* Write expected segment count */
1958         uint16_t segment_count = payload_len/DLT_MAX_TRACE_SEGMENT_SIZE+1;
1959
1960         /* If segments align perfectly with segment size, avoid sending empty segment */
1961         if((payload_len % DLT_MAX_TRACE_SEGMENT_SIZE) == 0)
1962         {
1963                 segment_count--;
1964         }
1965
1966         if(dlt_user_log_write_uint16(&log, segment_count) < 0)
1967         {
1968                 return -1;
1969         }
1970
1971         /* Write length of one segment */
1972         if(dlt_user_log_write_uint16(&log, DLT_MAX_TRACE_SEGMENT_SIZE) < 0)
1973         {
1974                 return -1;
1975         }
1976
1977         /* Send log */
1978         return dlt_user_log_send_log(&log, DLT_TYPE_NW_TRACE);
1979     }
1980     else
1981     {
1982         DLT_SEM_FREE();
1983     }
1984     return 0;
1985 }
1986
1987 int dlt_user_trace_network_segmented_segment(uint16_t id, DltContext *handle, DltNetworkTraceType nw_trace_type, int sequence, uint16_t payload_len, void *payload)
1988 {
1989         while(check_buffer() < 0)
1990         {
1991                 usleep(1000*50); // Wait 50ms
1992                 dlt_user_log_resend_buffer();
1993         }
1994
1995     if (handle==NULL)
1996     {
1997         return -1;
1998     }
1999
2000     DltContextData log;
2001
2002     if (dlt_user_log_init(handle, &log)==-1)
2003     {
2004                 return -1;
2005     }
2006
2007     DLT_SEM_LOCK();
2008
2009     if (dlt_user.dlt_ll_ts==0)
2010     {
2011         DLT_SEM_FREE();
2012         return -1;
2013     }
2014
2015     if (dlt_user.dlt_ll_ts[handle->log_level_pos].trace_status==DLT_TRACE_STATUS_ON)
2016     {
2017         DLT_SEM_FREE();
2018
2019         log.args_num = 0;
2020         log.trace_status = nw_trace_type;
2021         log.size = 0;
2022
2023         /* Write identifier */
2024         if(dlt_user_log_write_string(&log, "NWCH") < 0)
2025         {
2026                 return -1;
2027         }
2028
2029         /* Write stream handle */
2030         if(dlt_user_log_write_uint16(&log, id) < 0)
2031         {
2032                 return -1;
2033         }
2034
2035         /* Write segment sequence number */
2036         if(dlt_user_log_write_uint16(&log, sequence) < 0)
2037         {
2038                 return -1;
2039         }
2040
2041         /* Write data */
2042         if(dlt_user_log_write_raw(&log, payload, payload_len) < 0)
2043         {
2044                 return -1;
2045         }
2046
2047         /* Send log */
2048         return dlt_user_log_send_log(&log, DLT_TYPE_NW_TRACE);
2049     }
2050     else
2051     {
2052         DLT_SEM_FREE();
2053     }
2054
2055     /* Allow other threads to log between chunks */
2056         pthread_yield();
2057     return 0;
2058 }
2059
2060 int dlt_user_trace_network_segmented_end(uint16_t id, DltContext *handle, DltNetworkTraceType nw_trace_type)
2061 {
2062     DltContextData log;
2063
2064     if (handle==0)
2065     {
2066         return -1;
2067     }
2068
2069     if (dlt_user_log_init(handle, &log)==-1)
2070     {
2071                 return -1;
2072     }
2073
2074
2075
2076     DLT_SEM_LOCK();
2077
2078     if (dlt_user.dlt_ll_ts==0)
2079     {
2080         DLT_SEM_FREE();
2081         return -1;
2082     }
2083
2084     if (dlt_user.dlt_ll_ts[handle->log_level_pos].trace_status==DLT_TRACE_STATUS_ON)
2085     {
2086         DLT_SEM_FREE();
2087
2088         log.args_num = 0;
2089         log.trace_status = nw_trace_type;
2090         log.size = 0;
2091
2092         /* Write identifier */
2093         if(dlt_user_log_write_string(&log, "NWEN") < 0)
2094         {
2095                 return -1;
2096         }
2097
2098         /* Write stream handle */
2099         if(dlt_user_log_write_uint(&log, id) < 0)
2100         {
2101                 return -1;
2102         }
2103
2104         /* Send log */
2105         return dlt_user_log_send_log(&log, DLT_TYPE_NW_TRACE);
2106     }
2107     else
2108     {
2109         DLT_SEM_FREE();
2110     }
2111     return 0;
2112 }
2113
2114
2115 void dlt_user_trace_network_segmented_thread(void *unused)
2116 {
2117         /* Unused on purpose. */
2118         (void) unused;
2119
2120         s_segmented_data *data;
2121
2122         while(1)
2123         {
2124                 // Wait until message queue is initialized
2125                 pthread_mutex_lock(&mq_mutex);
2126                 if(dlt_user.dlt_segmented_queue_read_handle < 0)
2127                 {
2128                         pthread_cond_wait(&mq_init_condition, &mq_mutex);
2129                 }
2130                 pthread_mutex_unlock(&mq_mutex);
2131
2132                 ssize_t read = mq_receive(dlt_user.dlt_segmented_queue_read_handle, (char *)&data,
2133                                         sizeof(s_segmented_data * ), NULL);
2134
2135                 if(read != sizeof(s_segmented_data *))
2136                 {
2137                         dlt_log(LOG_ERR, "NWTSegmented: Error while reading queue.\n");
2138                         dlt_log(LOG_ERR, strerror(errno));
2139                         continue;
2140                 }
2141
2142                 /* Indicator just to try to flush the buffer */
2143                 if(data->payload_len == DLT_DELAYED_RESEND_INDICATOR_PATTERN)
2144                 {
2145                         // Sleep 100ms, to allow other process to read FIFO
2146                         usleep(100*1000);
2147                         if(dlt_user_log_resend_buffer() < 0)
2148                         {
2149                                 // Requeue if still not empty
2150                                 if ( dlt_user_queue_resend() < 0 )
2151                                     dlt_log(LOG_WARNING, "Failed to queue resending in dlt_user_trace_network_segmented_thread.\n");
2152                         }
2153                         free(data);
2154                         continue;
2155                 }
2156
2157                 dlt_user_trace_network_segmented_thread_segmenter(data);
2158
2159                 /* Send the end message */
2160                 DltReturnValue err = dlt_user_trace_network_segmented_end(data->id, data->handle, data->nw_trace_type);
2161                 if(err == DLT_RETURN_BUFFER_FULL || err == DLT_RETURN_ERROR)
2162                 {
2163                         dlt_log(LOG_ERR,"NWTSegmented: Could not send end segment.\n");
2164                 }
2165
2166                 /* Free resources */
2167                 free(data->header);
2168                 free(data->payload);
2169                 free(data);
2170         }
2171 }
2172
2173 void dlt_user_trace_network_segmented_thread_segmenter(s_segmented_data *data)
2174 {
2175         /* Segment the data and send the chunks */
2176         void *ptr                       = NULL;
2177         uint16_t offset         = 0;
2178         uint16_t sequence       = 0;
2179         do
2180         {
2181                 uint16_t len = 0;
2182                 if(offset + DLT_MAX_TRACE_SEGMENT_SIZE > data->payload_len)
2183                 {
2184                         len = data->payload_len - offset;
2185                 }
2186                 else
2187                 {
2188                         len = DLT_MAX_TRACE_SEGMENT_SIZE;
2189                 }
2190                 /* If payload size aligns perfectly with segment size, avoid sending empty segment */
2191                 if(len == 0)
2192                 {
2193                         break;
2194                 }
2195
2196                 ptr = data->payload + offset;
2197                 DltReturnValue err = dlt_user_trace_network_segmented_segment(data->id, data->handle, data->nw_trace_type, sequence++, len, ptr);
2198                 if(err == DLT_RETURN_BUFFER_FULL || err == DLT_RETURN_ERROR)
2199                 {
2200                         dlt_log(LOG_ERR,"NWTSegmented: Could not send segment. Aborting.\n");
2201                         break; // loop
2202                 }
2203                 offset += len;
2204         }while(ptr < data->payload + data->payload_len);
2205 }
2206
2207
2208 int dlt_user_trace_network_segmented(DltContext *handle, DltNetworkTraceType nw_trace_type, uint16_t header_len, void *header, uint16_t payload_len, void *payload)
2209 {
2210         /* Send as normal trace if possible */
2211         if(header_len+payload_len+sizeof(uint16_t) < DLT_USER_BUF_MAX_SIZE) {
2212                 return dlt_user_trace_network(handle, nw_trace_type, header_len, header, payload_len, payload);
2213         }
2214
2215         /* Allocate Memory */
2216         s_segmented_data *thread_data = malloc(sizeof(s_segmented_data));
2217         if(thread_data == NULL)
2218         {
2219                 return -1;
2220         }
2221         thread_data->header = malloc(header_len);
2222         if(thread_data->header == NULL)
2223         {
2224                 free(thread_data);
2225                 return -1;
2226         }
2227         thread_data->payload = malloc(payload_len);
2228         if(thread_data->payload == NULL)
2229         {
2230                 free(thread_data->header);
2231                 free(thread_data);
2232                 return -1;
2233         }
2234
2235         /* Copy data */
2236         thread_data->handle = handle;
2237         thread_data->nw_trace_type = nw_trace_type;
2238         thread_data->header_len = header_len;
2239         memcpy(thread_data->header, header, header_len);
2240         thread_data->payload_len = payload_len;
2241         memcpy(thread_data->payload, payload, payload_len);
2242
2243         /* Send start message */
2244         DltReturnValue err =    dlt_user_trace_network_segmented_start(&(thread_data->id),
2245                                                         thread_data->handle, thread_data->nw_trace_type,
2246                                                         thread_data->header_len, thread_data->header,
2247                                                         thread_data->payload_len);
2248         if(err == DLT_RETURN_BUFFER_FULL || err == DLT_RETURN_ERROR)
2249         {
2250                 dlt_log(LOG_ERR,"NWTSegmented: Could not send start segment. Aborting.\n");
2251                 free(thread_data->header);
2252                 free(thread_data->payload);
2253                 free(thread_data);
2254                 return -1;
2255         }
2256
2257         /* Open queue if it is not open */
2258         if(dlt_init_message_queue() < 0)
2259         {
2260                 dlt_log(LOG_ERR, "NWTSegmented: Could not open queue.\n");
2261                 free(thread_data->header);
2262                 free(thread_data->payload);
2263                 free(thread_data);
2264
2265                 return -1;
2266         }
2267
2268         /* Add to queue */
2269         if(mq_send(dlt_user.dlt_segmented_queue_write_handle,
2270                         (char *)&thread_data, sizeof(s_segmented_data *), 1) < 0)
2271         {
2272                 if(errno == EAGAIN)
2273                 {
2274                         dlt_log(LOG_ERR, "NWTSegmented: Queue full. Message discarded.\n");
2275                 }
2276                 free(thread_data->header);
2277                 free(thread_data->payload);
2278                 free(thread_data);
2279                 dlt_log(LOG_ERR, "NWTSegmented: Could not write into queue.\n");
2280                 dlt_log(LOG_ERR, strerror(errno));
2281                 return -1;
2282         }
2283
2284         //thread_data will be freed by the receiver function
2285         //coverity[leaked_storage]
2286         return 0;
2287 }
2288
2289 int dlt_user_trace_network(DltContext *handle, DltNetworkTraceType nw_trace_type, uint16_t header_len, void *header, uint16_t payload_len, void *payload)
2290 {
2291         return dlt_user_trace_network_truncated(handle, nw_trace_type, header_len, header, payload_len, payload, 1);
2292 }
2293
2294 int dlt_user_trace_network_truncated(DltContext *handle, DltNetworkTraceType nw_trace_type, uint16_t header_len, void *header, uint16_t payload_len, void *payload, int allow_truncate)
2295 {
2296     DltContextData log;
2297
2298     if (dlt_user_initialised==0)
2299     {
2300         if (dlt_init()<0)
2301         {
2302             return -1;
2303         }
2304     }
2305
2306     if (dlt_user_log_init(handle, &log)==-1)
2307     {
2308                 return -1;
2309     }
2310
2311     if (handle==0)
2312     {
2313         return -1;
2314     }
2315
2316     /* Commented out because of DltNetworkTraceType:
2317
2318     if ((nw_trace_type<=0) || (nw_trace_type>0x15))
2319     {
2320         return -1;
2321     }
2322
2323     */
2324
2325     DLT_SEM_LOCK();
2326
2327     if (dlt_user.dlt_ll_ts==0)
2328     {
2329         DLT_SEM_FREE();
2330         return -1;
2331     }
2332
2333     if (dlt_user.dlt_ll_ts[handle->log_level_pos].trace_status==DLT_TRACE_STATUS_ON)
2334     {
2335         DLT_SEM_FREE();
2336
2337         log.args_num = 0;
2338         log.trace_status = nw_trace_type;
2339         log.size = 0;
2340
2341         if (header==0)
2342         {
2343             header_len=0;
2344         }
2345
2346         /* If truncation is allowed, check if we must do it */
2347         if(allow_truncate > 0 && (header_len+payload_len+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
2348         {
2349                 /* Identify as truncated */
2350                 if(dlt_user_log_write_string(&log, "NWTR") < 0)
2351                 {
2352                         return -1;
2353                 }
2354
2355             /* Write header and its length */
2356             if (dlt_user_log_write_raw(&log, header, header_len) < 0)
2357             {
2358                 return -1;
2359             }
2360
2361                 /* Write original size of payload */
2362             if(dlt_user_log_write_uint16(&log, payload_len) < 0)
2363             {
2364                 return -1;
2365             }
2366
2367                 /**
2368                  *  Calculate maximum avaialble space in sending buffer after headers.
2369                  */
2370
2371                 int truncated_payload_len = DLT_USER_BUF_MAX_SIZE -
2372                                 log.size - sizeof(uint16_t) - sizeof(uint32_t);
2373
2374             /* Write truncated payload */
2375             if (dlt_user_log_write_raw(&log, payload, truncated_payload_len) < 0)
2376             {
2377                         return -1;
2378             }
2379         }
2380         else /* Truncation not allowed or data short enough */
2381         {
2382             /* Write header and its length */
2383             if (dlt_user_log_write_raw(&log, header, header_len)==-1)
2384             {
2385                 return -1;
2386             }
2387
2388             if (payload==0)
2389             {
2390                 payload_len=0;
2391             }
2392
2393             /* Write payload and its length */
2394             if (dlt_user_log_write_raw(&log, payload, payload_len)==-1)
2395             {
2396                         return -1;
2397             }
2398         }
2399
2400         /* Send log */
2401         return dlt_user_log_send_log(&log, DLT_TYPE_NW_TRACE);
2402     }
2403     else
2404     {
2405         DLT_SEM_FREE();
2406     }
2407
2408     return 0;
2409 }
2410
2411 int dlt_log_string(DltContext *handle,DltLogLevelType loglevel, const char *text)
2412 {
2413     DltContextData log;
2414
2415     if (dlt_user.verbose_mode==0)
2416     {
2417         return -1;
2418     }
2419
2420     if ((handle==0) || (text==0))
2421     {
2422         return -1;
2423     }
2424
2425     if (dlt_user_log_write_start(handle,&log,loglevel)>0)
2426     {
2427         if (dlt_user_log_write_string(&log,text)==-1)
2428         {
2429                         return -1;
2430         }
2431         if (dlt_user_log_write_finish(&log)==-1)
2432         {
2433                 return -1;
2434         }
2435     }
2436
2437     return 0;
2438 }
2439
2440 int dlt_log_string_int(DltContext *handle,DltLogLevelType loglevel, const char *text, int data)
2441 {
2442     DltContextData log;
2443
2444     if (dlt_user.verbose_mode==0)
2445     {
2446         return -1;
2447     }
2448
2449     if ((handle==0) || (text==0))
2450     {
2451         return -1;
2452     }
2453
2454     if (dlt_user_log_write_start(handle,&log,loglevel)>0)
2455     {
2456         if (dlt_user_log_write_string(&log,text)==-1)
2457         {
2458                         return -1;
2459         }
2460         if (dlt_user_log_write_int(&log,data)==-1)
2461         {
2462                         return -1;
2463         }
2464         if (dlt_user_log_write_finish(&log)==-1)
2465         {
2466                         return -1;
2467         }
2468     }
2469
2470     return 0;
2471 }
2472
2473 int dlt_log_string_uint(DltContext *handle,DltLogLevelType loglevel, const char *text, unsigned int data)
2474 {
2475     DltContextData log;
2476
2477     if (dlt_user.verbose_mode==0)
2478     {
2479         return -1;
2480     }
2481
2482     if ((handle==0) || (text==0))
2483     {
2484         return -1;
2485     }
2486
2487     if (dlt_user_log_write_start(handle,&log,loglevel)>0)
2488     {
2489         if (dlt_user_log_write_string(&log,text)==-1)
2490         {
2491                         return -1;
2492         }
2493         if (dlt_user_log_write_uint(&log,data)==-1)
2494         {
2495                         return -1;
2496         }
2497         if (dlt_user_log_write_finish(&log)==-1)
2498         {
2499                         return -1;
2500         }
2501     }
2502
2503     return 0;
2504 }
2505
2506 int dlt_log_int(DltContext *handle,DltLogLevelType loglevel, int data)
2507 {
2508     DltContextData log;
2509
2510     if (dlt_user.verbose_mode==0)
2511     {
2512         return -1;
2513     }
2514
2515     if (handle==0)
2516     {
2517         return -1;
2518     }
2519
2520     if (dlt_user_log_write_start(handle,&log,loglevel)>0)
2521     {
2522         if (dlt_user_log_write_int(&log,data)==-1)
2523         {
2524                         return -1;
2525         }
2526         if (dlt_user_log_write_finish(&log)==-1)
2527         {
2528                         return -1;
2529         }
2530     }
2531
2532     return 0;
2533 }
2534
2535 int dlt_log_uint(DltContext *handle,DltLogLevelType loglevel, unsigned int data)
2536 {
2537     DltContextData log;
2538
2539     if (dlt_user.verbose_mode==0)
2540     {
2541         return -1;
2542     }
2543
2544     if (handle==0)
2545     {
2546         return -1;
2547     }
2548
2549     if (dlt_user_log_write_start(handle,&log,loglevel)>0)
2550     {
2551         if (dlt_user_log_write_uint(&log,data)==-1)
2552         {
2553                         return -1;
2554         }
2555         if (dlt_user_log_write_finish(&log)==-1)
2556         {
2557                         return -1;
2558         }
2559     }
2560
2561     return 0;
2562 }
2563
2564 int dlt_log_raw(DltContext *handle,DltLogLevelType loglevel, void *data,uint16_t length)
2565 {
2566     DltContextData log;
2567
2568     if (dlt_user.verbose_mode==0)
2569     {
2570         return -1;
2571     }
2572
2573     if (handle==0)
2574     {
2575         return -1;
2576     }
2577
2578     if (dlt_user_log_write_start(handle,&log,loglevel)>0)
2579     {
2580         if (dlt_user_log_write_raw(&log,data,length)==-1)
2581         {
2582                         return -1;
2583         }
2584         if (dlt_user_log_write_finish(&log)==-1)
2585         {
2586                         return -1;
2587         }
2588     }
2589
2590     return 0;
2591 }
2592
2593 int dlt_verbose_mode(void)
2594 {
2595     if (dlt_user_initialised==0)
2596     {
2597         if (dlt_init()<0)
2598         {
2599             return -1;
2600         }
2601     }
2602
2603     /* Switch to verbose mode */
2604     dlt_user.verbose_mode = 1;
2605
2606     return 0;
2607 }
2608
2609 int dlt_nonverbose_mode(void)
2610 {
2611     if (dlt_user_initialised==0)
2612     {
2613         if (dlt_init()<0)
2614         {
2615             return -1;
2616         }
2617     }
2618
2619     /* Switch to non-verbose mode */
2620     dlt_user.verbose_mode = 0;
2621
2622     return 0;
2623 }
2624
2625 int dlt_enable_local_print(void)
2626 {
2627     if (dlt_user_initialised==0)
2628     {
2629         if (dlt_init()<0)
2630         {
2631             return -1;
2632         }
2633     }
2634
2635     dlt_user.enable_local_print = 1;
2636
2637     return 0;
2638 }
2639
2640 int dlt_disable_local_print(void)
2641 {
2642     if (dlt_user_initialised==0)
2643     {
2644         if (dlt_init()<0)
2645         {
2646             return -1;
2647         }
2648     }
2649
2650     dlt_user.enable_local_print = 0;
2651
2652     return 0;
2653 }
2654
2655 void dlt_user_receiverthread_function(__attribute__((unused)) void *ptr)
2656 {
2657     while (1)
2658     {
2659         /* Check for new messages from DLT daemon */
2660         if (dlt_user_log_check_user_message()==-1)
2661         {
2662                         /* Critical error */
2663                         dlt_log(LOG_CRIT,"Receiver thread encountered error condition\n");
2664         }
2665
2666         usleep(DLT_USER_RECEIVE_DELAY); /* delay */
2667     }
2668 }
2669
2670 /* Private functions of user library */
2671
2672 int dlt_user_log_init(DltContext *handle, DltContextData *log)
2673 {
2674     if (dlt_user_initialised==0)
2675     {
2676         if (dlt_init()<0)
2677         {
2678             return -1;
2679         }
2680     }
2681
2682     log->handle = handle;
2683
2684     return 0;
2685 }
2686
2687 int dlt_user_queue_resend(void)
2688 {
2689         if(dlt_user.dlt_log_handle < 0)
2690         {
2691                 // Fail silenty. FIFO is not open yet
2692                 return -1;
2693         }
2694     /**
2695      * Ask segmented thread to try emptying the buffer soon.
2696      * This will be freed in dlt_user_trace_network_segmented_thread
2697      * */
2698     s_segmented_data *resend_data = malloc(sizeof(s_segmented_data));
2699
2700     if (NULL == resend_data)
2701     {
2702         return -1;
2703     }
2704
2705     resend_data->payload_len = DLT_DELAYED_RESEND_INDICATOR_PATTERN;
2706
2707
2708
2709     /* Open queue if it is not open */
2710         if(dlt_init_message_queue() < 0)
2711         {
2712                 dlt_log(LOG_ERR, "NWTSegmented: Could not open queue.\n");
2713                 free(resend_data);
2714                 return -1;
2715         }
2716
2717     if(mq_send(dlt_user.dlt_segmented_queue_write_handle, (char *)&resend_data, sizeof(s_segmented_data *), 1) < 0)
2718     {
2719         dlt_log(LOG_ERR,"Could not request resending.\n");
2720         dlt_log(LOG_ERR, strerror(errno));
2721         free(resend_data);
2722         return -1;
2723     }
2724     //thread_data will be freed by the receiver function
2725     //coverity[leaked_storage]
2726     return 0;
2727 }
2728
2729 DltReturnValue dlt_user_log_send_log(DltContextData *log, int mtype)
2730 {
2731     DltMessage msg;
2732     DltUserHeader userheader;
2733     int32_t len;
2734
2735     DltReturnValue ret = DLT_RETURN_OK;
2736
2737     if (log==0)
2738     {
2739         return DLT_RETURN_ERROR;
2740     }
2741
2742     if (log->handle==0)
2743     {
2744         return DLT_RETURN_ERROR;
2745     }
2746
2747     if (dlt_user.appID[0]=='\0')
2748     {
2749         return DLT_RETURN_ERROR;
2750     }
2751
2752     if (log->handle->contextID[0]=='\0')
2753     {
2754         return DLT_RETURN_ERROR;
2755     }
2756
2757     if ((mtype<DLT_TYPE_LOG) || (mtype>DLT_TYPE_CONTROL))
2758     {
2759         return DLT_RETURN_ERROR;
2760     }
2761
2762     /* also for Trace messages */
2763 #ifdef DLT_SHM_ENABLE
2764     if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG_SHM)==-1)
2765 #else
2766     if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG)==-1)
2767 #endif
2768     {
2769                 return DLT_RETURN_ERROR;
2770     }
2771
2772     if (dlt_message_init(&msg,0)==-1)
2773     {
2774         return DLT_RETURN_ERROR;
2775     }
2776
2777     msg.storageheader = (DltStorageHeader*)msg.headerbuffer;
2778
2779     if (dlt_set_storageheader(msg.storageheader,dlt_user.ecuID)==-1)
2780     {
2781                 return DLT_RETURN_ERROR;
2782     }
2783
2784     msg.standardheader = (DltStandardHeader*)(msg.headerbuffer + sizeof(DltStorageHeader));
2785     msg.standardheader->htyp = DLT_HTYP_WEID | DLT_HTYP_WTMS | DLT_HTYP_PROTOCOL_VERSION1 ;
2786
2787     if (dlt_user.verbose_mode)
2788     {
2789         /* In verbose mode, send extended header */
2790         msg.standardheader->htyp = (msg.standardheader->htyp | DLT_HTYP_UEH );
2791     }
2792     else
2793     {
2794         /* In non-verbose, send extended header if desired */
2795 #if (DLT_USER_USE_EXTENDED_HEADER_FOR_NONVERBOSE==1)
2796         msg.standardheader->htyp = (msg.standardheader->htyp | DLT_HTYP_UEH );
2797 #endif
2798     }
2799
2800 #if (BYTE_ORDER==BIG_ENDIAN)
2801     msg.standardheader->htyp = (msg.standardheader->htyp | DLT_HTYP_MSBF);
2802 #endif
2803
2804     msg.standardheader->mcnt = log->handle->mcnt++;
2805
2806     /* Set header extra parameters */
2807     dlt_set_id(msg.headerextra.ecu,dlt_user.ecuID);
2808     //msg.headerextra.seid = 0;
2809     msg.headerextra.tmsp = dlt_uptime();
2810
2811     if (dlt_message_set_extraparameters(&msg,0)==-1)
2812     {
2813         return DLT_RETURN_ERROR;
2814     }
2815
2816     /* Fill out extended header, if extended header should be provided */
2817     if (DLT_IS_HTYP_UEH(msg.standardheader->htyp))
2818     {
2819         /* with extended header */
2820         msg.extendedheader = (DltExtendedHeader*)(msg.headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp)  );
2821
2822         switch (mtype)
2823         {
2824         case DLT_TYPE_LOG:
2825         {
2826             msg.extendedheader->msin = (DLT_TYPE_LOG << DLT_MSIN_MSTP_SHIFT) | ((log->log_level << DLT_MSIN_MTIN_SHIFT) & DLT_MSIN_MTIN) ; /* messsage info */
2827             break;
2828         }
2829         case DLT_TYPE_NW_TRACE:
2830         {
2831             msg.extendedheader->msin = (DLT_TYPE_NW_TRACE << DLT_MSIN_MSTP_SHIFT) | ((log->trace_status << DLT_MSIN_MTIN_SHIFT) & DLT_MSIN_MTIN) ; /* messsage info */
2832             break;
2833         }
2834         default:
2835         {
2836                     /* This case should not occur */
2837             return DLT_RETURN_ERROR;
2838             break;
2839         }
2840         }
2841
2842         /* If in verbose mode, set flag in header for verbose mode */
2843         if (dlt_user.verbose_mode)
2844         {
2845             msg.extendedheader->msin |= DLT_MSIN_VERB;
2846         }
2847
2848         msg.extendedheader->noar = log->args_num;              /* number of arguments */
2849         dlt_set_id(msg.extendedheader->apid,dlt_user.appID);       /* application id */
2850         dlt_set_id(msg.extendedheader->ctid,log->handle->contextID);   /* context id */
2851
2852         msg.headersize = sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + sizeof(DltExtendedHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp);
2853     }
2854     else
2855     {
2856         /* without extended header */
2857         msg.headersize = sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp);
2858     }
2859
2860     len=msg.headersize - sizeof(DltStorageHeader) +log->size;
2861     if (len>UINT16_MAX)
2862     {
2863         dlt_log(LOG_CRIT,"Huge message discarded!\n");
2864         return DLT_RETURN_ERROR;
2865     }
2866
2867     msg.standardheader->len = DLT_HTOBE_16(len);
2868
2869     /* print to std out, if enabled */
2870     if ((dlt_user.local_print_mode != DLT_PM_FORCE_OFF) &&
2871             (dlt_user.local_print_mode != DLT_PM_AUTOMATIC))
2872     {
2873         if ((dlt_user.enable_local_print) || (dlt_user.local_print_mode == DLT_PM_FORCE_ON))
2874         {
2875             if (dlt_user_print_msg(&msg, log)==-1)
2876             {
2877                                 return DLT_RETURN_ERROR;
2878             }
2879         }
2880     }
2881
2882     if (dlt_user.dlt_is_file)
2883     {
2884         /* log to file */
2885         ret=dlt_user_log_out2(dlt_user.dlt_log_handle, msg.headerbuffer, msg.headersize, log->buffer, log->size);
2886         return ret;
2887     }
2888     else
2889     {
2890         /* Reattach to daemon if neccesary */
2891         dlt_user_log_reattach_to_daemon();
2892
2893         if (dlt_user.overflow)
2894         {
2895             if (dlt_user_log_send_overflow()==0)
2896             {
2897                 dlt_user.overflow=0;
2898             }
2899         }
2900
2901                 /* try to resent old data first */
2902                 ret = DLT_RETURN_OK;
2903                 if(dlt_user.dlt_log_handle!=-1)
2904                         ret = dlt_user_log_resend_buffer();
2905                 if(ret==DLT_RETURN_OK)
2906                 {
2907                         /* resend ok or nothing to resent */
2908 #ifdef DLT_SHM_ENABLE
2909                         if(dlt_user.dlt_log_handle!=-1)
2910                                 dlt_shm_push(&dlt_user.dlt_shm,msg.headerbuffer+sizeof(DltStorageHeader), msg.headersize-sizeof(DltStorageHeader),
2911                                                                                         log->buffer, log->size,0,0);                   
2912
2913                         /* log to FIFO */
2914                         ret = dlt_user_log_out3(dlt_user.dlt_log_handle,
2915                                                                         &(userheader), sizeof(DltUserHeader),
2916                                                                         0, 0,
2917                                                                         0, 0);
2918 #else
2919                         /* log to FIFO */
2920 #ifdef DLT_TEST_ENABLE
2921                         if(dlt_user.corrupt_user_header) {
2922                                 userheader.pattern[0]=0xff;
2923                                 userheader.pattern[1]=0xff;
2924                                 userheader.pattern[2]=0xff;
2925                                 userheader.pattern[3]=0xff;
2926                         }
2927                         if(dlt_user.corrupt_message_size) {
2928                                 msg.standardheader->len = DLT_HTOBE_16(dlt_user.corrupt_message_size_size);
2929                         }
2930 #endif
2931                         ret = dlt_user_log_out3(dlt_user.dlt_log_handle,
2932                                                                         &(userheader), sizeof(DltUserHeader),
2933                                                                         msg.headerbuffer+sizeof(DltStorageHeader), msg.headersize-sizeof(DltStorageHeader),
2934                                                                         log->buffer, log->size);                
2935 #endif                  
2936                 }
2937                 
2938         /* store message in ringbuffer, if an error has occured */
2939         if (ret!=DLT_RETURN_OK)
2940         {
2941             DLT_SEM_LOCK();
2942
2943             if (dlt_buffer_push3(&(dlt_user.startup_buffer),
2944                                 (unsigned char *)&(userheader), sizeof(DltUserHeader),
2945                                 msg.headerbuffer+sizeof(DltStorageHeader), msg.headersize-sizeof(DltStorageHeader),
2946                                 log->buffer, log->size)==-1)
2947                         {
2948                                 dlt_log(LOG_ERR,"Storing message to history buffer failed! Message discarded.\n");
2949                                 ret = DLT_RETURN_BUFFER_FULL;
2950                         }
2951
2952             DLT_SEM_FREE();
2953
2954                 // Fail silenty if FIFO is not open
2955             if(dlt_user_queue_resend() < 0 && dlt_user.dlt_log_handle >= 0)
2956             {
2957                 dlt_log(LOG_WARNING, "Failed to queue resending.\n");
2958             }
2959         }
2960
2961         switch (ret)
2962         {
2963         case DLT_RETURN_BUFFER_FULL:
2964         {
2965                 /* Buffer full */
2966                 return DLT_RETURN_BUFFER_FULL;
2967         }
2968         case DLT_RETURN_PIPE_FULL:
2969         {
2970             /* data could not be written */
2971             dlt_user.overflow = 1;
2972             return DLT_RETURN_PIPE_FULL;
2973         }
2974         case DLT_RETURN_PIPE_ERROR:
2975         {
2976             /* handle not open or pipe error */
2977             close(dlt_user.dlt_log_handle);
2978             dlt_user.dlt_log_handle = -1;
2979
2980 #ifdef DLT_SHM_ENABLE
2981                         /* free shared memory */
2982                         dlt_shm_free_client(&dlt_user.dlt_shm);
2983 #endif
2984
2985             if (dlt_user.local_print_mode == DLT_PM_AUTOMATIC)
2986             {
2987                 dlt_user_print_msg(&msg, log);
2988             }
2989
2990             return DLT_RETURN_PIPE_ERROR;
2991         }
2992         case DLT_RETURN_ERROR:
2993         {
2994             /* other error condition */
2995             return DLT_RETURN_ERROR;
2996         }
2997                 case DLT_RETURN_OK:
2998         {
2999                 return DLT_RETURN_OK;
3000         }
3001                 default:
3002                 {
3003                         /* This case should never occur. */
3004                         return DLT_RETURN_ERROR;
3005                 }
3006         }
3007     }
3008
3009     return DLT_RETURN_OK;
3010 }
3011
3012 int dlt_user_log_send_register_application(void)
3013 {
3014     DltUserHeader userheader;
3015     DltUserControlMsgRegisterApplication usercontext;
3016
3017     DltReturnValue ret;
3018
3019     if (dlt_user.appID[0]=='\0')
3020     {
3021         return -1;
3022     }
3023
3024     /* set userheader */
3025     if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_REGISTER_APPLICATION)==-1)
3026     {
3027                 return -1;
3028     }
3029
3030     /* set usercontext */
3031     dlt_set_id(usercontext.apid,dlt_user.appID);       /* application id */
3032     usercontext.pid = getpid();
3033
3034     if (dlt_user.application_description!=0)
3035     {
3036         usercontext.description_length = strlen(dlt_user.application_description);
3037     }
3038     else
3039     {
3040         usercontext.description_length = 0;
3041     }
3042
3043     if (dlt_user.dlt_is_file)
3044     {
3045         return 0;
3046     }
3047
3048     /* log to FIFO */
3049     ret=dlt_user_log_out3(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgRegisterApplication),dlt_user.application_description,usercontext.description_length);
3050
3051     /* store message in ringbuffer, if an error has occured */
3052     if (ret!=DLT_RETURN_OK)
3053     {
3054         DLT_SEM_LOCK();
3055
3056         if (dlt_buffer_push3(&(dlt_user.startup_buffer),
3057                             (unsigned char *)&(userheader), sizeof(DltUserHeader),
3058                             (const unsigned char*)&(usercontext), sizeof(DltUserControlMsgRegisterApplication),
3059                             (const unsigned char*)dlt_user.application_description, usercontext.description_length)==-1)
3060              {
3061                     dlt_log(LOG_ERR,"Storing message to history buffer failed! Message discarded.\n");
3062                     DLT_SEM_FREE();
3063                     return -1;
3064              }
3065
3066         DLT_SEM_FREE();
3067
3068         if(dlt_user_queue_resend() < 0 && dlt_user.dlt_log_handle >= 0)
3069         {
3070                 dlt_log(LOG_WARNING, "Failed to queue resending.\n");
3071         }
3072     }
3073
3074     return 0;
3075 }
3076
3077 int dlt_user_log_send_unregister_application(void)
3078 {
3079     DltUserHeader userheader;
3080     DltUserControlMsgUnregisterApplication usercontext;
3081
3082     DltReturnValue ret;
3083
3084     if (dlt_user.appID[0]=='\0')
3085     {
3086         return -1;
3087     }
3088
3089     /* set userheader */
3090     if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_UNREGISTER_APPLICATION)==-1)
3091     {
3092         return -1;
3093     }
3094
3095     /* set usercontext */
3096     dlt_set_id(usercontext.apid,dlt_user.appID);       /* application id */
3097     usercontext.pid = getpid();
3098
3099     if (dlt_user.dlt_is_file)
3100     {
3101         return 0;
3102     }
3103
3104     /* log to FIFO */
3105     ret=dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgUnregisterApplication));
3106     return ((ret==DLT_RETURN_OK)?0:-1);
3107 }
3108
3109 int dlt_user_log_send_register_context(DltContextData *log)
3110 {
3111     DltUserHeader userheader;
3112     DltUserControlMsgRegisterContext usercontext;
3113     DltReturnValue ret;
3114
3115     if (log==0)
3116     {
3117                 return -1;
3118     }
3119
3120     if (log->handle==0)
3121     {
3122         return -1;
3123     }
3124
3125     if ((dlt_user.appID[0]=='\0') || (log->handle->contextID=='\0'))
3126     {
3127         return -1;
3128     }
3129
3130     /* set userheader */
3131     if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_REGISTER_CONTEXT)==-1)
3132     {
3133                 return -1;
3134     }
3135
3136     /* set usercontext */
3137     dlt_set_id(usercontext.apid,dlt_user.appID);       /* application id */
3138     dlt_set_id(usercontext.ctid,log->handle->contextID);       /* context id */
3139     usercontext.log_level_pos = log->handle->log_level_pos;
3140     usercontext.pid = getpid();
3141
3142     usercontext.log_level = (int8_t)log->log_level;
3143     usercontext.trace_status = (int8_t)log->trace_status;
3144
3145     if (log->context_description!=0)
3146     {
3147         usercontext.description_length = strlen(log->context_description);
3148     }
3149     else
3150     {
3151                 usercontext.description_length = 0;
3152     }
3153
3154     if (dlt_user.dlt_is_file)
3155     {
3156         return 0;
3157     }
3158
3159     /* log to FIFO */
3160     ret=dlt_user_log_out3(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgRegisterContext),log->context_description,usercontext.description_length);
3161
3162     /* store message in ringbuffer, if an error has occured */
3163     if (ret!=DLT_RETURN_OK)
3164     {
3165         DLT_SEM_LOCK();
3166
3167         if (dlt_buffer_push3(&(dlt_user.startup_buffer),
3168                             (unsigned char *)&(userheader), sizeof(DltUserHeader),
3169                             (const unsigned char*)&(usercontext), sizeof(DltUserControlMsgRegisterContext),
3170                             (const unsigned char*)log->context_description, usercontext.description_length)==-1)
3171              {
3172                     dlt_log(LOG_ERR,"Storing message to history buffer failed! Message discarded.\n");
3173                     DLT_SEM_FREE();
3174                     return -1;
3175              }
3176
3177         DLT_SEM_FREE();
3178
3179         if(dlt_user_queue_resend() < 0 && dlt_user.dlt_log_handle >= 0)
3180         {
3181                 dlt_log(LOG_WARNING, "Failed to queue resending.\n");
3182         }
3183     }
3184
3185     return 0;
3186
3187 }
3188
3189 int dlt_user_log_send_unregister_context(DltContextData *log)
3190 {
3191     DltUserHeader userheader;
3192     DltUserControlMsgUnregisterContext usercontext;
3193     DltReturnValue ret;
3194
3195     if (log==0)
3196     {
3197         return -1;
3198     }
3199
3200     if (log->handle==0)
3201     {
3202         return -1;
3203     }
3204
3205     if ((dlt_user.appID[0]=='\0') || (log->handle->contextID=='\0'))
3206     {
3207         return -1;
3208     }
3209
3210     /* set userheader */
3211     if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_UNREGISTER_CONTEXT)==-1)
3212     {
3213                 return -1;
3214     }
3215
3216     /* set usercontext */
3217     dlt_set_id(usercontext.apid,dlt_user.appID);       /* application id */
3218     dlt_set_id(usercontext.ctid,log->handle->contextID);       /* context id */
3219     usercontext.pid = getpid();
3220
3221     if (dlt_user.dlt_is_file)
3222     {
3223         return 0;
3224     }
3225
3226     /* log to FIFO */
3227     ret=dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgUnregisterContext));
3228         return ((ret==DLT_RETURN_OK)?0:-1);
3229 }
3230
3231 int dlt_send_app_ll_ts_limit(const char *appid, DltLogLevelType loglevel, DltTraceStatusType tracestatus)
3232 {
3233     DltUserHeader userheader;
3234     DltUserControlMsgAppLogLevelTraceStatus usercontext;
3235         DltReturnValue ret;
3236
3237     if ((appid==0) || (appid[0]=='\0'))
3238     {
3239         return -1;
3240     }
3241
3242     /* Removed because of DltLogLevelType and DltTraceStatusType
3243
3244     if ((loglevel<DLT_LOG_DEFAULT) || (loglevel>DLT_LOG_VERBOSE))
3245     {
3246         return -1;
3247     }
3248
3249     if ((tracestatus<DLT_TRACE_STATUS_DEFAULT) || (tracestatus>DLT_TRACE_STATUS_ON))
3250     {
3251         return -1;
3252     }
3253
3254     */
3255
3256     /* set userheader */
3257     if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_APP_LL_TS)==-1)
3258     {
3259                 return -1;
3260     }
3261
3262     /* set usercontext */
3263     dlt_set_id(usercontext.apid,appid);       /* application id */
3264     usercontext.log_level = loglevel;
3265     usercontext.trace_status = tracestatus;
3266
3267     if (dlt_user.dlt_is_file)
3268     {
3269         return 0;
3270     }
3271
3272     /* log to FIFO */
3273     ret=dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgAppLogLevelTraceStatus));
3274     return ((ret==DLT_RETURN_OK)?0:-1);
3275 }
3276
3277 int dlt_user_log_send_log_mode(DltUserLogMode mode)
3278 {
3279     DltUserHeader userheader;
3280     DltUserControlMsgLogMode logmode;
3281
3282     DltReturnValue ret;
3283
3284     /* set userheader */
3285     if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG_MODE)==-1)
3286     {
3287         return -1;
3288     }
3289
3290     /* set data */
3291     logmode.log_mode = (unsigned char) mode;
3292
3293     if (dlt_user.dlt_is_file)
3294     {
3295         return 0;
3296     }
3297
3298     /* log to FIFO */
3299     ret=dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(logmode), sizeof(DltUserControlMsgLogMode));
3300     return ((ret==DLT_RETURN_OK)?0:-1);
3301 }
3302
3303 int dlt_user_print_msg(DltMessage *msg, DltContextData *log)
3304 {
3305     uint8_t *databuffer_tmp;
3306     int32_t datasize_tmp;
3307     int32_t databuffersize_tmp;
3308     static char text[DLT_USER_TEXT_LENGTH];
3309
3310     if ((msg==0) || (log==0))
3311     {
3312         return -1;
3313     }
3314
3315     /* Save variables before print */
3316     databuffer_tmp = msg->databuffer;
3317     datasize_tmp = msg->datasize;
3318     databuffersize_tmp = msg->databuffersize;
3319
3320     /* Act like a receiver, convert header back to host format */
3321     msg->standardheader->len = DLT_BETOH_16(msg->standardheader->len);
3322     dlt_message_get_extraparameters(msg,0);
3323
3324     msg->databuffer = log->buffer;
3325     msg->datasize = log->size;
3326     msg->databuffersize = log->size;
3327
3328     /* Print message as ASCII */
3329     if (dlt_message_print_ascii(msg,text,DLT_USER_TEXT_LENGTH,0)==-1)
3330     {
3331                 return -1;
3332     }
3333
3334     /* Restore variables and set len to BE*/
3335     msg->databuffer = databuffer_tmp;
3336     msg->databuffersize = databuffersize_tmp;
3337     msg->datasize =  datasize_tmp;
3338
3339     msg->standardheader->len = DLT_HTOBE_16(msg->standardheader->len);
3340
3341     return 0;
3342 }
3343
3344 int dlt_user_log_check_user_message(void)
3345 {
3346     int offset=0;
3347     int leave_while=0;
3348
3349     uint32_t i;
3350
3351     DltUserHeader *userheader;
3352     DltReceiver *receiver = &(dlt_user.receiver);
3353
3354     DltUserControlMsgLogLevel *usercontextll;
3355     DltUserControlMsgInjection *usercontextinj;
3356     DltUserControlMsgLogState *userlogstate;
3357     unsigned char *userbuffer;
3358
3359     /* For delayed calling of injection callback, to avoid deadlock */
3360     DltUserInjectionCallback    delayed_injection_callback;
3361     unsigned char                               *delayed_inject_buffer = 0;
3362     uint32_t                                    delayed_inject_data_length = 0;
3363
3364     /* Ensure that callback is null before searching for it */
3365     delayed_injection_callback.injection_callback = 0;
3366     delayed_injection_callback.service_id = 0;
3367
3368     if (dlt_user.dlt_user_handle!=DLT_FD_INIT)
3369     {
3370         while (1)
3371         {
3372             if (dlt_receiver_receive_fd(receiver)<=0)
3373             {
3374                 /* No new message available */
3375                 return 0;
3376             }
3377
3378             /* look through buffer as long as data is in there */
3379             while (1)
3380             {
3381                 if (receiver->bytesRcvd < (int32_t)sizeof(DltUserHeader))
3382                 {
3383                     break;
3384                 }
3385
3386                 /* resync if necessary */
3387                 offset=0;
3388                 do
3389                 {
3390                     userheader = (DltUserHeader*) (receiver->buf+offset);
3391
3392                     /* Check for user header pattern */
3393                     if (dlt_user_check_userheader(userheader))
3394                     {
3395                         break;
3396                     }
3397                     offset++;
3398
3399                 }
3400                 while ((int32_t)(sizeof(DltUserHeader)+offset)<=receiver->bytesRcvd);
3401
3402                 /* Check for user header pattern */
3403                 if (dlt_user_check_userheader(userheader)<0 ||
3404                     dlt_user_check_userheader(userheader)==0)
3405                 {
3406                     break;
3407                 }
3408
3409                 /* Set new start offset */
3410                 if (offset>0)
3411                 {
3412                     receiver->buf+=offset;
3413                     receiver->bytesRcvd-=offset;
3414                 }
3415
3416                 switch (userheader->message)
3417                 {
3418                 case DLT_USER_MESSAGE_LOG_LEVEL:
3419                 {
3420                     if (receiver->bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogLevel)))
3421                     {
3422                         leave_while=1;
3423                         break;
3424                     }
3425
3426                     usercontextll = (DltUserControlMsgLogLevel*) (receiver->buf+sizeof(DltUserHeader));
3427
3428                     /* Update log level and trace status */
3429                     if (usercontextll!=0)
3430                     {
3431                         DLT_SEM_LOCK();
3432
3433                         if ((usercontextll->log_level_pos >= 0) && (usercontextll->log_level_pos < (int32_t)dlt_user.dlt_ll_ts_num_entries))
3434                         {
3435                             // printf("Store ll, ts\n");
3436                             if (dlt_user.dlt_ll_ts)
3437                             {
3438                                 dlt_user.dlt_ll_ts[usercontextll->log_level_pos].log_level = usercontextll->log_level;
3439                                 dlt_user.dlt_ll_ts[usercontextll->log_level_pos].trace_status = usercontextll->trace_status;
3440                             }
3441                         }
3442
3443                         DLT_SEM_FREE();
3444                     }
3445
3446                     /* keep not read data in buffer */
3447                     if (dlt_receiver_remove(receiver,sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogLevel))==-1)
3448                     {
3449                         return -1;
3450                     }
3451                 }
3452                 break;
3453                 case DLT_USER_MESSAGE_INJECTION:
3454                 {
3455                     /* At least, user header, user context, and service id and data_length of injected message is available */
3456                     if (receiver->bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgInjection)))
3457                     {
3458                         leave_while = 1;
3459                         break;
3460                     }
3461
3462                     usercontextinj = (DltUserControlMsgInjection*) (receiver->buf+sizeof(DltUserHeader));
3463                     userbuffer = (unsigned char*) (receiver->buf+sizeof(DltUserHeader)+sizeof(DltUserControlMsgInjection));
3464
3465                     if (userbuffer!=0)
3466                     {
3467
3468                         if (receiver->bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgInjection)+usercontextinj->data_length_inject))
3469                         {
3470                             leave_while = 1;
3471                             break;
3472                         }
3473
3474                         DLT_SEM_LOCK();
3475
3476                         if ((usercontextinj->data_length_inject>0) && (dlt_user.dlt_ll_ts))
3477                         {
3478                             /* Check if injection callback is registered for this context */
3479                             for (i=0; i<dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].nrcallbacks;i++)
3480                             {
3481                                 if ((dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table) &&
3482                                         (dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table[i].service_id == usercontextinj->service_id))
3483                                 {
3484                                         /* Prepare delayed injection callback call */
3485                                                                         if (dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table[i].injection_callback!=0)
3486                                                                         {
3487                                                                                 delayed_injection_callback.injection_callback = dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table[i].injection_callback;
3488                                                                                 delayed_injection_callback.service_id = usercontextinj->service_id;
3489                                                                                 delayed_inject_data_length = usercontextinj->data_length_inject;
3490                                                                                 delayed_inject_buffer = malloc(delayed_inject_data_length);
3491                                                                                 if(delayed_inject_buffer != 0) {
3492                                                                                         memcpy(delayed_inject_buffer, userbuffer, delayed_inject_data_length);
3493                                                                                 }
3494
3495                                                                         }
3496                                     break;
3497                                 }
3498                             }
3499                         }
3500
3501                         DLT_SEM_FREE();
3502
3503                         /* Delayed injection callback call */
3504                         if(delayed_inject_buffer != 0 && delayed_injection_callback.injection_callback != 0) {
3505                                 delayed_injection_callback.injection_callback(delayed_injection_callback.service_id, delayed_inject_buffer, delayed_inject_data_length);
3506                                 delayed_injection_callback.injection_callback = 0;
3507                                 free(delayed_inject_buffer);
3508                                 delayed_inject_buffer = NULL;
3509
3510                         }
3511
3512                         /* keep not read data in buffer */
3513                         if (dlt_receiver_remove(receiver,(sizeof(DltUserHeader)+sizeof(DltUserControlMsgInjection)+usercontextinj->data_length_inject))==-1)
3514                                                 {
3515                                                         return -1;
3516                                                 }
3517                     }
3518                 }
3519                 break;
3520                 case DLT_USER_MESSAGE_LOG_STATE:
3521                 {
3522                     /* At least, user header, user context, and service id and data_length of injected message is available */
3523                     if (receiver->bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogState)))
3524                     {
3525                         leave_while = 1;
3526                         break;
3527                     }
3528
3529                     userlogstate = (DltUserControlMsgLogState*) (receiver->buf+sizeof(DltUserHeader));
3530                                         dlt_user.log_state = userlogstate->log_state;
3531
3532                                         /* keep not read data in buffer */
3533                                         if (dlt_receiver_remove(receiver,(sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogState)))==-1)
3534                                         {
3535                                                 return -1;
3536                                         }
3537                 }
3538                 break;
3539                 default:
3540                 {
3541                     dlt_log(LOG_ERR,"Invalid user message type received!\n");
3542                     /* Ignore result */
3543                     dlt_receiver_remove(receiver,sizeof(DltUserHeader));
3544                                         /* In next invocation of while loop, a resync will be triggered if additional data was received */
3545                 }
3546                 break;
3547                 } /* switch() */
3548
3549                 if (leave_while==1)
3550                 {
3551                     leave_while=0;
3552                     break;
3553                 }
3554
3555             } /* while buffer*/
3556
3557             if (dlt_receiver_move_to_begin(receiver)==-1)
3558             {
3559                                 return -1;
3560             }
3561         } /* while receive */
3562     } /* if */
3563
3564     return DLT_RETURN_OK;
3565 }
3566
3567 int dlt_user_log_resend_buffer(void)
3568 {
3569         int num,count;
3570     int size;
3571         DltReturnValue ret;
3572         
3573         /* Send content of ringbuffer */
3574         DLT_SEM_LOCK();
3575         count = dlt_buffer_get_message_count(&(dlt_user.startup_buffer));
3576         DLT_SEM_FREE();
3577
3578         for (num=0;num<count;num++)
3579         {
3580
3581                 DLT_SEM_LOCK();
3582                 size = dlt_buffer_copy(&(dlt_user.startup_buffer),dlt_user.resend_buffer,sizeof(dlt_user.resend_buffer));
3583
3584                 if (size>0)
3585                 {
3586 #ifdef DLT_SHM_ENABLE                                           
3587                         dlt_shm_push(&dlt_user.dlt_shm,dlt_user.resend_buffer+sizeof(DltUserHeader),size-sizeof(DltUserHeader),0,0,0,0);
3588
3589                         /* log to FIFO */
3590                         ret = dlt_user_log_out3(dlt_user.dlt_log_handle, dlt_user.resend_buffer,sizeof(DltUserHeader),0,0,0,0);
3591 #else
3592                         /* log to FIFO */
3593                         ret = dlt_user_log_out3(dlt_user.dlt_log_handle, dlt_user.resend_buffer,size,0,0,0,0);
3594 #endif
3595
3596                         /* in case of error, keep message in ringbuffer */                        
3597                         if (ret==DLT_RETURN_OK)
3598                         {
3599                                 dlt_buffer_remove(&(dlt_user.startup_buffer));
3600                         }
3601                         else
3602                         {
3603                                 /* keep message in ringbuffer */   
3604                                 DLT_SEM_FREE();
3605                                 return -1;
3606                         }
3607                 }
3608                 DLT_SEM_FREE();
3609         }
3610         
3611         return 0;
3612 }
3613
3614 void dlt_user_log_reattach_to_daemon(void)
3615 {
3616         uint32_t num,reregistered=0;
3617
3618         DltContext handle;
3619         DltContextData log_new;
3620
3621     if (dlt_user.dlt_log_handle<0)
3622     {
3623         dlt_user.dlt_log_handle=-1;
3624
3625         /* try to open pipe to dlt daemon */
3626         dlt_user.dlt_log_handle = open(DLT_USER_FIFO, O_WRONLY | O_NONBLOCK);
3627         if (dlt_user.dlt_log_handle > 0)
3628         {
3629             if (dlt_user_log_init(&handle,&log_new)==-1)
3630             {
3631                 return;
3632             }
3633
3634 #ifdef DLT_SHM_ENABLE
3635                         /* init shared memory */
3636                         if (dlt_shm_init_client(&dlt_user.dlt_shm,DLT_SHM_KEY) < 0)
3637                         {
3638                                 sprintf(str,"Loging disabled, Shared memory %d cannot be created!\n",DLT_SHM_KEY);
3639                                 dlt_log(LOG_WARNING, str);
3640                                 //return 0; 
3641                         }   
3642 #endif
3643
3644             dlt_log(LOG_NOTICE, "Logging re-enabled!\n");
3645
3646             /* Re-register application */
3647             if (dlt_user_log_send_register_application()==-1)
3648             {
3649                 return;
3650             }
3651
3652             DLT_SEM_LOCK();
3653
3654             /* Re-register all stored contexts */
3655             for (num=0; num<dlt_user.dlt_ll_ts_num_entries; num++)
3656             {
3657                 /* Re-register stored context */
3658                 if ((dlt_user.appID[0]!='\0') && (dlt_user.dlt_ll_ts) && (dlt_user.dlt_ll_ts[num].contextID[0]!='\0'))
3659                 {
3660                     //dlt_set_id(log_new.appID, dlt_user.appID);
3661                     dlt_set_id(handle.contextID, dlt_user.dlt_ll_ts[num].contextID);
3662                     handle.log_level_pos = num;
3663                     log_new.context_description = dlt_user.dlt_ll_ts[num].context_description;
3664
3665                     log_new.log_level = DLT_USER_LOG_LEVEL_NOT_SET;
3666                     log_new.trace_status = DLT_USER_TRACE_STATUS_NOT_SET;
3667
3668                     if (dlt_user_log_send_register_context(&log_new)==-1)
3669                     {
3670                         DLT_SEM_FREE();
3671                         return;
3672                     }
3673
3674                     reregistered=1;
3675                 }
3676             }
3677
3678             DLT_SEM_FREE();
3679
3680             if (reregistered==1)
3681             {
3682                                 dlt_user_log_resend_buffer();
3683             }
3684         }
3685     }
3686 }
3687
3688 int dlt_user_log_send_overflow(void)
3689 {
3690     DltUserHeader userheader;
3691     DltReturnValue ret;
3692
3693     /* set userheader */
3694     if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_OVERFLOW)==-1)
3695     {
3696         return -1;
3697     }
3698
3699     if (dlt_user.dlt_is_file)
3700     {
3701         return 0;
3702     }
3703
3704     /* log to FIFO */
3705     ret=dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), 0, 0);
3706     return ((ret==DLT_RETURN_OK)?0:-1);
3707 }
3708
3709 int dlt_user_check_buffer(int *total_size, int *used_size)
3710 {
3711 #ifdef DLT_SHM_ENABLE
3712         *total_size = dlt_shm_get_total_size(&(dlt_user.dlt_shm));
3713         *used_size = dlt_shm_get_used_size(&(dlt_user.dlt_shm));
3714 #else
3715         *total_size = dlt_buffer_get_total_size(&(dlt_user.startup_buffer));
3716         *used_size = dlt_buffer_get_used_size(&(dlt_user.startup_buffer));
3717 #endif
3718         
3719         return 0; /* ok */
3720 }
3721
3722 #ifdef DLT_TEST_ENABLE
3723 void dlt_user_test_corrupt_user_header(int enable)
3724 {
3725     dlt_user.corrupt_user_header = enable;
3726 }
3727 void dlt_user_test_corrupt_message_size(int enable,int16_t size)
3728 {
3729     dlt_user.corrupt_message_size = enable;
3730     dlt_user.corrupt_message_size_size = size;
3731 }
3732 #endif
3733
3734