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