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