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