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