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