Modified library for new test cases to corrupt data - related to the bug fix for...
[profile/ivi/dlt-daemon.git] / src / lib / dlt_user.c
1 /*
2 * Dlt- Diagnostic Log and Trace user library
3 * @licence app begin@
4  *
5  * Copyright (C) 2011, BMW AG - Alexander Wenzel <alexander.wenzel@bmw.de>
6  * 
7  * This program is free software; you can redistribute it and/or modify it under the terms of the 
8  * GNU Lesser General Public License, version 2.1, as published by the Free Software Foundation.
9  * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even 
10  * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General 
11  * Public License, version 2.1, for more details.
12  * 
13  * You should have received a copy of the GNU Lesser General Public License, version 2.1, along 
14  * with this program; if not, see <http://www.gnu.org/licenses/lgpl-2.1.html>.
15  * 
16  * Note that the copyright holders assume that the GNU Lesser General Public License, version 2.1, may 
17  * also be applicable to programs even in cases in which the program is not a library in the technical sense.
18  * 
19  * Linking DLT statically or dynamically with other modules is making a combined work based on DLT. You may 
20  * license such other modules under the GNU Lesser General Public License, version 2.1. If you do not want to 
21  * license your linked modules under the GNU Lesser General Public License, version 2.1, you 
22  * may use the program under the following exception.
23  * 
24  * As a special exception, the copyright holders of DLT give you permission to combine DLT 
25  * with software programs or libraries that are released under any license unless such a combination is not
26  * permitted by the license of such a software program or library. You may copy and distribute such a 
27  * system following the terms of the GNU Lesser General Public License, version 2.1, including this
28  * special exception, for DLT and the licenses of the other code concerned.
29  * 
30  * Note that people who make modified versions of DLT are not obligated to grant this special exception 
31  * for their modified versions; it is their choice whether to do so. The GNU Lesser General Public License, 
32  * version 2.1, gives permission to release a modified version without this exception; this exception 
33  * also makes it possible to release a modified version which carries forward this exception.
34  *
35  * @licence end@
36 */
37
38
39 /*******************************************************************************
40 **                                                                            **
41 **  SRC-MODULE: dlt_user.c                                                    **
42 **                                                                            **
43 **  TARGET    : linux                                                         **
44 **                                                                            **
45 **  PROJECT   : DLT                                                           **
46 **                                                                            **
47 **  AUTHOR    : Alexander Wenzel Alexander.AW.Wenzel@bmw.de                   **
48 **              Markus Klein                                                  **
49 **                                                                            **
50 **  PURPOSE   :                                                               **
51 **                                                                            **
52 **  REMARKS   :                                                               **
53 **                                                                            **
54 **  PLATFORM DEPENDANT [yes/no]: yes                                          **
55 **                                                                            **
56 **  TO BE CHANGED BY USER [yes/no]: no                                        **
57 **                                                                            **
58 *******************************************************************************/
59
60 /*******************************************************************************
61 **                      Author Identity                                       **
62 ********************************************************************************
63 **                                                                            **
64 ** Initials     Name                       Company                            **
65 ** --------     -------------------------  ---------------------------------- **
66 **  aw          Alexander Wenzel           BMW                                **
67 **  mk          Markus Klein               Fraunhofer ESK                     **
68 *******************************************************************************/
69
70 /*******************************************************************************
71 **                      Revision Control History                              **
72 *******************************************************************************/
73
74 /*
75  * $LastChangedRevision: 1670 $
76  * $LastChangedDate: 2011-04-08 15:12:06 +0200 (Fr, 08. Apr 2011) $
77  * $LastChangedBy$
78  Initials    Date         Comment
79  aw          13.01.2010   initial
80  */
81
82 #include <stdlib.h> /* for getenv(), free(), atexit() */
83 #include <string.h> /* for strcmp(), strncmp(), strlen(), memset(), memcpy() */
84 #include <signal.h> /* for signal(), SIGPIPE, SIG_IGN */
85
86 #if !defined (__WIN32__)
87 #include <syslog.h> /* for LOG_... */
88 #include <semaphore.h>
89 #include <pthread.h>    /* POSIX Threads */
90 #endif
91
92 #include <sys/stat.h>
93 #include <fcntl.h>
94 #include <errno.h>
95
96 #include <sys/uio.h> /* writev() */
97
98 #include "dlt_user.h"
99 #include "dlt_user_shared.h"
100 #include "dlt_user_shared_cfg.h"
101 #include "dlt_user_cfg.h"
102
103 static DltUser dlt_user;
104 static int dlt_user_initialised = 0;
105
106 static char str[DLT_USER_BUFFER_LENGTH];
107
108 static sem_t dlt_mutex;
109 static pthread_t dlt_receiverthread_handle;
110 static pthread_attr_t dlt_receiverthread_attr;
111
112 /* Function prototypes for internally used functions */
113 static void dlt_user_receiverthread_function(void *ptr);
114 static void dlt_user_atexit_handler(void);
115 static int dlt_user_log_init(DltContext *handle, DltContextData *log);
116 static int dlt_user_log_send_log(DltContextData *log, int mtype);
117 static int dlt_user_log_send_register_application(void);
118 static int dlt_user_log_send_unregister_application(void);
119 static int dlt_user_log_send_register_context(DltContextData *log);
120 static int dlt_user_log_send_unregister_context(DltContextData *log);
121 static int dlt_send_app_ll_ts_limit(const char *appid, DltLogLevelType loglevel, DltTraceStatusType tracestatus);
122 static int dlt_user_log_send_log_mode(DltUserLogMode mode);
123 static int dlt_user_print_msg(DltMessage *msg, DltContextData *log);
124 static int dlt_user_log_check_user_message(void);
125 static int dlt_user_log_resend_buffer(void);
126 static void dlt_user_log_reattach_to_daemon(void);
127 static int dlt_user_log_send_overflow(void);
128
129 int dlt_user_check_library_version(const char *user_major_version,const char *user_minor_version){
130
131         char str[200];
132         char lib_major_version[DLT_USER_MAX_LIB_VERSION_LENGTH];
133         char lib_minor_version[DLT_USER_MAX_LIB_VERSION_LENGTH];
134
135         dlt_get_major_version( lib_major_version);
136         dlt_get_minor_version( lib_minor_version);
137
138         if( (strcmp(lib_major_version,user_major_version)!=0) || (strcmp(lib_minor_version,user_minor_version)!=0))
139         {
140                 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);
141                 dlt_log(LOG_WARNING, str);
142                 return -1;
143         }
144         return 0;
145 }
146
147 int dlt_init(void)
148 {
149     char filename[DLT_USER_MAX_FILENAME_LENGTH];
150     int ret;
151
152     dlt_user_initialised = 1;
153
154     /* Initialize common part of dlt_init()/dlt_init_file() */
155     if (dlt_init_common()==-1)
156     {
157         dlt_user_initialised = 0;
158         return -1;
159     }
160
161     dlt_user.dlt_is_file = 0;
162     dlt_user.overflow = 0;
163 #ifdef DLT_SHM_ENABLE
164         memset(&(dlt_user.dlt_shm),0,sizeof(DltShm));
165 #endif
166
167     /* create and open DLT user FIFO */
168     sprintf(filename,"%s/dlt%d",DLT_USER_DIR,getpid());
169      
170     /* Try to delete existing pipe, ignore result of unlink */
171     unlink(filename);
172     
173     ret=mkfifo(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH  | S_IWOTH );
174     if (ret==-1)
175     {
176         sprintf(str,"Loging disabled, FIFO user %s cannot be created!\n",filename);
177         dlt_log(LOG_WARNING, str);
178         /* return 0; */ /* removed to prevent error, when FIFO already exists */
179     }
180
181     dlt_user.dlt_user_handle = open(filename, O_RDWR);
182     if (dlt_user.dlt_user_handle == -1)
183     {
184         sprintf(str,"Loging disabled, FIFO user %s cannot be opened!\n",filename);
185         dlt_log(LOG_WARNING, str);
186         unlink(filename);
187         return 0;
188     }
189
190     /* open DLT output FIFO */
191     dlt_user.dlt_log_handle = open(DLT_USER_FIFO, O_WRONLY | O_NONBLOCK);
192     if (dlt_user.dlt_log_handle==-1)
193     {
194         sprintf(str,"Loging disabled, FIFO %s cannot be opened with open()!\n",DLT_USER_FIFO);
195         dlt_log(LOG_WARNING, str);
196         //return 0;
197     }
198         else
199         {
200 #ifdef DLT_SHM_ENABLE
201                 /* init shared memory */
202                 if (dlt_shm_init_client(&(dlt_user.dlt_shm),DLT_SHM_KEY) < 0)
203                 {
204                         sprintf(str,"Loging disabled, Shared memory %d cannot be created!\n",DLT_SHM_KEY);
205                         dlt_log(LOG_WARNING, str);
206                         //return 0; 
207                 }   
208 #endif
209         }
210                 
211
212     if (dlt_receiver_init(&(dlt_user.receiver),dlt_user.dlt_user_handle, DLT_USER_RCVBUF_MAX_SIZE)==-1)
213         {
214         dlt_user_initialised = 0;
215         return -1;
216     }
217
218     /* Start receiver thread */
219     if (pthread_create(&(dlt_receiverthread_handle),
220                        0,
221                        (void *) &dlt_user_receiverthread_function,
222                        0)!=0)
223         {
224                 if (pthread_attr_destroy(&dlt_receiverthread_attr)!=0)
225                 {
226                         dlt_log(LOG_WARNING, "Can't destroy thread attributes!\n");
227                 }
228
229                 dlt_log(LOG_CRIT, "Can't create receiver thread!\n");
230                 dlt_user_initialised = 0;
231         return -1;
232         }
233
234     if (pthread_attr_destroy(&dlt_receiverthread_attr)!=0)
235         {
236                 dlt_log(LOG_WARNING, "Can't destroy thread attributes!\n");
237         }
238
239     return 0;
240 }
241
242 int dlt_init_file(const char *name)
243 {
244     dlt_user_initialised = 1;
245
246     /* Initialize common part of dlt_init()/dlt_init_file() */
247     if (dlt_init_common()==-1)
248     {
249         dlt_user_initialised = 0;
250         return -1;
251     }
252
253     dlt_user.dlt_is_file = 1;
254
255     /* open DLT output file */
256     dlt_user.dlt_log_handle = open(name,O_WRONLY|O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); /* mode: wb */
257     if (dlt_user.dlt_log_handle == -1)
258     {
259         sprintf(str,"Log file %s cannot be opened!\n",name);
260         dlt_log(LOG_ERR, str);
261         return -1;
262     }
263
264     return 0;
265 }
266
267 int dlt_init_common(void)
268 {
269     char *env_local_print;
270
271     /* Binary semaphore for threads */
272     if (sem_init(&dlt_mutex, 0, 1)==-1)
273     {
274         dlt_user_initialised = 0;
275         return -1;
276     }
277
278         /* set to unknown state of connected client */
279         dlt_user.log_state = -1;
280
281     dlt_user.dlt_log_handle=-1;
282     dlt_user.dlt_user_handle=-1;
283
284     dlt_set_id(dlt_user.ecuID,DLT_USER_DEFAULT_ECU_ID);
285     dlt_set_id(dlt_user.appID,"");
286
287     dlt_user.application_description = 0;
288
289     /* Verbose mode is enabled by default */
290     dlt_user.verbose_mode = 1;
291
292     /* Local print is disabled by default */
293     dlt_user.enable_local_print = 0;
294
295     dlt_user.local_print_mode = DLT_PM_UNSET;
296
297     env_local_print = getenv(DLT_USER_ENV_LOCAL_PRINT_MODE);
298     if (env_local_print)
299     {
300         if (strcmp(env_local_print,"AUTOMATIC")==0)
301         {
302             dlt_user.local_print_mode = DLT_PM_AUTOMATIC;
303         }
304         else if (strcmp(env_local_print,"FORCE_ON")==0)
305         {
306             dlt_user.local_print_mode = DLT_PM_FORCE_ON;
307         }
308         else if (strcmp(env_local_print,"FORCE_OFF")==0)
309         {
310             dlt_user.local_print_mode = DLT_PM_FORCE_OFF;
311         }
312     }
313
314     /* Initialize LogLevel/TraceStatus field */
315     dlt_user.dlt_ll_ts = 0;
316     dlt_user.dlt_ll_ts_max_num_entries = 0;
317     dlt_user.dlt_ll_ts_num_entries = 0;
318
319     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)
320     {
321                 dlt_user_initialised = 0;
322         return -1;
323     }
324
325     signal(SIGPIPE,SIG_IGN);                  /* ignore pipe signals */
326
327     atexit(dlt_user_atexit_handler);
328
329 #ifdef DLT_TEST_ENABLE
330     dlt_user.corrupt_user_header = 0;
331     dlt_user.corrupt_message_size = 0;
332     dlt_user.corrupt_message_size_size = 0;
333 #endif
334
335     return 0;
336 }
337
338 void dlt_user_atexit_handler(void)
339 {
340
341         /* Try to resend potential log messages in the user buffer */
342         int count = dlt_user_atexit_blow_out_user_buffer();
343
344         if(count != 0){
345                 char tmp[256];
346                 sprintf(tmp,"Lost log messages in user buffer when exiting: %i\n",count);
347                 dlt_log(LOG_ERR, tmp);
348         }
349
350     /* Unregister app (this also unregisters all contexts in daemon) */
351     /* Ignore return value */
352     dlt_unregister_app();
353
354     /* Cleanup */
355     /* Ignore return value */
356     dlt_free();
357 }
358
359 int dlt_user_atexit_blow_out_user_buffer(void){
360
361         int count,ret;
362
363         uint32_t exitTime = dlt_uptime() + DLT_USER_ATEXIT_RESEND_BUFFER_EXIT_TIMEOUT;
364
365         while(dlt_uptime() < exitTime ){
366
367                 ret = dlt_user_log_resend_buffer();
368
369                 if(ret == 0)
370                 {
371                                 return 0;
372                 }
373
374                 usleep(DLT_USER_ATEXIT_RESEND_BUFFER_SLEEP);
375         }
376
377         DLT_SEM_LOCK();
378         count = dlt_buffer_get_message_count(&(dlt_user.startup_buffer));
379         DLT_SEM_FREE();
380
381         return count;
382 }
383
384 int dlt_free(void)
385 {
386     uint32_t i;
387         char filename[DLT_USER_MAX_FILENAME_LENGTH];
388
389     if (dlt_user_initialised==0)
390     {
391         return -1;
392     }
393
394     if (dlt_receiverthread_handle)
395     {
396         /* Ignore return value */
397         pthread_cancel(dlt_receiverthread_handle);
398     }
399
400     if (dlt_user.dlt_user_handle!=-1)
401     {
402         sprintf(filename,"/tmp/dlt%d",getpid());
403
404         close(dlt_user.dlt_user_handle);
405         dlt_user.dlt_user_handle=-1;
406
407         unlink(filename);
408     }
409
410 #ifdef DLT_SHM_ENABLE
411         /* free shared memory */
412         dlt_shm_free_client(&dlt_user.dlt_shm);
413 #endif
414
415     if (dlt_user.dlt_log_handle!=-1)
416     {
417         /* close log file/output fifo to daemon */
418         close(dlt_user.dlt_log_handle);
419         dlt_user.dlt_log_handle = -1;
420     }
421
422         /* Ignore return value */
423     dlt_receiver_free(&(dlt_user.receiver));
424
425         /* Ignore return value */
426     dlt_buffer_free_dynamic(&(dlt_user.startup_buffer));
427
428     if (dlt_user.dlt_ll_ts)
429     {
430         for (i=0;i<dlt_user.dlt_ll_ts_max_num_entries;i++)
431         {
432             if (dlt_user.dlt_ll_ts[i].injection_table!=0)
433             {
434                 free(dlt_user.dlt_ll_ts[i].injection_table);
435                 dlt_user.dlt_ll_ts[i].injection_table = 0;
436             }
437             dlt_user.dlt_ll_ts[i].nrcallbacks     = 0;
438         }
439
440         free(dlt_user.dlt_ll_ts);
441         dlt_user.dlt_ll_ts = 0;
442         dlt_user.dlt_ll_ts_max_num_entries = 0;
443         dlt_user.dlt_ll_ts_num_entries = 0;
444     }
445
446     dlt_user_initialised = 0;
447
448     return 0;
449 }
450
451 int dlt_check_library_version(const char * user_major_version,const char * user_minor_version)
452 {
453         return dlt_user_check_library_version(user_major_version, user_minor_version);
454 }
455
456 int dlt_register_app(const char *appid, const char * description)
457 {
458     int ret;
459
460     if (dlt_user_initialised==0)
461     {
462         if (dlt_init()<0)
463         {
464             return -1;
465         }
466     }
467
468     if ((appid==0) || (appid[0]=='\0'))
469     {
470         return -1;
471     }
472
473     DLT_SEM_LOCK();
474
475     /* Store locally application id and application description */
476     dlt_set_id(dlt_user.appID, appid);
477
478     if (dlt_user.application_description!=0)
479     {
480         free(dlt_user.application_description);
481     }
482
483     dlt_user.application_description = 0;
484
485     if (description!=0)
486     {
487         dlt_user.application_description= malloc(strlen(description)+1);
488         strncpy(dlt_user.application_description, description, strlen(description));
489
490         /* Terminate transmitted string with 0 */
491         dlt_user.application_description[strlen(description)]='\0';
492     }
493
494     DLT_SEM_FREE();
495
496     ret = dlt_user_log_send_register_application();
497
498     return ret;
499 }
500 int dlt_register_context(DltContext *handle, const char *contextid, const char * description)
501 {
502     if (dlt_user_initialised==0)
503     {
504         if (dlt_init()<0)
505         {
506             return -1;
507         }
508     }
509
510     DLT_SEM_LOCK();
511
512     if (dlt_user.appID[0]=='\0')
513     {
514         dlt_log(LOG_ERR, "no application registered!\n");
515
516         DLT_SEM_FREE();
517         return -1;
518     }
519
520     if ((contextid==0) || (contextid[0]=='\0'))
521     {
522         DLT_SEM_FREE();
523         return -1;
524     }
525
526     DLT_SEM_FREE();
527
528     return dlt_register_context_ll_ts(handle, contextid, description, DLT_USER_LOG_LEVEL_NOT_SET, DLT_USER_TRACE_STATUS_NOT_SET);
529 }
530
531 int dlt_register_context_ll_ts(DltContext *handle, const char *contextid, const char * description, int loglevel, int tracestatus)
532 {
533     DltContextData log;
534     uint32_t i;
535     int registered,ret;
536     char ctid[DLT_ID_SIZE+1];
537
538     if (dlt_user_initialised==0)
539     {
540         if (dlt_init()<0)
541         {
542             return -1;
543         }
544     }
545
546     DLT_SEM_LOCK();
547
548     if (dlt_user.appID[0]=='\0')
549     {
550         dlt_log(LOG_ERR, "no application registered!\n");
551
552         DLT_SEM_FREE();
553         return -1;
554     }
555
556     DLT_SEM_FREE();
557
558     if ((contextid==0) || (contextid[0]=='\0'))
559     {
560         return -1;
561     }
562
563     if ((loglevel<DLT_USER_LOG_LEVEL_NOT_SET) || (loglevel>DLT_LOG_VERBOSE) || (loglevel==DLT_LOG_DEFAULT))
564     {
565         return -1;
566     }
567
568     if ((tracestatus<DLT_USER_TRACE_STATUS_NOT_SET) || (tracestatus>DLT_TRACE_STATUS_ON) || (tracestatus==DLT_TRACE_STATUS_DEFAULT))
569     {
570         return -1;
571     }
572
573     if (dlt_user_log_init(handle, &log)==-1)
574     {
575         return -1;
576     }
577
578     /* Reset message counter */
579     handle->mcnt = 0;
580
581     /* Store context id in log level/trace status field */
582
583     /* Check if already registered, else register context */
584     DLT_SEM_LOCK();
585
586     registered=0;
587     for (i=0;i<dlt_user.dlt_ll_ts_num_entries;i++)
588     {
589         if (dlt_user.dlt_ll_ts)
590         {
591             if (memcmp(dlt_user.dlt_ll_ts[i].contextID, contextid,DLT_ID_SIZE)==0)
592             {
593                 registered=1;
594
595                 memset(ctid,0,(DLT_ID_SIZE+1));
596                 dlt_print_id(ctid, contextid);
597
598                 sprintf(str,"context '%s' already registered!\n",ctid);
599                 dlt_log(LOG_WARNING, str);
600
601                 break;
602             }
603         }
604     }
605
606     if (registered==0)
607     {
608         /* Allocate or expand context array */
609         if (dlt_user.dlt_ll_ts == 0)
610         {
611             dlt_user.dlt_ll_ts = (dlt_ll_ts_type*) malloc(sizeof(dlt_ll_ts_type)*DLT_USER_CONTEXT_ALLOC_SIZE);
612             if (dlt_user.dlt_ll_ts==0)
613             {
614                 DLT_SEM_FREE();
615                 return -1;
616             }
617
618             dlt_user.dlt_ll_ts_max_num_entries = DLT_USER_CONTEXT_ALLOC_SIZE;
619
620             /* Initialize new entries */
621             for (i=0;i<dlt_user.dlt_ll_ts_max_num_entries;i++)
622             {
623                 dlt_set_id(dlt_user.dlt_ll_ts[i].contextID,"");
624
625                 /* At startup, logging and tracing is locally enabled */
626                 /* the correct log level/status is set after received from daemon */
627                 dlt_user.dlt_ll_ts[i].log_level    = DLT_USER_INITIAL_LOG_LEVEL;
628                 dlt_user.dlt_ll_ts[i].trace_status = DLT_USER_INITIAL_TRACE_STATUS;
629
630                 dlt_user.dlt_ll_ts[i].context_description = 0;
631
632                 dlt_user.dlt_ll_ts[i].injection_table = 0;
633                 dlt_user.dlt_ll_ts[i].nrcallbacks     = 0;
634             }
635         }
636         else
637         {
638             if ((dlt_user.dlt_ll_ts_num_entries%DLT_USER_CONTEXT_ALLOC_SIZE)==0)
639             {
640                 /* allocate memory in steps of DLT_USER_CONTEXT_ALLOC_SIZE, e.g. 500 */
641                 dlt_ll_ts_type *old;
642                 old = dlt_user.dlt_ll_ts;
643                 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;
644                 dlt_user.dlt_ll_ts = (dlt_ll_ts_type*) malloc(sizeof(dlt_ll_ts_type)*
645                                      dlt_user.dlt_ll_ts_max_num_entries);
646                 if (dlt_user.dlt_ll_ts==0)
647                 {
648                     DLT_SEM_FREE();
649                     return -1;
650                 }
651
652                 memcpy(dlt_user.dlt_ll_ts,old,sizeof(dlt_ll_ts_type)*dlt_user.dlt_ll_ts_num_entries);
653                 free(old);
654
655                 /* Initialize new entries */
656                 for (i=dlt_user.dlt_ll_ts_num_entries;i<dlt_user.dlt_ll_ts_max_num_entries;i++)
657                 {
658                     dlt_set_id(dlt_user.dlt_ll_ts[i].contextID,"");
659
660                     /* At startup, logging and tracing is locally enabled */
661                     /* the correct log level/status is set after received from daemon */
662                     dlt_user.dlt_ll_ts[i].log_level    = DLT_USER_INITIAL_LOG_LEVEL;
663                     dlt_user.dlt_ll_ts[i].trace_status = DLT_USER_INITIAL_TRACE_STATUS;
664
665                     dlt_user.dlt_ll_ts[i].context_description = 0;
666
667                     dlt_user.dlt_ll_ts[i].injection_table = 0;
668                     dlt_user.dlt_ll_ts[i].nrcallbacks     = 0;
669                 }
670             }
671         }
672
673         /* Store locally context id and context description */
674         dlt_set_id(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].contextID, contextid);
675
676         if (dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description!=0)
677         {
678             free(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description);
679         }
680
681         dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description = 0;
682
683         if (description!=0)
684         {
685             dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description = malloc(strlen(description)+1);
686             strncpy(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description, description, strlen(description));
687
688             /* Terminate transmitted string with 0 */
689             dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description[strlen(description)]='\0';
690         }
691
692         if (loglevel!=DLT_USER_LOG_LEVEL_NOT_SET)
693         {
694             dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].log_level = loglevel;
695         }
696
697         if (tracestatus!=DLT_USER_TRACE_STATUS_NOT_SET)
698         {
699             dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].trace_status = tracestatus;
700         }
701
702         /* Prepare transfer struct */
703         //dlt_set_id(log->appID, dlt_user.appID);
704         dlt_set_id(handle->contextID, contextid);
705         handle->log_level_pos = dlt_user.dlt_ll_ts_num_entries;
706
707         log.context_description = dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description;
708
709         if (loglevel!=DLT_USER_LOG_LEVEL_NOT_SET)
710         {
711             log.log_level = loglevel;
712         }
713         else
714         {
715             log.log_level = DLT_USER_LOG_LEVEL_NOT_SET;
716         }
717
718         if (tracestatus!=DLT_USER_TRACE_STATUS_NOT_SET)
719         {
720             log.trace_status = tracestatus;
721         }
722         else
723         {
724             log.trace_status = DLT_USER_TRACE_STATUS_NOT_SET;
725         }
726
727         dlt_user.dlt_ll_ts_num_entries++;
728
729         DLT_SEM_FREE();
730
731         ret=dlt_user_log_send_register_context(&log);
732     }
733     else
734     {
735         DLT_SEM_FREE();
736
737         ret=-1;
738     }
739
740     return ret;
741 }
742
743 int dlt_unregister_app(void)
744 {
745     int ret;
746
747     if (dlt_user_initialised==0)
748     {
749         return -1;
750     }
751
752     /* Inform daemon to unregister application and all of its contexts */
753     ret = dlt_user_log_send_unregister_application();
754
755     DLT_SEM_LOCK();
756
757     /* Clear and free local stored application information */
758     dlt_set_id(dlt_user.appID, "");
759
760     if (dlt_user.application_description!=0)
761     {
762         free(dlt_user.application_description);
763     }
764
765     dlt_user.application_description = 0;
766
767     DLT_SEM_FREE();
768
769     return ret;
770 }
771
772 int dlt_unregister_context(DltContext *handle)
773 {
774     DltContextData log;
775     int ret;
776
777     if (dlt_user_initialised==0)
778     {
779         return -1;
780     }
781
782     if (dlt_user_log_init(handle, &log) == -1)
783     {
784                 return -1;
785     }
786
787     DLT_SEM_LOCK();
788
789     if (dlt_user.dlt_ll_ts)
790     {
791         /* Clear and free local stored context information */
792         dlt_set_id(dlt_user.dlt_ll_ts[handle->log_level_pos].contextID, "");
793
794         dlt_user.dlt_ll_ts[handle->log_level_pos].log_level = DLT_USER_INITIAL_LOG_LEVEL;
795         dlt_user.dlt_ll_ts[handle->log_level_pos].trace_status = DLT_USER_INITIAL_TRACE_STATUS;
796
797         if (dlt_user.dlt_ll_ts[handle->log_level_pos].context_description!=0)
798         {
799             free(dlt_user.dlt_ll_ts[handle->log_level_pos].context_description);
800         }
801
802         dlt_user.dlt_ll_ts[handle->log_level_pos].context_description = 0;
803
804         if (dlt_user.dlt_ll_ts[handle->log_level_pos].injection_table)
805         {
806             free(dlt_user.dlt_ll_ts[handle->log_level_pos].injection_table);
807             dlt_user.dlt_ll_ts[handle->log_level_pos].injection_table = 0;
808         }
809
810         dlt_user.dlt_ll_ts[handle->log_level_pos].nrcallbacks     = 0;
811     }
812
813     DLT_SEM_FREE();
814
815     /* Inform daemon to unregister context */
816     ret = dlt_user_log_send_unregister_context(&log);
817
818     return ret;
819 }
820
821 int dlt_set_application_ll_ts_limit(DltLogLevelType loglevel, DltTraceStatusType tracestatus)
822 {
823     uint32_t i;
824     int ret;
825
826     if (dlt_user_initialised==0)
827     {
828         if (dlt_init()<0)
829         {
830             return -1;
831         }
832     }
833
834     /* Removed because of DltLogLevelType and DltTraceStatusType
835
836     if ((loglevel<DLT_LOG_DEFAULT) || (loglevel>DLT_LOG_VERBOSE))
837     {
838         return -1;
839     }
840
841     if ((tracestatus<DLT_TRACE_STATUS_DEFAULT) || (tracestatus>DLT_TRACE_STATUS_ON))
842     {
843         return -1;
844     }
845
846     if (dlt_user.dlt_ll_ts==0)
847     {
848         return -1;
849     }
850
851     */
852
853     DLT_SEM_LOCK();
854
855     /* Update local structures */
856     for (i=0; i<dlt_user.dlt_ll_ts_num_entries;i++)
857     {
858         dlt_user.dlt_ll_ts[i].log_level = loglevel;
859         dlt_user.dlt_ll_ts[i].trace_status = tracestatus;
860     }
861
862     DLT_SEM_FREE();
863
864     /* Inform DLT server about update */
865     ret = dlt_send_app_ll_ts_limit(dlt_user.appID, loglevel, tracestatus);
866
867     return ret;
868 }
869
870 int dlt_get_log_state()
871 {
872         return dlt_user.log_state;
873 }
874
875 int dlt_set_log_mode(DltUserLogMode mode)
876 {
877     if (dlt_user_initialised==0)
878     {
879         if (dlt_init()<0)
880         {
881             return -1;
882         }
883     }
884
885         return dlt_user_log_send_log_mode(mode);
886 }
887
888 int dlt_forward_msg(void *msgdata,size_t size)
889 {
890     DltUserHeader userheader;
891     DltReturnValue ret;
892
893     if ((msgdata==0) || (size==0))
894     {
895         return -1;
896     }
897
898     if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG)==-1)
899     {
900         /* Type of internal user message; same value for Trace messages */
901         return -1;
902     }
903
904     if (dlt_user.dlt_is_file)
905     {
906         /* log to file */
907         ret = dlt_user_log_out2(dlt_user.dlt_log_handle, msgdata, size, 0, 0);
908         return ((ret==DLT_RETURN_OK)?0:-1);
909     }
910     else
911     {
912         /* Reattach to daemon if neccesary */
913         dlt_user_log_reattach_to_daemon();
914
915         if (dlt_user.overflow)
916         {
917             if (dlt_user_log_send_overflow()==0)
918             {
919                 dlt_user.overflow=0;
920             }
921         }
922
923         /* log to FIFO */
924         ret = dlt_user_log_out3(dlt_user.dlt_log_handle,
925                                 &(userheader), sizeof(DltUserHeader),
926                                 msgdata, size, 0, 0);
927
928         /* store message in ringbuffer, if an error has occured */
929         if (ret!=DLT_RETURN_OK)
930         {
931             DLT_SEM_LOCK();
932
933             if (dlt_buffer_push3(&(dlt_user.startup_buffer),
934                                 (unsigned char *)&(userheader), sizeof(DltUserHeader),
935                                  msgdata, size, 0, 0)==-1)
936                         {
937                                 dlt_log(LOG_ERR,"Storing message to history buffer failed! Message discarded.\n");
938                         }
939
940             DLT_SEM_FREE();
941         }
942
943         switch (ret)
944         {
945         case DLT_RETURN_PIPE_FULL:
946         {
947             /* data could not be written */
948             dlt_user.overflow = 1;
949             return -1;
950         }
951         case DLT_RETURN_PIPE_ERROR:
952         {
953             /* handle not open or pipe error */
954             close(dlt_user.dlt_log_handle);
955             dlt_user.dlt_log_handle = -1;
956
957             return -1;
958         }
959         case DLT_RETURN_ERROR:
960         {
961             /* other error condition */
962             return -1;
963         }
964         case DLT_RETURN_OK:
965         {
966                 return 0;
967         }
968                 default:
969                 {
970                         /* This case should not occur */
971                         return -1;
972                 }
973         }
974     }
975
976     return 0;
977 }
978
979 /* ********************************************************************************************* */
980
981 int dlt_user_log_write_start(DltContext *handle, DltContextData *log,DltLogLevelType loglevel)
982 {
983     return dlt_user_log_write_start_id(handle,log,loglevel,DLT_USER_DEFAULT_MSGID);
984 }
985
986 int dlt_user_log_write_start_id(DltContext *handle, DltContextData *log,DltLogLevelType loglevel, uint32_t messageid)
987 {
988     uint32_t mid;
989
990     if (dlt_user_initialised==0)
991     {
992         if (dlt_init()<0)
993         {
994             return -1;
995         }
996     }
997
998     if (dlt_user_log_init(handle, log)==-1)
999     {
1000                 return -1;
1001     }
1002
1003     if (log==0)
1004     {
1005         return -1;
1006     }
1007
1008     /* Removed because of DltLogLevelType
1009
1010     if ((loglevel<DLT_LOG_DEFAULT) || (loglevel>DLT_LOG_VERBOSE))
1011     {
1012         return -1;
1013     }
1014
1015     */
1016
1017     mid = messageid;
1018
1019     log->args_num = 0;
1020     log->log_level = loglevel;
1021     log->size = 0;
1022
1023     if (dlt_user.dlt_ll_ts==0)
1024     {
1025         return -1;
1026     }
1027
1028     DLT_SEM_LOCK();
1029
1030     if ((log->log_level<=(int)(dlt_user.dlt_ll_ts[handle->log_level_pos].log_level) ) && (log->log_level!=0))
1031     {
1032         DLT_SEM_FREE();
1033
1034         /* In non-verbose mode, insert message id */
1035         if (dlt_user.verbose_mode==0)
1036         {
1037             if ((sizeof(uint32_t))>DLT_USER_BUF_MAX_SIZE)
1038             {
1039                 return -1;
1040             }
1041             /* Write message id */
1042             memcpy(log->buffer,&(mid),sizeof(uint32_t));
1043             log->size = sizeof(uint32_t);
1044
1045             /* as the message id is part of each message in non-verbose mode,
1046                it doesn't increment the argument counter in extended header (if used) */
1047         }
1048         return 1;
1049     }
1050     else
1051     {
1052         DLT_SEM_FREE();
1053         return 0;
1054     }
1055
1056     return -1;
1057 }
1058
1059 int dlt_user_log_write_finish(DltContextData *log)
1060 {
1061     if (log==0)
1062     {
1063         return -1;
1064     }
1065
1066     return dlt_user_log_send_log(log, DLT_TYPE_LOG);
1067 }
1068
1069 int dlt_user_log_write_raw(DltContextData *log,void *data,uint16_t length)
1070 {
1071     uint16_t arg_size;
1072     uint32_t type_info;
1073
1074     if (log==0)
1075     {
1076         return -1;
1077     }
1078
1079     if ((log->size+length+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1080     {
1081         return -1;
1082     }
1083
1084     if (dlt_user.verbose_mode)
1085     {
1086         if ((log->size+length+sizeof(uint32_t)+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1087         {
1088             return -1;
1089         }
1090
1091         /* Transmit type information */
1092         type_info = DLT_TYPE_INFO_RAWD;
1093
1094         memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1095         log->size += sizeof(uint32_t);
1096
1097     }
1098
1099     /* First transmit length of raw data, then the raw data itself */
1100     arg_size = (uint16_t)length;
1101
1102     memcpy((log->buffer)+log->size,&(arg_size),sizeof(uint16_t));
1103     log->size += sizeof(uint16_t);
1104
1105     memcpy((log->buffer)+log->size,data,arg_size);
1106     log->size += arg_size;
1107
1108     log->args_num ++;
1109
1110     return 0;
1111 }
1112
1113 int dlt_user_log_write_float32(DltContextData *log, float32_t data)
1114 {
1115     uint32_t type_info;
1116
1117     if (log==0)
1118     {
1119         return -1;
1120     }
1121
1122     if (sizeof(float32_t)!=4)
1123     {
1124         return -1;
1125     }
1126
1127     if ((log->size+sizeof(float32_t))>DLT_USER_BUF_MAX_SIZE)
1128     {
1129         return -1;
1130     }
1131
1132     if (dlt_user.verbose_mode)
1133     {
1134         if ((log->size+sizeof(uint32_t)+sizeof(float32_t))>DLT_USER_BUF_MAX_SIZE)
1135         {
1136             return -1;
1137         }
1138
1139         type_info = DLT_TYPE_INFO_FLOA | DLT_TYLE_32BIT;
1140
1141         memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1142         log->size += sizeof(uint32_t);
1143     }
1144
1145     memcpy((log->buffer)+log->size,&data, sizeof(float32_t));
1146     log->size += sizeof(float32_t);
1147
1148     log->args_num ++;
1149
1150     return 0;
1151 }
1152
1153 int dlt_user_log_write_float64(DltContextData *log, float64_t data)
1154 {
1155     uint32_t type_info;
1156
1157     if (log==0)
1158     {
1159         return -1;
1160     }
1161
1162     if (sizeof(float64_t)!=8)
1163     {
1164         return -1;
1165     }
1166
1167     if ((log->size+sizeof(float64_t))>DLT_USER_BUF_MAX_SIZE)
1168     {
1169         return -1;
1170     }
1171
1172     if (dlt_user.verbose_mode)
1173     {
1174         if ((log->size+sizeof(uint32_t)+sizeof(float64_t))>DLT_USER_BUF_MAX_SIZE)
1175         {
1176             return -1;
1177         }
1178
1179         type_info = DLT_TYPE_INFO_FLOA | DLT_TYLE_64BIT;
1180
1181         memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1182         log->size += sizeof(uint32_t);
1183     }
1184
1185     memcpy((log->buffer)+log->size,&data, sizeof(float64_t));
1186     log->size += sizeof(float64_t);
1187
1188     log->args_num ++;
1189
1190     return 0;
1191 }
1192
1193 int dlt_user_log_write_uint( DltContextData *log, unsigned int data)
1194 {
1195     if (log==0)
1196     {
1197         return -1;
1198     }
1199
1200     switch (sizeof(unsigned int))
1201     {
1202     case 1:
1203     {
1204         return dlt_user_log_write_uint8(log, (uint8_t)data);
1205         break;
1206     }
1207     case 2:
1208     {
1209         return dlt_user_log_write_uint16(log, (uint16_t)data);
1210         break;
1211     }
1212     case 4:
1213     {
1214         return dlt_user_log_write_uint32(log, (uint32_t)data);
1215         break;
1216     }
1217     case 8:
1218     {
1219         return dlt_user_log_write_uint64(log, (uint64_t)data);
1220                 break;
1221     }
1222     default:
1223     {
1224         return -1;
1225         break;
1226     }
1227     }
1228
1229     return 0;
1230 }
1231
1232 int dlt_user_log_write_uint8(DltContextData *log, uint8_t data)
1233 {
1234     uint32_t type_info;
1235
1236     if (log==0)
1237     {
1238         return -1;
1239     }
1240
1241     if ((log->size+sizeof(uint8_t))>DLT_USER_BUF_MAX_SIZE)
1242     {
1243         return -1;
1244     }
1245
1246     if (dlt_user.verbose_mode)
1247     {
1248         if ((log->size+sizeof(uint32_t)+sizeof(uint8_t))>DLT_USER_BUF_MAX_SIZE)
1249         {
1250             return -1;
1251         }
1252
1253         type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_8BIT;
1254
1255         memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1256         log->size += sizeof(uint32_t);
1257     }
1258
1259     memcpy((log->buffer)+log->size,&data,sizeof(uint8_t));
1260     log->size += sizeof(uint8_t);
1261
1262     log->args_num ++;
1263
1264     return 0;
1265 }
1266
1267 int dlt_user_log_write_uint16(DltContextData *log, uint16_t data)
1268 {
1269     uint32_t type_info;
1270
1271     if (log==0)
1272     {
1273         return -1;
1274     }
1275
1276     if ((log->size+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1277     {
1278         return -1;
1279     }
1280
1281     if (dlt_user.verbose_mode)
1282     {
1283         if ((log->size+sizeof(uint32_t)+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1284         {
1285             return -1;
1286         }
1287
1288         type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_16BIT;
1289
1290         memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1291         log->size += sizeof(uint32_t);
1292     }
1293
1294     memcpy((log->buffer)+log->size,&data,sizeof(uint16_t));
1295     log->size += sizeof(uint16_t);
1296
1297     log->args_num ++;
1298
1299     return 0;
1300 }
1301
1302 int dlt_user_log_write_uint32(DltContextData *log, uint32_t data)
1303 {
1304     uint32_t type_info;
1305
1306     if (log==0)
1307     {
1308         return -1;
1309     }
1310
1311     if ((log->size+sizeof(uint32_t))>DLT_USER_BUF_MAX_SIZE)
1312     {
1313         return -1;
1314     }
1315
1316     if (dlt_user.verbose_mode)
1317     {
1318         if ((log->size+sizeof(uint32_t)+sizeof(uint32_t))>DLT_USER_BUF_MAX_SIZE)
1319         {
1320             return -1;
1321         }
1322
1323         type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_32BIT;
1324
1325         memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1326         log->size += sizeof(uint32_t);
1327     }
1328
1329     memcpy((log->buffer)+log->size,&data, sizeof(uint32_t));
1330     log->size += sizeof(uint32_t);
1331
1332     log->args_num ++;
1333
1334     return 0;
1335 }
1336
1337 int dlt_user_log_write_uint64(DltContextData *log, uint64_t data)
1338 {
1339     uint32_t type_info;
1340
1341     if (log==0)
1342     {
1343         return -1;
1344     }
1345
1346     if ((log->size+sizeof(uint64_t))>DLT_USER_BUF_MAX_SIZE)
1347     {
1348         return -1;
1349     }
1350
1351     if (dlt_user.verbose_mode)
1352     {
1353         if ((log->size+sizeof(uint32_t)+sizeof(uint64_t))>DLT_USER_BUF_MAX_SIZE)
1354         {
1355             return -1;
1356         }
1357
1358         type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_64BIT;
1359
1360         memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1361         log->size +=sizeof(uint32_t);
1362     }
1363
1364     memcpy((log->buffer)+log->size,&data,sizeof(uint64_t));
1365     log->size += sizeof(uint64_t);
1366
1367     log->args_num ++;
1368
1369     return 0;
1370 }
1371
1372 int dlt_user_log_write_int(DltContextData *log, int data)
1373 {
1374     if (log==0)
1375     {
1376         return -1;
1377     }
1378
1379     switch (sizeof(int))
1380     {
1381     case 1:
1382     {
1383         return dlt_user_log_write_int8(log, (int8_t)data);
1384         break;
1385     }
1386     case 2:
1387     {
1388         return dlt_user_log_write_int16(log, (int16_t)data);
1389         break;
1390     }
1391     case 4:
1392     {
1393         return dlt_user_log_write_int32(log, (int32_t)data);
1394         break;
1395     }
1396     case 8:
1397     {
1398         return dlt_user_log_write_int64(log, (int64_t)data);
1399                 break;
1400     }
1401     default:
1402     {
1403         return -1;
1404         break;
1405     }
1406     }
1407
1408     return 0;
1409 }
1410
1411 int dlt_user_log_write_int8(DltContextData *log, int8_t data)
1412 {
1413     uint32_t type_info;
1414
1415     if (log==0)
1416     {
1417         return -1;
1418     }
1419
1420     if ((log->size+sizeof(int8_t))>DLT_USER_BUF_MAX_SIZE)
1421     {
1422         return -1;
1423     }
1424
1425     if (dlt_user.verbose_mode)
1426     {
1427         if ((log->size+sizeof(uint32_t)+sizeof(int8_t))>DLT_USER_BUF_MAX_SIZE)
1428         {
1429             return -1;
1430         }
1431
1432         type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_8BIT;
1433
1434         memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1435         log->size += sizeof(uint32_t);
1436     }
1437
1438     memcpy((log->buffer)+log->size,&data,sizeof(int8_t));
1439     log->size += sizeof(int8_t);
1440
1441     log->args_num ++;
1442
1443     return 0;
1444 }
1445
1446 int dlt_user_log_write_int16(DltContextData *log, int16_t data)
1447 {
1448     uint32_t type_info;
1449
1450     if (log==0)
1451     {
1452         return -1;
1453     }
1454
1455     if ((log->size+sizeof(int16_t))>DLT_USER_BUF_MAX_SIZE)
1456     {
1457         return -1;
1458     }
1459
1460     if (dlt_user.verbose_mode)
1461     {
1462         if ((log->size+sizeof(uint32_t)+sizeof(int16_t))>DLT_USER_BUF_MAX_SIZE)
1463                 {
1464             return -1;
1465                 }
1466
1467         type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_16BIT;
1468
1469         memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1470         log->size += sizeof(uint32_t);
1471     }
1472
1473     memcpy((log->buffer)+log->size,&data,sizeof(int16_t));
1474     log->size += sizeof(int16_t);
1475
1476     log->args_num ++;
1477
1478     return 0;
1479 }
1480
1481 int dlt_user_log_write_int32(DltContextData *log, int32_t data)
1482 {
1483     uint32_t type_info;
1484
1485     if (log==0)
1486     {
1487         return -1;
1488     }
1489
1490     if ((log->size+sizeof(int32_t))>DLT_USER_BUF_MAX_SIZE)
1491     {
1492         return -1;
1493     }
1494
1495     if (dlt_user.verbose_mode)
1496     {
1497         if ((log->size+sizeof(uint32_t)+sizeof(int32_t))>DLT_USER_BUF_MAX_SIZE)
1498         {
1499             return -1;
1500         }
1501
1502         type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_32BIT;
1503
1504         memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1505         log->size += sizeof(uint32_t);
1506     }
1507
1508     memcpy((log->buffer)+log->size,&data, sizeof(int32_t));
1509     log->size += sizeof(int32_t);
1510
1511     log->args_num ++;
1512
1513     return 0;
1514 }
1515
1516 int dlt_user_log_write_int64(DltContextData *log, int64_t data)
1517 {
1518     uint32_t type_info;
1519
1520     if (log==0)
1521     {
1522         return -1;
1523     }
1524
1525     if ((log->size+sizeof(int64_t))>DLT_USER_BUF_MAX_SIZE)
1526     {
1527         return -1;
1528     }
1529
1530     if (dlt_user.verbose_mode)
1531     {
1532         if ((log->size+sizeof(uint32_t)+sizeof(int64_t))>DLT_USER_BUF_MAX_SIZE)
1533         {
1534             return -1;
1535         }
1536
1537         type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_64BIT;
1538
1539         memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1540         log->size += sizeof(uint32_t);
1541     }
1542
1543     memcpy((log->buffer)+log->size,&data,sizeof(int64_t));
1544     log->size += sizeof(int64_t);
1545
1546     log->args_num ++;
1547
1548     return 0;
1549 }
1550
1551 int dlt_user_log_write_bool(DltContextData *log, uint8_t data)
1552 {
1553     uint32_t type_info;
1554
1555     if (log==0)
1556     {
1557         return -1;
1558     }
1559
1560     if ((log->size+sizeof(uint8_t))>DLT_USER_BUF_MAX_SIZE)
1561     {
1562         return -1;
1563     }
1564
1565     if (dlt_user.verbose_mode)
1566     {
1567         if ((log->size+sizeof(uint32_t)+sizeof(uint8_t))>DLT_USER_BUF_MAX_SIZE)
1568         {
1569             return -1;
1570         }
1571
1572         type_info = DLT_TYPE_INFO_BOOL;
1573
1574         memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1575         log->size += sizeof(uint32_t);
1576     }
1577
1578     memcpy((log->buffer)+log->size,&data,sizeof(uint8_t));
1579     log->size += sizeof(uint8_t);
1580
1581     log->args_num ++;
1582
1583     return 0;
1584 }
1585
1586 int dlt_user_log_write_string(DltContextData *log, const char *text)
1587 {
1588     uint16_t arg_size;
1589     uint32_t type_info;
1590
1591     if ((log==0) || (text==0))
1592     {
1593         return -1;
1594     }
1595
1596     if ((log->size+(strlen(text)+1)+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1597     {
1598         return -1;
1599     }
1600
1601     if (dlt_user.verbose_mode)
1602     {
1603         if ((log->size+(strlen(text)+1)+sizeof(uint32_t)+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1604         {
1605             return -1;
1606         }
1607
1608         type_info = DLT_TYPE_INFO_STRG;
1609
1610         memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1611         log->size += sizeof(uint32_t);
1612     }
1613
1614     arg_size = strlen(text) + 1;
1615
1616     memcpy((log->buffer)+log->size,&(arg_size),sizeof(uint16_t));
1617     log->size += sizeof(uint16_t);
1618
1619     memcpy((log->buffer)+log->size,text,arg_size);
1620     log->size += arg_size;
1621
1622     log->args_num ++;
1623
1624     return 0;
1625 }
1626
1627 int dlt_register_injection_callback(DltContext *handle, uint32_t service_id,
1628                                     int (*dlt_injection_callback)(uint32_t service_id, void *data, uint32_t length))
1629 {
1630     DltContextData log;
1631     uint32_t i,j,k;
1632     int found = 0;
1633
1634         DltUserInjectionCallback *old;
1635
1636     if (handle==0)
1637     {
1638         return -1;
1639     }
1640
1641     if (dlt_user_log_init(handle, &log)==-1)
1642     {
1643                 return -1;
1644     }
1645
1646     if (service_id<DLT_USER_INJECTION_MIN)
1647     {
1648         return -1;
1649     }
1650     /* This function doesn't make sense storing to local file is choosen;
1651        so terminate this function */
1652     if (dlt_user.dlt_is_file)
1653     {
1654         return 0;
1655     }
1656
1657     DLT_SEM_LOCK();
1658
1659     if (dlt_user.dlt_ll_ts==0)
1660     {
1661         DLT_SEM_FREE();
1662         return 0;
1663     }
1664
1665     /* Insert callback in corresponding table */
1666     i=handle->log_level_pos;
1667
1668     /* Insert each service_id only once */
1669     for (k=0;k<dlt_user.dlt_ll_ts[i].nrcallbacks;k++)
1670     {
1671         if ((dlt_user.dlt_ll_ts[i].injection_table) &&
1672                 (dlt_user.dlt_ll_ts[i].injection_table[k].service_id == service_id))
1673         {
1674             found = 1;
1675             break;
1676         }
1677     }
1678
1679     if (found)
1680     {
1681         j = k;
1682     }
1683     else
1684     {
1685         j=dlt_user.dlt_ll_ts[i].nrcallbacks;
1686
1687         /* Allocate or expand injection table */
1688         if (dlt_user.dlt_ll_ts[i].injection_table == 0)
1689         {
1690             dlt_user.dlt_ll_ts[i].injection_table = (DltUserInjectionCallback*) malloc(sizeof(DltUserInjectionCallback));
1691         }
1692         else
1693         {
1694             old = dlt_user.dlt_ll_ts[i].injection_table;
1695             dlt_user.dlt_ll_ts[i].injection_table = (DltUserInjectionCallback*) malloc(sizeof(DltUserInjectionCallback)*(j+1));
1696             memcpy(dlt_user.dlt_ll_ts[i].injection_table,old,sizeof(DltUserInjectionCallback)*j);
1697             free(old);
1698         }
1699
1700         dlt_user.dlt_ll_ts[i].nrcallbacks++;
1701     }
1702
1703     /* Store service_id and corresponding function pointer for callback function */
1704     dlt_user.dlt_ll_ts[i].injection_table[j].service_id = service_id;
1705     dlt_user.dlt_ll_ts[i].injection_table[j].injection_callback = dlt_injection_callback;
1706
1707     DLT_SEM_FREE();
1708     return 0;
1709 }
1710
1711 int dlt_user_trace_network(DltContext *handle, DltNetworkTraceType nw_trace_type, uint16_t header_len, void *header, uint16_t payload_len, void *payload)
1712 {
1713     DltContextData log;
1714
1715     if (dlt_user_initialised==0)
1716     {
1717         if (dlt_init()<0)
1718         {
1719             return -1;
1720         }
1721     }
1722
1723     if (dlt_user_log_init(handle, &log)==-1)
1724     {
1725                 return -1;
1726     }
1727
1728     if (handle==0)
1729     {
1730         return -1;
1731     }
1732
1733     /* Commented out because of DltNetworkTraceType:
1734
1735     if ((nw_trace_type<=0) || (nw_trace_type>0x15))
1736     {
1737         return -1;
1738     }
1739
1740     */
1741
1742     DLT_SEM_LOCK();
1743
1744     if (dlt_user.dlt_ll_ts==0)
1745     {
1746         DLT_SEM_FREE();
1747         return -1;
1748     }
1749
1750     if (dlt_user.dlt_ll_ts[handle->log_level_pos].trace_status==DLT_TRACE_STATUS_ON)
1751     {
1752         DLT_SEM_FREE();
1753
1754         log.args_num = 0;
1755         log.trace_status = nw_trace_type;
1756         log.size = 0;
1757
1758         if (header==0)
1759         {
1760             header_len=0;
1761         }
1762
1763         /* Write header and its length */
1764         if (dlt_user_log_write_raw(&log, header, header_len)==-1)
1765         {
1766                 return -1;
1767         }
1768
1769         if (payload==0)
1770         {
1771             payload_len=0;
1772         }
1773
1774         /* Write payload and its length */
1775         if (dlt_user_log_write_raw(&log, payload, payload_len)==-1)
1776         {
1777                         return -1;
1778         }
1779
1780         /* Send log */
1781         return dlt_user_log_send_log(&log, DLT_TYPE_NW_TRACE);
1782     }
1783     else
1784     {
1785         DLT_SEM_FREE();
1786     }
1787
1788     return 0;
1789 }
1790
1791 int dlt_log_string(DltContext *handle,DltLogLevelType loglevel, const char *text)
1792 {
1793     DltContextData log;
1794
1795     if (dlt_user.verbose_mode==0)
1796     {
1797         return -1;
1798     }
1799
1800     if ((handle==0) || (text==0))
1801     {
1802         return -1;
1803     }
1804
1805     if (dlt_user_log_write_start(handle,&log,loglevel))
1806     {
1807         if (dlt_user_log_write_string(&log,text)==-1)
1808         {
1809                         return -1;
1810         }
1811         if (dlt_user_log_write_finish(&log)==-1)
1812         {
1813                 return -1;
1814         }
1815     }
1816
1817     return 0;
1818 }
1819
1820 int dlt_log_string_int(DltContext *handle,DltLogLevelType loglevel, const char *text, int data)
1821 {
1822     DltContextData log;
1823
1824     if (dlt_user.verbose_mode==0)
1825     {
1826         return -1;
1827     }
1828
1829     if ((handle==0) || (text==0))
1830     {
1831         return -1;
1832     }
1833
1834     if (dlt_user_log_write_start(handle,&log,loglevel))
1835     {
1836         if (dlt_user_log_write_string(&log,text)==-1)
1837         {
1838                         return -1;
1839         }
1840         if (dlt_user_log_write_int(&log,data)==-1)
1841         {
1842                         return -1;
1843         }
1844         if (dlt_user_log_write_finish(&log)==-1)
1845         {
1846                         return -1;
1847         }
1848     }
1849
1850     return 0;
1851 }
1852
1853 int dlt_log_string_uint(DltContext *handle,DltLogLevelType loglevel, const char *text, unsigned int data)
1854 {
1855     DltContextData log;
1856
1857     if (dlt_user.verbose_mode==0)
1858     {
1859         return -1;
1860     }
1861
1862     if ((handle==0) || (text==0))
1863     {
1864         return -1;
1865     }
1866
1867     if (dlt_user_log_write_start(handle,&log,loglevel))
1868     {
1869         if (dlt_user_log_write_string(&log,text)==-1)
1870         {
1871                         return -1;
1872         }
1873         if (dlt_user_log_write_uint(&log,data)==-1)
1874         {
1875                         return -1;
1876         }
1877         if (dlt_user_log_write_finish(&log)==-1)
1878         {
1879                         return -1;
1880         }
1881     }
1882
1883     return 0;
1884 }
1885
1886 int dlt_log_int(DltContext *handle,DltLogLevelType loglevel, int data)
1887 {
1888     DltContextData log;
1889
1890     if (dlt_user.verbose_mode==0)
1891     {
1892         return -1;
1893     }
1894
1895     if (handle==0)
1896     {
1897         return -1;
1898     }
1899
1900     if (dlt_user_log_write_start(handle,&log,loglevel))
1901     {
1902         if (dlt_user_log_write_int(&log,data)==-1)
1903         {
1904                         return -1;
1905         }
1906         if (dlt_user_log_write_finish(&log)==-1)
1907         {
1908                         return -1;
1909         }
1910     }
1911
1912     return 0;
1913 }
1914
1915 int dlt_log_uint(DltContext *handle,DltLogLevelType loglevel, unsigned int data)
1916 {
1917     DltContextData log;
1918
1919     if (dlt_user.verbose_mode==0)
1920     {
1921         return -1;
1922     }
1923
1924     if (handle==0)
1925     {
1926         return -1;
1927     }
1928
1929     if (dlt_user_log_write_start(handle,&log,loglevel))
1930     {
1931         if (dlt_user_log_write_uint(&log,data)==-1)
1932         {
1933                         return -1;
1934         }
1935         if (dlt_user_log_write_finish(&log)==-1)
1936         {
1937                         return -1;
1938         }
1939     }
1940
1941     return 0;
1942 }
1943
1944 int dlt_log_raw(DltContext *handle,DltLogLevelType loglevel, void *data,uint16_t length)
1945 {
1946     DltContextData log;
1947
1948     if (dlt_user.verbose_mode==0)
1949     {
1950         return -1;
1951     }
1952
1953     if (handle==0)
1954     {
1955         return -1;
1956     }
1957
1958     if (dlt_user_log_write_start(handle,&log,loglevel))
1959     {
1960         if (dlt_user_log_write_raw(&log,data,length)==-1)
1961         {
1962                         return -1;
1963         }
1964         if (dlt_user_log_write_finish(&log)==-1)
1965         {
1966                         return -1;
1967         }
1968     }
1969
1970     return 0;
1971 }
1972
1973 int dlt_verbose_mode(void)
1974 {
1975     if (dlt_user_initialised==0)
1976     {
1977         if (dlt_init()<0)
1978         {
1979             return -1;
1980         }
1981     }
1982
1983     /* Switch to verbose mode */
1984     dlt_user.verbose_mode = 1;
1985
1986     return 0;
1987 }
1988
1989 int dlt_nonverbose_mode(void)
1990 {
1991     if (dlt_user_initialised==0)
1992     {
1993         if (dlt_init()<0)
1994         {
1995             return -1;
1996         }
1997     }
1998
1999     /* Switch to non-verbose mode */
2000     dlt_user.verbose_mode = 0;
2001
2002     return 0;
2003 }
2004
2005 int dlt_enable_local_print(void)
2006 {
2007     if (dlt_user_initialised==0)
2008     {
2009         if (dlt_init()<0)
2010         {
2011             return -1;
2012         }
2013     }
2014
2015     dlt_user.enable_local_print = 1;
2016
2017     return 0;
2018 }
2019
2020 int dlt_disable_local_print(void)
2021 {
2022     if (dlt_user_initialised==0)
2023     {
2024         if (dlt_init()<0)
2025         {
2026             return -1;
2027         }
2028     }
2029
2030     dlt_user.enable_local_print = 0;
2031
2032     return 0;
2033 }
2034
2035 void dlt_user_receiverthread_function(void *ptr)
2036 {
2037     while (1)
2038     {
2039         /* Check for new messages from DLT daemon */
2040         if (dlt_user_log_check_user_message()==-1)
2041         {
2042                         /* Critical error */
2043                         dlt_log(LOG_CRIT,"Receiver thread encountered error condition\n");
2044         }
2045
2046         usleep(DLT_USER_RECEIVE_DELAY); /* delay */
2047     }
2048 }
2049
2050 /* Private functions of user library */
2051
2052 int dlt_user_log_init(DltContext *handle, DltContextData *log)
2053 {
2054     if (dlt_user_initialised==0)
2055     {
2056         if (dlt_init()<0)
2057         {
2058             return -1;
2059         }
2060     }
2061
2062     log->handle = handle;
2063
2064     return 0;
2065 }
2066
2067 int dlt_user_log_send_log(DltContextData *log, int mtype)
2068 {
2069     DltMessage msg;
2070     DltUserHeader userheader;
2071     int32_t len;
2072
2073     DltReturnValue ret = 0;
2074
2075     if (log==0)
2076     {
2077         return -1;
2078     }
2079
2080     if (log->handle==0)
2081     {
2082         return -1;
2083     }
2084
2085     if (dlt_user.appID[0]=='\0')
2086     {
2087         return -1;
2088     }
2089
2090     if (log->handle->contextID[0]=='\0')
2091     {
2092         return -1;
2093     }
2094
2095     if ((mtype<DLT_TYPE_LOG) || (mtype>DLT_TYPE_CONTROL))
2096     {
2097         return -1;
2098     }
2099
2100     /* also for Trace messages */
2101 #ifdef DLT_SHM_ENABLE
2102     if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG_SHM)==-1)
2103 #else
2104     if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG)==-1)
2105 #endif
2106     {
2107                 return -1;
2108     }
2109
2110     if (dlt_message_init(&msg,0)==-1)
2111     {
2112         return -1;
2113     }
2114
2115     msg.storageheader = (DltStorageHeader*)msg.headerbuffer;
2116
2117     if (dlt_set_storageheader(msg.storageheader,dlt_user.ecuID)==-1)
2118     {
2119                 return -1;
2120     }
2121
2122     msg.standardheader = (DltStandardHeader*)(msg.headerbuffer + sizeof(DltStorageHeader));
2123     msg.standardheader->htyp = DLT_HTYP_WEID | DLT_HTYP_WTMS | DLT_HTYP_PROTOCOL_VERSION1 ;
2124
2125     if (dlt_user.verbose_mode)
2126     {
2127         /* In verbose mode, send extended header */
2128         msg.standardheader->htyp = (msg.standardheader->htyp | DLT_HTYP_UEH );
2129     }
2130     else
2131     {
2132         /* In non-verbose, send extended header if desired */
2133 #if (DLT_USER_USE_EXTENDED_HEADER_FOR_NONVERBOSE==1)
2134         msg.standardheader->htyp = (msg.standardheader->htyp | DLT_HTYP_UEH );
2135 #endif
2136     }
2137
2138 #if (BYTE_ORDER==BIG_ENDIAN)
2139     msg.standardheader->htyp = (msg.standardheader->htyp | DLT_HTYP_MSBF);
2140 #endif
2141
2142     msg.standardheader->mcnt = log->handle->mcnt++;
2143
2144     /* Set header extra parameters */
2145     dlt_set_id(msg.headerextra.ecu,dlt_user.ecuID);
2146     //msg.headerextra.seid = 0;
2147     msg.headerextra.tmsp = dlt_uptime();
2148
2149     if (dlt_message_set_extraparameters(&msg,0)==-1)
2150     {
2151         return -1;
2152     }
2153
2154     /* Fill out extended header, if extended header should be provided */
2155     if (DLT_IS_HTYP_UEH(msg.standardheader->htyp))
2156     {
2157         /* with extended header */
2158         msg.extendedheader = (DltExtendedHeader*)(msg.headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp)  );
2159
2160         switch (mtype)
2161         {
2162         case DLT_TYPE_LOG:
2163         {
2164             msg.extendedheader->msin = (DLT_TYPE_LOG << DLT_MSIN_MSTP_SHIFT) | ((log->log_level << DLT_MSIN_MTIN_SHIFT) & DLT_MSIN_MTIN) ; /* messsage info */
2165             break;
2166         }
2167         case DLT_TYPE_NW_TRACE:
2168         {
2169             msg.extendedheader->msin = (DLT_TYPE_NW_TRACE << DLT_MSIN_MSTP_SHIFT) | ((log->trace_status << DLT_MSIN_MTIN_SHIFT) & DLT_MSIN_MTIN) ; /* messsage info */
2170             break;
2171         }
2172         default:
2173         {
2174                     /* This case should not occur */
2175             return -1;
2176             break;
2177         }
2178         }
2179
2180         /* If in verbose mode, set flag in header for verbose mode */
2181         if (dlt_user.verbose_mode)
2182         {
2183             msg.extendedheader->msin |= DLT_MSIN_VERB;
2184         }
2185
2186         msg.extendedheader->noar = log->args_num;              /* number of arguments */
2187         dlt_set_id(msg.extendedheader->apid,dlt_user.appID);       /* application id */
2188         dlt_set_id(msg.extendedheader->ctid,log->handle->contextID);   /* context id */
2189
2190         msg.headersize = sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + sizeof(DltExtendedHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp);
2191     }
2192     else
2193     {
2194         /* without extended header */
2195         msg.headersize = sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp);
2196     }
2197
2198     len=msg.headersize - sizeof(DltStorageHeader) +log->size;
2199     if (len>UINT16_MAX)
2200     {
2201         dlt_log(LOG_CRIT,"Huge message discarded!\n");
2202         return -1;
2203     }
2204
2205     msg.standardheader->len = DLT_HTOBE_16(len);
2206
2207     /* print to std out, if enabled */
2208     if ((dlt_user.local_print_mode != DLT_PM_FORCE_OFF) &&
2209             (dlt_user.local_print_mode != DLT_PM_AUTOMATIC))
2210     {
2211         if ((dlt_user.enable_local_print) || (dlt_user.local_print_mode == DLT_PM_FORCE_ON))
2212         {
2213             if (dlt_user_print_msg(&msg, log)==-1)
2214             {
2215                                 return -1;
2216             }
2217         }
2218     }
2219
2220     if (dlt_user.dlt_is_file)
2221     {
2222         /* log to file */
2223         ret=dlt_user_log_out2(dlt_user.dlt_log_handle, msg.headerbuffer, msg.headersize, log->buffer, log->size);
2224         return ((ret==DLT_RETURN_OK)?0:-1);
2225     }
2226     else
2227     {
2228         /* Reattach to daemon if neccesary */
2229         dlt_user_log_reattach_to_daemon();
2230
2231         if (dlt_user.overflow)
2232         {
2233             if (dlt_user_log_send_overflow()==0)
2234             {
2235                 dlt_user.overflow=0;
2236             }
2237         }
2238
2239                 /* try to resent old data first */
2240                 ret = 0;
2241                 if(dlt_user.dlt_log_handle!=-1)
2242                         ret = dlt_user_log_resend_buffer();
2243                 if(ret==0) 
2244                 {
2245                         /* resend ok or nothing to resent */
2246 #ifdef DLT_SHM_ENABLE
2247                         if(dlt_user.dlt_log_handle!=-1)
2248                                 dlt_shm_push(&dlt_user.dlt_shm,msg.headerbuffer+sizeof(DltStorageHeader), msg.headersize-sizeof(DltStorageHeader),
2249                                                                                         log->buffer, log->size,0,0);                   
2250
2251                         /* log to FIFO */
2252                         ret = dlt_user_log_out3(dlt_user.dlt_log_handle,
2253                                                                         &(userheader), sizeof(DltUserHeader),
2254                                                                         0, 0,
2255                                                                         0, 0);
2256 #else
2257                         /* log to FIFO */
2258 #ifdef DLT_TEST_ENABLE
2259                         if(dlt_user.corrupt_user_header) {
2260                                 userheader.pattern[0]=0xff;
2261                                 userheader.pattern[1]=0xff;
2262                                 userheader.pattern[2]=0xff;
2263                                 userheader.pattern[3]=0xff;
2264                         }
2265                         if(dlt_user.corrupt_message_size) {
2266                                 msg.standardheader->len = DLT_HTOBE_16(dlt_user.corrupt_message_size_size);
2267                         }
2268 #endif
2269                         ret = dlt_user_log_out3(dlt_user.dlt_log_handle,
2270                                                                         &(userheader), sizeof(DltUserHeader),
2271                                                                         msg.headerbuffer+sizeof(DltStorageHeader), msg.headersize-sizeof(DltStorageHeader),
2272                                                                         log->buffer, log->size);                
2273 #endif                  
2274                 }
2275                 
2276         /* store message in ringbuffer, if an error has occured */
2277         if (ret!=DLT_RETURN_OK)
2278         {
2279             DLT_SEM_LOCK();
2280
2281             if (dlt_buffer_push3(&(dlt_user.startup_buffer),
2282                                 (unsigned char *)&(userheader), sizeof(DltUserHeader),
2283                                 msg.headerbuffer+sizeof(DltStorageHeader), msg.headersize-sizeof(DltStorageHeader),
2284                                 log->buffer, log->size)==-1)
2285                         {
2286                                 dlt_log(LOG_ERR,"Storing message to history buffer failed! Message discarded.\n");
2287                         }
2288
2289             DLT_SEM_FREE();
2290         }
2291
2292         switch (ret)
2293         {
2294         case DLT_RETURN_PIPE_FULL:
2295         {
2296             /* data could not be written */
2297             dlt_user.overflow = 1;
2298             return -1;
2299         }
2300         case DLT_RETURN_PIPE_ERROR:
2301         {
2302             /* handle not open or pipe error */
2303             close(dlt_user.dlt_log_handle);
2304             dlt_user.dlt_log_handle = -1;
2305
2306 #ifdef DLT_SHM_ENABLE
2307                         /* free shared memory */
2308                         dlt_shm_free_client(&dlt_user.dlt_shm);
2309 #endif
2310
2311             if (dlt_user.local_print_mode == DLT_PM_AUTOMATIC)
2312             {
2313                 dlt_user_print_msg(&msg, log);
2314             }
2315
2316             return -1;
2317         }
2318         case DLT_RETURN_ERROR:
2319         {
2320             /* other error condition */
2321             return -1;
2322         }
2323                 case DLT_RETURN_OK:
2324         {
2325                 return 0;
2326         }
2327                 default:
2328                 {
2329                         /* This case should never occur. */
2330                         return -1;
2331                 }
2332         }
2333     }
2334
2335     return 0;
2336 }
2337
2338 int dlt_user_log_send_register_application(void)
2339 {
2340     DltUserHeader userheader;
2341     DltUserControlMsgRegisterApplication usercontext;
2342
2343     DltReturnValue ret;
2344
2345     if (dlt_user.appID[0]=='\0')
2346     {
2347         return -1;
2348     }
2349
2350     /* set userheader */
2351     if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_REGISTER_APPLICATION)==-1)
2352     {
2353                 return -1;
2354     }
2355
2356     /* set usercontext */
2357     dlt_set_id(usercontext.apid,dlt_user.appID);       /* application id */
2358     usercontext.pid = getpid();
2359
2360     if (dlt_user.application_description!=0)
2361     {
2362         usercontext.description_length = strlen(dlt_user.application_description);
2363     }
2364     else
2365     {
2366         usercontext.description_length = 0;
2367     }
2368
2369     if (dlt_user.dlt_is_file)
2370     {
2371         return 0;
2372     }
2373
2374     /* log to FIFO */
2375     ret=dlt_user_log_out3(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgRegisterApplication),dlt_user.application_description,usercontext.description_length);
2376         return ((ret==DLT_RETURN_OK)?0:-1);
2377 }
2378
2379 int dlt_user_log_send_unregister_application(void)
2380 {
2381     DltUserHeader userheader;
2382     DltUserControlMsgUnregisterApplication usercontext;
2383
2384     DltReturnValue ret;
2385
2386     if (dlt_user.appID[0]=='\0')
2387     {
2388         return -1;
2389     }
2390
2391     /* set userheader */
2392     if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_UNREGISTER_APPLICATION)==-1)
2393     {
2394         return -1;
2395     }
2396
2397     /* set usercontext */
2398     dlt_set_id(usercontext.apid,dlt_user.appID);       /* application id */
2399     usercontext.pid = getpid();
2400
2401     if (dlt_user.dlt_is_file)
2402     {
2403         return 0;
2404     }
2405
2406     /* log to FIFO */
2407     ret=dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgUnregisterApplication));
2408     return ((ret==DLT_RETURN_OK)?0:-1);
2409 }
2410
2411 int dlt_user_log_send_register_context(DltContextData *log)
2412 {
2413     DltUserHeader userheader;
2414     DltUserControlMsgRegisterContext usercontext;
2415     DltReturnValue ret;
2416
2417     if (log==0)
2418     {
2419                 return -1;
2420     }
2421
2422     if (log->handle==0)
2423     {
2424         return -1;
2425     }
2426
2427     if ((dlt_user.appID[0]=='\0') || (log->handle->contextID=='\0'))
2428     {
2429         return -1;
2430     }
2431
2432     /* set userheader */
2433     if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_REGISTER_CONTEXT)==-1)
2434     {
2435                 return -1;
2436     }
2437
2438     /* set usercontext */
2439     dlt_set_id(usercontext.apid,dlt_user.appID);       /* application id */
2440     dlt_set_id(usercontext.ctid,log->handle->contextID);       /* context id */
2441     usercontext.log_level_pos = log->handle->log_level_pos;
2442     usercontext.pid = getpid();
2443
2444     usercontext.log_level = (int8_t)log->log_level;
2445     usercontext.trace_status = (int8_t)log->trace_status;
2446
2447     if (log->context_description!=0)
2448     {
2449         usercontext.description_length = strlen(log->context_description);
2450     }
2451     else
2452     {
2453                 usercontext.description_length = 0;
2454     }
2455
2456     if (dlt_user.dlt_is_file)
2457     {
2458         return 0;
2459     }
2460
2461     /* log to FIFO */
2462     ret=dlt_user_log_out3(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgRegisterContext),log->context_description,usercontext.description_length);
2463     return ((ret==DLT_RETURN_OK)?0:-1);
2464 }
2465
2466 int dlt_user_log_send_unregister_context(DltContextData *log)
2467 {
2468     DltUserHeader userheader;
2469     DltUserControlMsgUnregisterContext usercontext;
2470     DltReturnValue ret;
2471
2472     if (log==0)
2473     {
2474         return -1;
2475     }
2476
2477     if (log->handle==0)
2478     {
2479         return -1;
2480     }
2481
2482     if ((dlt_user.appID[0]=='\0') || (log->handle->contextID=='\0'))
2483     {
2484         return -1;
2485     }
2486
2487     /* set userheader */
2488     if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_UNREGISTER_CONTEXT)==-1)
2489     {
2490                 return -1;
2491     }
2492
2493     /* set usercontext */
2494     dlt_set_id(usercontext.apid,dlt_user.appID);       /* application id */
2495     dlt_set_id(usercontext.ctid,log->handle->contextID);       /* context id */
2496     usercontext.pid = getpid();
2497
2498     if (dlt_user.dlt_is_file)
2499     {
2500         return 0;
2501     }
2502
2503     /* log to FIFO */
2504     ret=dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgUnregisterContext));
2505         return ((ret==DLT_RETURN_OK)?0:-1);
2506 }
2507
2508 int dlt_send_app_ll_ts_limit(const char *appid, DltLogLevelType loglevel, DltTraceStatusType tracestatus)
2509 {
2510     DltUserHeader userheader;
2511     DltUserControlMsgAppLogLevelTraceStatus usercontext;
2512         DltReturnValue ret;
2513
2514     if ((appid==0) || (appid[0]=='\0'))
2515     {
2516         return -1;
2517     }
2518
2519     /* Removed because of DltLogLevelType and DltTraceStatusType
2520
2521     if ((loglevel<DLT_LOG_DEFAULT) || (loglevel>DLT_LOG_VERBOSE))
2522     {
2523         return -1;
2524     }
2525
2526     if ((tracestatus<DLT_TRACE_STATUS_DEFAULT) || (tracestatus>DLT_TRACE_STATUS_ON))
2527     {
2528         return -1;
2529     }
2530
2531     */
2532
2533     /* set userheader */
2534     if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_APP_LL_TS)==-1)
2535     {
2536                 return -1;
2537     }
2538
2539     /* set usercontext */
2540     dlt_set_id(usercontext.apid,appid);       /* application id */
2541     usercontext.log_level = loglevel;
2542     usercontext.trace_status = tracestatus;
2543
2544     if (dlt_user.dlt_is_file)
2545     {
2546         return 0;
2547     }
2548
2549     /* log to FIFO */
2550     ret=dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgAppLogLevelTraceStatus));
2551     return ((ret==DLT_RETURN_OK)?0:-1);
2552 }
2553
2554 int dlt_user_log_send_log_mode(DltUserLogMode mode)
2555 {
2556     DltUserHeader userheader;
2557     DltUserControlMsgLogMode logmode;
2558
2559     DltReturnValue ret;
2560
2561     /* set userheader */
2562     if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG_MODE)==-1)
2563     {
2564         return -1;
2565     }
2566
2567     /* set data */
2568     logmode.log_mode = (unsigned char) mode;
2569
2570     if (dlt_user.dlt_is_file)
2571     {
2572         return 0;
2573     }
2574
2575     /* log to FIFO */
2576     ret=dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(logmode), sizeof(DltUserControlMsgLogMode));
2577     return ((ret==DLT_RETURN_OK)?0:-1);
2578 }
2579
2580 int dlt_user_print_msg(DltMessage *msg, DltContextData *log)
2581 {
2582     uint8_t *databuffer_tmp;
2583     int32_t datasize_tmp;
2584     static char text[DLT_USER_TEXT_LENGTH];
2585
2586     if ((msg==0) || (log==0))
2587     {
2588         return -1;
2589     }
2590
2591     /* Save variables before print */
2592     databuffer_tmp = msg->databuffer;
2593     datasize_tmp = msg->datasize;
2594
2595     /* Act like a receiver, convert header back to host format */
2596     msg->standardheader->len = DLT_BETOH_16(msg->standardheader->len);
2597     dlt_message_get_extraparameters(msg,0);
2598
2599     msg->databuffer = log->buffer;
2600     msg->datasize = log->size;
2601
2602     /* Print message as ASCII */
2603     if (dlt_message_print_ascii(msg,text,DLT_USER_TEXT_LENGTH,0)==-1)
2604     {
2605                 return -1;
2606     }
2607
2608     /* Restore variables and set len to BE*/
2609     msg->databuffer = databuffer_tmp;
2610     msg->datasize =  datasize_tmp;
2611
2612     msg->standardheader->len = DLT_HTOBE_16(msg->standardheader->len);
2613
2614     return 0;
2615 }
2616
2617 int dlt_user_log_check_user_message(void)
2618 {
2619     int offset=0;
2620     int leave_while=0;
2621
2622     uint32_t i;
2623
2624     DltUserHeader *userheader;
2625     DltReceiver *receiver = &(dlt_user.receiver);
2626
2627     DltUserControlMsgLogLevel *usercontextll;
2628     DltUserControlMsgInjection *usercontextinj;
2629     DltUserControlMsgLogState *userlogstate;
2630     unsigned char *userbuffer;
2631     unsigned char *inject_buffer;
2632
2633     if (dlt_user.dlt_user_handle!=-1)
2634     {
2635         while (1)
2636         {
2637             if (dlt_receiver_receive_fd(receiver)<=0)
2638             {
2639                 /* No new message available */
2640                 return 0;
2641             }
2642
2643             /* look through buffer as long as data is in there */
2644             while (1)
2645             {
2646                 if (receiver->bytesRcvd < (int32_t)sizeof(DltUserHeader))
2647                 {
2648                     break;
2649                 }
2650
2651                 /* resync if necessary */
2652                 offset=0;
2653                 do
2654                 {
2655                     userheader = (DltUserHeader*) (receiver->buf+offset);
2656
2657                     /* Check for user header pattern */
2658                     if (dlt_user_check_userheader(userheader))
2659                     {
2660                         break;
2661                     }
2662                     offset++;
2663
2664                 }
2665                 while ((int32_t)(sizeof(DltUserHeader)+offset)<=receiver->bytesRcvd);
2666
2667                 /* Check for user header pattern */
2668                 if (dlt_user_check_userheader(userheader)==0)
2669                 {
2670                     break;
2671                 }
2672
2673                 /* Set new start offset */
2674                 if (offset>0)
2675                 {
2676                     receiver->buf+=offset;
2677                     receiver->bytesRcvd-=offset;
2678                 }
2679
2680                 switch (userheader->message)
2681                 {
2682                 case DLT_USER_MESSAGE_LOG_LEVEL:
2683                 {
2684                     if (receiver->bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogLevel)))
2685                     {
2686                         leave_while=1;
2687                         break;
2688                     }
2689
2690                     usercontextll = (DltUserControlMsgLogLevel*) (receiver->buf+sizeof(DltUserHeader));
2691
2692                     /* Update log level and trace status */
2693                     if (usercontextll!=0)
2694                     {
2695                         DLT_SEM_LOCK();
2696
2697                         if ((usercontextll->log_level_pos >= 0) && (usercontextll->log_level_pos < (int32_t)dlt_user.dlt_ll_ts_num_entries))
2698                         {
2699                             // printf("Store ll, ts\n");
2700                             if (dlt_user.dlt_ll_ts)
2701                             {
2702                                 dlt_user.dlt_ll_ts[usercontextll->log_level_pos].log_level = usercontextll->log_level;
2703                                 dlt_user.dlt_ll_ts[usercontextll->log_level_pos].trace_status = usercontextll->trace_status;
2704                             }
2705                         }
2706
2707                         DLT_SEM_FREE();
2708                     }
2709
2710                     /* keep not read data in buffer */
2711                     if (dlt_receiver_remove(receiver,sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogLevel))==-1)
2712                     {
2713                         return -1;
2714                     }
2715                 }
2716                 break;
2717                 case DLT_USER_MESSAGE_INJECTION:
2718                 {
2719                     /* At least, user header, user context, and service id and data_length of injected message is available */
2720                     if (receiver->bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgInjection)))
2721                     {
2722                         leave_while = 1;
2723                         break;
2724                     }
2725
2726                     usercontextinj = (DltUserControlMsgInjection*) (receiver->buf+sizeof(DltUserHeader));
2727                     userbuffer = (unsigned char*) (receiver->buf+sizeof(DltUserHeader)+sizeof(DltUserControlMsgInjection));
2728                     inject_buffer = 0;
2729
2730                     if (userbuffer!=0)
2731                     {
2732
2733                         if (receiver->bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgInjection)+usercontextinj->data_length_inject))
2734                         {
2735                             leave_while = 1;
2736                             break;
2737                         }
2738
2739                         DLT_SEM_LOCK();
2740
2741                         if ((usercontextinj->data_length_inject>0) && (dlt_user.dlt_ll_ts))
2742                         {
2743                             /* Check if injection callback is registered for this context */
2744                             for (i=0; i<dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].nrcallbacks;i++)
2745                             {
2746                                 if ((dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table) &&
2747                                         (dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table[i].service_id == usercontextinj->service_id))
2748                                 {
2749                                     /* callback available, so prepare data, then call it */
2750                                     inject_buffer = malloc(usercontextinj->data_length_inject);
2751                                     if (inject_buffer!=0)
2752                                     {
2753                                         /* copy from receiver to inject_buffer */
2754                                         memcpy(inject_buffer, userbuffer, usercontextinj->data_length_inject);
2755
2756                                         /* call callback */
2757                                         if (dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table[i].injection_callback!=0)
2758                                         {
2759                                             // printf("Got injection(%d), length=%d, '%s' \n", usercontext->service_id, usercontext->data_length_inject, inject_buffer);
2760                                             dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table[i].injection_callback(
2761                                                 usercontextinj->service_id, inject_buffer, usercontextinj->data_length_inject);
2762                                         }
2763
2764                                         if (inject_buffer!=0)
2765                                         {
2766                                             free(inject_buffer);
2767                                             inject_buffer = 0;
2768                                         }
2769                                     }
2770
2771                                     break;
2772                                 }
2773                             }
2774                         }
2775
2776                         DLT_SEM_FREE();
2777
2778                         /* keep not read data in buffer */
2779                         if (dlt_receiver_remove(receiver,(sizeof(DltUserHeader)+sizeof(DltUserControlMsgInjection)+usercontextinj->data_length_inject))==-1)
2780                                                 {
2781                                                         return -1;
2782                                                 }
2783                     }
2784                 }
2785                 break;
2786                 case DLT_USER_MESSAGE_LOG_STATE:
2787                 {
2788                     /* At least, user header, user context, and service id and data_length of injected message is available */
2789                     if (receiver->bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogState)))
2790                     {
2791                         leave_while = 1;
2792                         break;
2793                     }
2794
2795                     userlogstate = (DltUserControlMsgLogState*) (receiver->buf+sizeof(DltUserHeader));
2796                                         dlt_user.log_state = userlogstate->log_state;
2797
2798                                         /* keep not read data in buffer */
2799                                         if (dlt_receiver_remove(receiver,(sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogState)))==-1)
2800                                         {
2801                                                 return -1;
2802                                         }
2803                 }
2804                 break;
2805                 default:
2806                 {
2807                     dlt_log(LOG_ERR,"Invalid user message type received!\n");
2808                     /* Ignore result */
2809                     dlt_receiver_remove(receiver,sizeof(DltUserHeader));
2810                                         /* In next invocation of while loop, a resync will be triggered if additional data was received */
2811                 }
2812                 break;
2813                 } /* switch() */
2814
2815                 if (leave_while==1)
2816                 {
2817                     leave_while=0;
2818                     break;
2819                 }
2820
2821             } /* while buffer*/
2822
2823             if (dlt_receiver_move_to_begin(receiver)==-1)
2824             {
2825                                 return -1;
2826             }
2827         } /* while receive */
2828     } /* if */
2829
2830     return DLT_RETURN_OK;
2831 }
2832
2833 int dlt_user_log_resend_buffer(void)
2834 {
2835         int num,count;
2836     uint8_t buf[DLT_USER_RCVBUF_MAX_SIZE];
2837     int size;
2838         DltReturnValue ret;
2839         
2840         /* Send content of ringbuffer */
2841         DLT_SEM_LOCK();
2842         count = dlt_buffer_get_message_count(&(dlt_user.startup_buffer));
2843         DLT_SEM_FREE();
2844
2845         for (num=0;num<count;num++)
2846         {
2847
2848                 DLT_SEM_LOCK();
2849                 size = dlt_buffer_copy(&(dlt_user.startup_buffer),buf,sizeof(buf));
2850
2851                 if (size>0)
2852                 {
2853 #ifdef DLT_SHM_ENABLE                                           
2854                         dlt_shm_push(&dlt_user.dlt_shm,buf+sizeof(DltUserHeader),size-sizeof(DltUserHeader),0,0,0,0);                   
2855
2856                         /* log to FIFO */
2857                         ret = dlt_user_log_out3(dlt_user.dlt_log_handle, buf,sizeof(DltUserHeader),0,0,0,0);
2858 #else
2859                         /* log to FIFO */
2860                         ret = dlt_user_log_out3(dlt_user.dlt_log_handle, buf,size,0,0,0,0);
2861 #endif
2862
2863                         /* in case of error, keep message in ringbuffer */                        
2864                         if (ret==DLT_RETURN_OK)
2865                         {
2866                                 dlt_buffer_remove(&(dlt_user.startup_buffer));
2867                                 /*
2868                                 DLT_SEM_LOCK();
2869                                 if (dlt_buffer_push(&(dlt_user.startup_buffer), buf, size)==-1)
2870                                 {
2871                                         dlt_log(LOG_ERR,"Error pushing back message to history buffer. Message discarded.\n");
2872                                 }
2873                                 DLT_SEM_FREE();
2874
2875                                 // In case of: data could not be written, set overflow flag
2876                                 if (ret==DLT_RETURN_PIPE_FULL)
2877                                 {
2878                                         dlt_user.overflow = 1;
2879                                 }
2880                                 */
2881                         }
2882                         else
2883                         {
2884                                 /* keep message in ringbuffer */   
2885                                 DLT_SEM_FREE();
2886                                 return -1;
2887                         }
2888                 }
2889                 DLT_SEM_FREE();
2890         }
2891         
2892         return 0;
2893 }
2894
2895 void dlt_user_log_reattach_to_daemon(void)
2896 {
2897         uint32_t num,reregistered=0;
2898
2899         DltContext handle;
2900         DltContextData log_new;
2901
2902     if (dlt_user.dlt_log_handle<0)
2903     {
2904         dlt_user.dlt_log_handle=-1;
2905
2906         /* try to open pipe to dlt daemon */
2907         dlt_user.dlt_log_handle = open(DLT_USER_FIFO, O_WRONLY | O_NONBLOCK);
2908         if (dlt_user.dlt_log_handle > 0)
2909         {
2910             if (dlt_user_log_init(&handle,&log_new)==-1)
2911             {
2912                 return;
2913             }
2914
2915 #ifdef DLT_SHM_ENABLE
2916                         /* init shared memory */
2917                         if (dlt_shm_init_client(&dlt_user.dlt_shm,DLT_SHM_KEY) < 0)
2918                         {
2919                                 sprintf(str,"Loging disabled, Shared memory %d cannot be created!\n",DLT_SHM_KEY);
2920                                 dlt_log(LOG_WARNING, str);
2921                                 //return 0; 
2922                         }   
2923 #endif
2924
2925             dlt_log(LOG_NOTICE, "Logging re-enabled!\n");
2926
2927             /* Re-register application */
2928             if (dlt_user_log_send_register_application()==-1)
2929             {
2930                 return;
2931             }
2932
2933             DLT_SEM_LOCK();
2934
2935             /* Re-register all stored contexts */
2936             for (num=0; num<dlt_user.dlt_ll_ts_num_entries; num++)
2937             {
2938                 /* Re-register stored context */
2939                 if ((dlt_user.appID[0]!='\0') && (dlt_user.dlt_ll_ts[num].contextID[0]!='\0') && (dlt_user.dlt_ll_ts))
2940                 {
2941                     //dlt_set_id(log_new.appID, dlt_user.appID);
2942                     dlt_set_id(handle.contextID, dlt_user.dlt_ll_ts[num].contextID);
2943                     handle.log_level_pos = num;
2944                     log_new.context_description = dlt_user.dlt_ll_ts[num].context_description;
2945
2946                     log_new.log_level = DLT_USER_LOG_LEVEL_NOT_SET;
2947                     log_new.trace_status = DLT_USER_TRACE_STATUS_NOT_SET;
2948
2949                     if (dlt_user_log_send_register_context(&log_new)==-1)
2950                     {
2951                         DLT_SEM_FREE();
2952                         return;
2953                     }
2954
2955                     reregistered=1;
2956                 }
2957             }
2958
2959             DLT_SEM_FREE();
2960
2961             if (reregistered==1)
2962             {
2963                                 dlt_user_log_resend_buffer();
2964             }
2965         }
2966     }
2967 }
2968
2969 int dlt_user_log_send_overflow(void)
2970 {
2971     DltUserHeader userheader;
2972     DltReturnValue ret;
2973
2974     /* set userheader */
2975     if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_OVERFLOW)==-1)
2976     {
2977         return -1;
2978     }
2979
2980     if (dlt_user.dlt_is_file)
2981     {
2982         return 0;
2983     }
2984
2985     /* log to FIFO */
2986     ret=dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), 0, 0);
2987     return ((ret==DLT_RETURN_OK)?0:-1);
2988 }
2989
2990 int dlt_user_check_buffer(int *total_size, int *used_size)
2991 {
2992 #ifdef DLT_SHM_ENABLE
2993         *total_size = dlt_shm_get_total_size(&(dlt_user.dlt_shm));
2994         *used_size = dlt_shm_get_used_size(&(dlt_user.dlt_shm));
2995 #else
2996         *total_size = dlt_buffer_get_total_size(&(dlt_user.startup_buffer));
2997         *used_size = dlt_buffer_get_used_size(&(dlt_user.startup_buffer));
2998 #endif
2999         
3000         return 0; /* ok */
3001 }
3002
3003 #ifdef DLT_TEST_ENABLE
3004 void dlt_user_test_corrupt_user_header(int enable)
3005 {
3006     dlt_user.corrupt_user_header = enable;
3007 }
3008 void dlt_user_test_corrupt_message_size(int enable,int16_t size)
3009 {
3010     dlt_user.corrupt_message_size = enable;
3011     dlt_user.corrupt_message_size_size = size;
3012 }
3013 #endif
3014
3015