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