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