Added define statement for initial value of file descriptor and (-1). Updated the...
[profile/ivi/dlt-daemon.git] / src / daemon / dlt-daemon.c
1 /**
2  * @licence app begin@
3  * Copyright (C) 2012  BMW AG
4  *
5  * This file is part of GENIVI Project Dlt - Diagnostic Log and Trace console apps.
6  *
7  * Contributions are licensed to the GENIVI Alliance under one or more
8  * Contribution License Agreements.
9  *
10  * \copyright
11  * This Source Code Form is subject to the terms of the
12  * Mozilla Public License, v. 2.0. If a  copy of the MPL was not distributed with
13  * this file, You can obtain one at http://mozilla.org/MPL/2.0/.
14  *
15  *
16  * \author Alexander Wenzel <alexander.aw.wenzel@bmw.de> BMW 2011-2012
17  *
18  * \file dlt-daemon.c
19  * For further information see http://www.genivi.org/.
20  * @licence end@
21  */
22
23 /*******************************************************************************
24 **                                                                            **
25 **  SRC-MODULE: dlt-daemon.c                                                  **
26 **                                                                            **
27 **  TARGET    : linux                                                         **
28 **                                                                            **
29 **  PROJECT   : DLT                                                           **
30 **                                                                            **
31 **  AUTHOR    : Alexander Wenzel Alexander.AW.Wenzel@bmw.de                   **
32 **              Markus Klein                                                  **
33 **                                                                            **
34 **  PURPOSE   :                                                               **
35 **                                                                            **
36 **  REMARKS   :                                                               **
37 **                                                                            **
38 **  PLATFORM DEPENDANT [yes/no]: yes                                          **
39 **                                                                            **
40 **  TO BE CHANGED BY USER [yes/no]: no                                        **
41 **                                                                            **
42 *******************************************************************************/
43
44 /*******************************************************************************
45 **                      Author Identity                                       **
46 ********************************************************************************
47 **                                                                            **
48 ** Initials     Name                       Company                            **
49 ** --------     -------------------------  ---------------------------------- **
50 **  aw          Alexander Wenzel           BMW                                **
51 **  mk          Markus Klein               Fraunhofer ESK                     **
52 *******************************************************************************/
53
54 /*******************************************************************************
55 **                      Revision Control History                              **
56 *******************************************************************************/
57
58 /*
59  * $LastChangedRevision: 1670 $
60  * $LastChangedDate: 2011-04-08 15:12:06 +0200 (Fr, 08. Apr 2011) $
61  * $LastChangedBy$
62  Initials    Date         Comment
63  aw          13.01.2010   initial
64  */
65
66 #include <netdb.h>
67 #include <ctype.h>
68 #include <stdio.h>      /* for printf() and fprintf() */
69 #include <sys/socket.h> /* for socket(), connect(), (), and recv() */
70 #include <arpa/inet.h>  /* for sockaddr_in and inet_addr() */
71 #include <stdlib.h>     /* for atoi() and exit() */
72 #include <string.h>     /* for memset() */
73 #include <unistd.h>     /* for close() */
74 #include <fcntl.h>
75 #include <signal.h>
76 #include <syslog.h>
77 #include <errno.h>
78 #include <pthread.h>
79
80 #include <sys/timerfd.h>
81 #include <sys/stat.h>
82 #include <sys/time.h>
83 #include <linux/stat.h>
84
85 #include "dlt_types.h"
86 #include "dlt-daemon.h"
87 #include "dlt-daemon_cfg.h"
88
89 /** \page Contents
90   * The package automotive-dlt includes the following items:
91   * - dlt daemon (dlt-daemon)
92   * - adptors to to interface the daemon (dlt-adaptor-stdin, dlt-adaptor-udp)
93   * - dlt client gui (dlt-viewer)
94   * - dlt console tools (dlt-receive, dlt-convert)
95   * - examples (dlt-example-user, dlt-example-user-func, dlt-example-ringbuffer)
96   * - a library including user-application, client and common functions
97   */
98
99 /**
100   \defgroup daemon DLT Daemon
101   \addtogroup daemon
102   \{
103 */
104
105 /** Global text output buffer, mainly used for creation of error/warning strings */
106 static char str[DLT_DAEMON_TEXTBUFSIZE];
107
108 static DltDaemonTimingPacketThreadData dlt_daemon_timingpacket_thread_data;
109
110 static pthread_t      dlt_daemon_timingpacket_thread_handle;
111 static pthread_attr_t dlt_daemon_timingpacket_thread_attr;
112
113 /**
114  * Print usage information of tool.
115  */
116 void usage()
117 {
118     printf("Usage: dlt-daemon [options]\n");
119     printf("DLT logging daemon %s\n", _DLT_PACKAGE_REVISION);
120     printf("Options:\n");
121     printf("  -d            Daemonize\n");
122     printf("  -h            Usage\n");
123     printf("  -c filename   DLT daemon configuration file (Default: /etc/dlt.conf)\n");
124 } /* usage() */
125
126 /**
127  * Option handling
128  */
129 int option_handling(DltDaemonLocal *daemon_local,int argc, char* argv[])
130  {
131         int c;
132
133         if (daemon_local==0)
134         {
135                 fprintf (stderr, "Invalid parameter passed to option_handling()\n");
136                 return -1;
137         }
138
139     /* Initialize flags */
140     memset(daemon_local,0,sizeof(DltDaemonLocal));
141
142     opterr = 0;
143
144     while ((c = getopt (argc, argv, "hdc:")) != -1)
145     {
146         switch (c)
147         {
148         case 'd':
149         {
150             daemon_local->flags.dflag = 1;
151             break;
152         }
153         case 'c':
154         {
155             strncpy(daemon_local->flags.cvalue,optarg,sizeof(daemon_local->flags.cvalue));
156             break;
157         }
158         case 'h':
159         {
160             usage();
161             return -2; /* return no error */
162         }
163         case '?':
164         {
165             if (optopt == 'c')
166             {
167                 fprintf (stderr, "Option -%c requires an argument.\n", optopt);
168             }
169             else if (isprint (optopt))
170             {
171                 fprintf (stderr, "Unknown option `-%c'.\n", optopt);
172             }
173             else
174             {
175                 fprintf (stderr, "Unknown option character `\\x%x'.\n",optopt);
176             }
177             /* unknown or wrong option used, show usage information and terminate */
178             usage();
179             return -1;
180         }
181         default:
182         {
183                 fprintf (stderr, "Invalid option, this should never occur!\n");
184             return -1;
185         }
186         } /* switch() */
187     }
188
189     return 0;
190
191  } /* option_handling() */
192
193 /**
194  * Option file parser
195  */
196 int option_file_parser(DltDaemonLocal *daemon_local)
197 {
198         FILE * pFile;
199         char line[1024];
200         char token[1024];
201         char value[1024];
202     char *pch;
203     const char *filename;
204
205         /* set default values for configuration */
206         daemon_local->flags.sharedMemorySize = DLT_SHM_SIZE;
207         daemon_local->flags.sendMessageTime = 0;
208         daemon_local->flags.offlineTraceDirectory[0] = 0;
209         daemon_local->flags.offlineTraceFileSize = 1000000;
210         daemon_local->flags.offlineTraceMaxSize = 0;
211         daemon_local->flags.loggingMode = 0;
212         daemon_local->flags.loggingLevel = 6;
213         strncpy(daemon_local->flags.loggingFilename, DLT_USER_DIR "/dlt.log",sizeof(daemon_local->flags.loggingFilename));
214
215         /* open configuration file */
216         if(daemon_local->flags.cvalue[0])
217                 filename = daemon_local->flags.cvalue;
218         else
219                 filename = "/etc/dlt.conf";
220     //printf("Load configuration from file: %s\n",filename);
221         pFile = fopen (filename,"r");
222
223         if (pFile!=NULL)
224         {
225                 while(1)
226                 {
227                         /* fetch line from configuration file */
228                         if ( fgets (line , 1024 , pFile) != NULL )
229                         {
230                                   pch = strtok (line," =\r\n");
231                                   token[0]=0;
232                                   value[0]=0;
233                                   
234                                   while (pch != NULL)
235                                   {
236                                         if(strcmp(pch,"#")==0)
237                                                 break;
238
239                                         if(token[0]==0)
240                                         {
241                                                 strncpy(token,pch,sizeof(token));
242                                         }
243                                         else
244                                         {
245                                                 strncpy(value,pch,sizeof(value));
246                                                 break;
247                                         }
248
249                                         pch = strtok (NULL, " =\r\n");
250                                   }
251                                   
252                                   if(token[0] && value[0])
253                                   {
254                                                 /* parse arguments here */
255                                                 if(strcmp(token,"Verbose")==0)
256                                                 {
257                                                         daemon_local->flags.vflag = atoi(value);
258                                                         //printf("Option: %s=%s\n",token,value);
259                                                 }
260                                                 else if(strcmp(token,"PrintASCII")==0)
261                                                 {
262                                                         daemon_local->flags.aflag = atoi(value);
263                                                         //printf("Option: %s=%s\n",token,value);
264                                                 }
265                                                 else if(strcmp(token,"PrintHex")==0)
266                                                 {
267                                                         daemon_local->flags.xflag = atoi(value);
268                                                         //printf("Option: %s=%s\n",token,value);
269                                                 }
270                                                 else if(strcmp(token,"PrintHeadersOnly")==0)
271                                                 {
272                                                         daemon_local->flags.sflag = atoi(value);
273                                                         //printf("Option: %s=%s\n",token,value);
274                                                 }
275                                                 else if(strcmp(token,"SendSerialHeader")==0)
276                                                 {
277                                                         daemon_local->flags.lflag = atoi(value);
278                                                         //printf("Option: %s=%s\n",token,value);
279                                                 }
280                                                 else if(strcmp(token,"SendContextRegistration")==0)
281                                                 {
282                                                         daemon_local->flags.rflag = atoi(value);
283                                                         //printf("Option: %s=%s\n",token,value);
284                                                 }
285                                                 else if(strcmp(token,"SendMessageTime")==0)
286                                                 {
287                                                         daemon_local->flags.sendMessageTime = atoi(value);
288                                                         //printf("Option: %s=%s\n",token,value);
289                                                 }
290                                                 else if(strcmp(token,"RS232SyncSerialHeader")==0)
291                                                 {
292                                                         daemon_local->flags.mflag = atoi(value);
293                                                         //printf("Option: %s=%s\n",token,value);
294                                                 }
295                                                 else if(strcmp(token,"TCPSyncSerialHeader")==0)
296                                                 {
297                                                         daemon_local->flags.nflag = atoi(value);
298                                                         //printf("Option: %s=%s\n",token,value);
299                                                 }
300                                                 else if(strcmp(token,"RS232DeviceName")==0)
301                                                 {
302                                                         strncpy(daemon_local->flags.yvalue,value,sizeof(daemon_local->flags.yvalue));
303                                                         //printf("Option: %s=%s\n",token,value);
304                                                 }
305                                                 else if(strcmp(token,"RS232Baudrate")==0)
306                                                 {
307                                                         strncpy(daemon_local->flags.bvalue,value,sizeof(daemon_local->flags.bvalue));
308                                                         //printf("Option: %s=%s\n",token,value);
309                                                 }
310                                                 else if(strcmp(token,"ECUId")==0)
311                                                 {
312                                                         strncpy(daemon_local->flags.evalue,value,sizeof(daemon_local->flags.evalue));
313                                                         //printf("Option: %s=%s\n",token,value);
314                                                 }
315                                                 else if(strcmp(token,"PersistanceStoragePath")==0)
316                                                 {
317                                                         strncpy(daemon_local->flags.ivalue,value,sizeof(daemon_local->flags.ivalue));
318                                                         //printf("Option: %s=%s\n",token,value);
319                                                 }
320                                                 else if(strcmp(token,"LoggingMode")==0)
321                                                 {
322                                                         daemon_local->flags.loggingMode = atoi(value);
323                                                         //printf("Option: %s=%s\n",token,value);
324                                                 }
325                                                 else if(strcmp(token,"LoggingLevel")==0)
326                                                 {
327                                                         daemon_local->flags.loggingLevel = atoi(value);
328                                                         //printf("Option: %s=%s\n",token,value);
329                                                 }
330                                                 else if(strcmp(token,"LoggingFilename")==0)
331                                                 {
332                                                         strncpy(daemon_local->flags.loggingFilename,value,sizeof(daemon_local->flags.loggingFilename));
333                                                         //printf("Option: %s=%s\n",token,value);
334                                                 }
335                                                 else if(strcmp(token,"SharedMemorySize")==0)
336                                                 {
337                                                         daemon_local->flags.sharedMemorySize = atoi(value);
338                                                         //printf("Option: %s=%s\n",token,value);
339                                                 }
340                                                 else if(strcmp(token,"OfflineTraceDirectory")==0)
341                                                 {
342                                                         strncpy(daemon_local->flags.offlineTraceDirectory,value,sizeof(daemon_local->flags.offlineTraceDirectory));
343                                                         //printf("Option: %s=%s\n",token,value);
344                                                 }
345                                                 else if(strcmp(token,"OfflineTraceFileSize")==0)
346                                                 {
347                                                         daemon_local->flags.offlineTraceFileSize = atoi(value);
348                                                         //printf("Option: %s=%s\n",token,value);
349                                                 }
350                                                 else if(strcmp(token,"OfflineTraceMaxSize")==0)
351                                                 {
352                                                         daemon_local->flags.offlineTraceMaxSize = atoi(value);
353                                                         //printf("Option: %s=%s\n",token,value);
354                                                 }
355                                                 else
356                                                 {
357                                                         fprintf(stderr, "Unknown option: %s=%s\n",token,value);
358                                                 }
359                                         }
360                         }
361                         else
362                         {
363                                 break;
364                         }
365                 }
366                 fclose (pFile);
367         }
368         else
369         {
370                 fprintf(stderr, "Cannot open configuration file: %s\n",filename);
371         }       
372
373         return 0;
374 }
375
376 /**
377  * Main function of tool.
378  */
379 int main(int argc, char* argv[])
380 {
381         char version[DLT_DAEMON_TEXTBUFSIZE];
382     DltDaemonLocal daemon_local;
383     DltDaemon daemon;
384
385     int i,back;
386
387     /* Command line option handling */
388         if ((back = option_handling(&daemon_local,argc,argv))<0)
389         {
390                 if(back!=-2) {
391                         fprintf (stderr, "option_handling() failed!\n");
392                 }
393                 return -1;
394         }
395
396     /* Configuration file option handling */
397         if ((back = option_file_parser(&daemon_local))<0)
398         {
399                 if(back!=-2) {
400                         fprintf (stderr, "option_file_parser() failed!\n");
401                 }
402                 return -1;
403         }
404         
405     /* Initialize internal logging facility */
406     dlt_log_set_filename(daemon_local.flags.loggingFilename);
407     dlt_log_set_level(daemon_local.flags.loggingLevel);
408     dlt_log_init(daemon_local.flags.loggingMode);
409
410     /* Print version information */
411     dlt_get_version(version);
412
413     sprintf(str,"Starting DLT Daemon; %s\n", version );
414     dlt_log(LOG_NOTICE, str);
415
416         PRINT_FUNCTION_VERBOSE(daemon_local.flags.vflag);
417
418     /* --- Daemon init phase 1 begin --- */
419     if (dlt_daemon_local_init_p1(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
420     {
421         dlt_log(LOG_CRIT,"Initialization of phase 1 failed!\n");
422         return -1;
423     }
424     /* --- Daemon init phase 1 end --- */
425
426     /* --- Daemon connection init begin */
427     if (dlt_daemon_local_connection_init(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
428     {
429         dlt_log(LOG_CRIT,"Initialization of local connections failed!\n");
430         return -1;
431     }
432     /* --- Daemon connection init end */
433
434     /* --- Daemon init phase 2 begin --- */
435     if (dlt_daemon_local_init_p2(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
436     {
437         dlt_log(LOG_CRIT,"Initialization of phase 2 failed!\n");
438         return -1;
439     }
440     /* --- Daemon init phase 2 end --- */
441
442     while (1)
443     {
444         /* wait for events form all FIFO and sockets */
445         daemon_local.read_fds = daemon_local.master;
446         if (select(daemon_local.fdmax+1, &(daemon_local.read_fds), NULL, NULL, NULL) == -1)
447         {
448             dlt_log(LOG_CRIT, "select() failed!\n");
449             return -1 ;
450         } /* if */
451
452         /* run through the existing FIFO and sockets to check for events */
453         for (i = 0; i <= daemon_local.fdmax; i++)
454         {
455             if (FD_ISSET(i, &(daemon_local.read_fds)))
456             {
457                 if (i == daemon_local.sock && ((daemon.mode == DLT_USER_MODE_EXTERNAL) || (daemon.mode == DLT_USER_MODE_BOTH)))
458                 {
459                     /* event from TCP server socket, new connection */
460                     if (dlt_daemon_process_client_connect(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
461                     {
462                         dlt_log(LOG_CRIT,"Connect to dlt client failed!\n");
463                         return -1;
464                     }
465                 }
466                 else if (i == daemon_local.fp)
467                 {
468                     /* event from the FIFO happened */
469                     if (dlt_daemon_process_user_messages(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
470                     {
471                         dlt_log(LOG_CRIT,"Processing of messages from user connection failed!\n");
472                         return -1;
473                     }
474                 }
475                 else if ((i == daemon_local.fdserial) && (daemon_local.flags.yvalue[0]))
476                 {
477                     /* event from serial connection to client received */
478                     if (dlt_daemon_process_client_messages_serial(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
479                     {
480                         dlt_log(LOG_CRIT,"Processing of messages from serial connection failed!\n");
481                         return -1;
482                     }
483                 }
484                 else
485                 {
486                     /* event from tcp connection to client received */
487                     daemon_local.receiverSock.fd = i;
488                     if (dlt_daemon_process_client_messages(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
489                     {
490                         dlt_log(LOG_CRIT,"Processing of messages from client connection failed!\n");
491                                                 return -1;
492                     }
493                 } /* else */
494             } /* if */
495         } /* for */
496     } /* while */
497
498     dlt_daemon_local_cleanup(&daemon, &daemon_local, daemon_local.flags.vflag);
499
500     dlt_log(LOG_NOTICE, "Leaving DLT daemon\n");
501
502     return 0;
503
504 } /* main() */
505
506 int dlt_daemon_local_init_p1(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
507 {
508     PRINT_FUNCTION_VERBOSE(verbose);
509
510     if ((daemon==0)  || (daemon_local==0))
511     {
512         dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_local_init_p1()\n");
513         return -1;
514     }
515
516     /* Check for daemon mode */
517     if (daemon_local->flags.dflag)
518     {
519         dlt_daemon_daemonize(daemon_local->flags.vflag);
520     }
521
522     /* initialise structure to use DLT file */
523     if (dlt_file_init(&(daemon_local->file),daemon_local->flags.vflag)==-1)
524     {
525                 dlt_log(LOG_ERR,"Could not initialize file structure\n");
526                 /* Return value ignored, dlt daemon will exit */
527                 dlt_file_free(&(daemon_local->file),daemon_local->flags.vflag);
528                 return -1;
529     }
530
531     signal(SIGPIPE,SIG_IGN);
532
533     signal(SIGTERM, dlt_daemon_signal_handler); /* software termination signal from kill */
534     signal(SIGHUP,  dlt_daemon_signal_handler); /* hangup signal */
535     signal(SIGQUIT, dlt_daemon_signal_handler);
536     signal(SIGINT,  dlt_daemon_signal_handler);
537
538         /* init offline trace */
539         if(((daemon->mode == DLT_USER_MODE_INTERNAL) || (daemon->mode == DLT_USER_MODE_BOTH)) && daemon_local->flags.offlineTraceDirectory[0]) 
540         {
541                 if (dlt_offline_trace_init(&(daemon_local->offlineTrace),daemon_local->flags.offlineTraceDirectory,daemon_local->flags.offlineTraceFileSize,daemon_local->flags.offlineTraceMaxSize)==-1)
542                 {
543                         dlt_log(LOG_ERR,"Could not initialize offline trace\n");
544                         return -1;
545                 }
546         }
547         
548     return 0;
549 }
550
551 int dlt_daemon_local_init_p2(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
552 {
553     PRINT_FUNCTION_VERBOSE(verbose);
554
555     if ((daemon==0)  || (daemon_local==0))
556     {
557         dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_local_init_p2()\n");
558         return -1;
559     }
560
561     /* Daemon data */
562     if (dlt_daemon_init(daemon,daemon_local->flags.ivalue,daemon_local->flags.vflag)==-1)
563     {
564         dlt_log(LOG_ERR,"Could not initialize daemon data\n");
565                 return -1;
566     }
567
568     /* Set ECU id of daemon */
569     if (daemon_local->flags.evalue[0])
570     {
571         dlt_set_id(daemon->ecuid,daemon_local->flags.evalue);
572     }
573     else
574     {
575         dlt_set_id(daemon->ecuid,DLT_DAEMON_ECU_ID);
576     }
577
578     /* Set flag for optional sending of serial header */
579     daemon->sendserialheader = daemon_local->flags.lflag;
580
581 #ifdef DLT_SHM_ENABLE
582         /* init shared memory */
583     if (dlt_shm_init_server(&(daemon_local->dlt_shm),DLT_SHM_KEY,daemon_local->flags.sharedMemorySize)==-1)
584     {
585         dlt_log(LOG_ERR,"Could not initialize shared memory\n");
586                 return -1;
587     }
588 #endif
589         
590     /* prepare main loop */
591     if (dlt_message_init(&(daemon_local->msg),daemon_local->flags.vflag)==-1)
592     {
593         dlt_log(LOG_ERR,"Could not initialize message\n");
594                 return -1;
595     }
596
597     if (dlt_receiver_init(&(daemon_local->receiver),daemon_local->fp,DLT_DAEMON_RCVBUFSIZE)==-1)
598     {
599         dlt_log(LOG_ERR,"Could not initialize receiver\n");
600                 return -1;
601     }
602     if (dlt_receiver_init(&(daemon_local->receiverSock),daemon_local->sock,DLT_DAEMON_RCVBUFSIZESOCK)==-1)
603         {
604         dlt_log(LOG_ERR,"Could not initialize receiver for socket\n");
605                 return -1;
606     }
607     if (daemon_local->flags.yvalue[0])
608     {
609         if (dlt_receiver_init(&(daemon_local->receiverSerial),daemon_local->fdserial,DLT_DAEMON_RCVBUFSIZESERIAL)==-1)
610         {
611                         dlt_log(LOG_ERR,"Could not initialize receiver for serial connection\n");
612                         return -1;
613         }
614     }
615
616     /* setup period thread for timing packets */
617     if (pthread_attr_init(&dlt_daemon_timingpacket_thread_attr)<0)
618     {
619         dlt_log(LOG_WARNING, "Initialization of default thread stack size failed!\n");
620     }
621     else
622     {
623         if (pthread_attr_setstacksize(&dlt_daemon_timingpacket_thread_attr,DLT_DAEMON_TIMINGPACKET_THREAD_STACKSIZE)<0)
624         {
625             dlt_log(LOG_WARNING, "Setting of default thread stack size failed!\n");
626         }
627     }
628     
629     /* configure sending timing packets */
630     if (daemon_local->flags.sendMessageTime)    
631     {
632                 daemon->timingpackets = 1;
633         }
634         
635     /* Binary semaphore for thread */
636     if (sem_init(&dlt_daemon_mutex, 0, 1)==-1)
637     {
638         dlt_log(LOG_ERR,"Could not initialize binary semaphore\n");
639         return -1;
640     }
641
642     /* start thread */
643     dlt_daemon_timingpacket_thread_data.daemon = daemon;
644     dlt_daemon_timingpacket_thread_data.daemon_local = daemon_local;
645
646     if (pthread_create(&(dlt_daemon_timingpacket_thread_handle),
647                        &dlt_daemon_timingpacket_thread_attr,
648                        (void *) &dlt_daemon_timingpacket_thread,
649                        (void *)&dlt_daemon_timingpacket_thread_data)!=0)
650         {
651                 dlt_log(LOG_ERR,"Could not initialize timing packet thread\n");
652                 pthread_attr_destroy(&dlt_daemon_timingpacket_thread_attr);
653         return -1;
654         }
655
656     pthread_attr_destroy(&dlt_daemon_timingpacket_thread_attr);
657
658     return 0;
659 }
660
661 int dlt_daemon_local_connection_init(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
662 {
663     int ret;
664     int yes = 1;
665
666     struct sockaddr_in servAddr;
667     unsigned int servPort = DLT_DAEMON_TCP_PORT;
668
669     PRINT_FUNCTION_VERBOSE(verbose);
670
671     if ((daemon==0)  || (daemon_local==0))
672     {
673         dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_local_connection_init()\n");
674         return -1;
675     }
676
677     /* open named pipe(FIFO) to receive DLT messages from users */
678     umask(0);
679
680     /* Try to delete existing pipe, ignore result of unlink */
681     unlink(DLT_USER_FIFO);
682
683     ret=mkfifo(DLT_USER_FIFO, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH  | S_IWOTH );
684     if (ret==-1)
685     {
686         sprintf(str,"FIFO user %s cannot be created!\n",DLT_USER_FIFO);
687         dlt_log(LOG_ERR, str);
688         return -1;
689     } /* if */
690
691     daemon_local->fp = open(DLT_USER_FIFO, O_RDWR);
692     if (daemon_local->fp==-1)
693     {
694         sprintf(str,"FIFO user %s cannot be opened!\n",DLT_USER_FIFO);
695         dlt_log(LOG_ERR, str);
696         return -1;
697     } /* if */
698
699     /* create and open socket to receive incoming connections from client */
700     if ((daemon_local->sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
701     {
702         dlt_log(LOG_ERR, "socket() failed!\n");
703         return -1;
704     } /* if */
705
706     setsockopt(daemon_local->sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
707     memset(&servAddr, 0, sizeof(servAddr));
708     servAddr.sin_family      = AF_INET;
709     servAddr.sin_addr.s_addr = INADDR_ANY;
710     servAddr.sin_port        = htons(servPort);
711
712     if (bind(daemon_local->sock, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0)
713     {
714         dlt_log(LOG_ERR, "bind() failed!\n");
715         return -1;
716     } /* if */
717
718     if (daemon_local->flags.vflag)
719     {
720         dlt_log(LOG_INFO, "Bind succesfull\n");
721     }
722
723     if (listen(daemon_local->sock, 3) < 0)
724     {
725         dlt_log(LOG_ERR, "listen() failed!\n");
726         return -1;
727     } /* if */
728
729     if (daemon_local->flags.vflag)
730     {
731         dlt_log(LOG_INFO, "Listen succesfull\n");
732     }
733
734     /* prepare usage of select(), add FIFO and receiving socket */
735     FD_ZERO(&(daemon_local->master));
736     FD_ZERO(&(daemon_local->read_fds));
737     FD_SET(daemon_local->sock, &(daemon_local->master));
738
739     daemon_local->fdmax = daemon_local->sock;
740
741     FD_SET(daemon_local->fp, &(daemon_local->master));
742
743     if (daemon_local->fp > daemon_local->fdmax)
744     {
745         daemon_local->fdmax = daemon_local->fp;
746     }
747
748     if (daemon_local->flags.yvalue[0])
749     {
750         /* create and open serial connection from/to client */
751         /* open serial connection */
752         daemon_local->fdserial=open(daemon_local->flags.yvalue,O_RDWR);
753         if (daemon_local->fdserial<0)
754         {
755             sprintf(str,"Failed to open serial device %s\n", daemon_local->flags.yvalue);
756             daemon_local->flags.yvalue[0] = 0;
757             dlt_log(LOG_ERR, str);
758             return -1;
759         }
760
761         if (isatty(daemon_local->fdserial))
762         {
763             if (daemon_local->flags.bvalue[0])
764             {
765                 daemon_local->baudrate = dlt_convert_serial_speed(atoi(daemon_local->flags.bvalue));
766             }
767             else
768             {
769                 daemon_local->baudrate = dlt_convert_serial_speed(DLT_DAEMON_SERIAL_DEFAULT_BAUDRATE);
770             }
771
772             if (dlt_setup_serial(daemon_local->fdserial,daemon_local->baudrate)<0)
773             {
774                 close(daemon_local->fdserial);
775                 sprintf(str,"Failed to configure serial device %s (%s) \n", daemon_local->flags.yvalue, strerror(errno));
776                 daemon_local->flags.yvalue[0] = 0;
777                 dlt_log(LOG_ERR, str);
778                 return -1;
779             }
780
781             FD_SET(daemon_local->fdserial, &(daemon_local->master));
782
783             if (daemon_local->fdserial > daemon_local->fdmax)
784             {
785                 daemon_local->fdmax = daemon_local->fdserial;
786             }
787
788             if (daemon_local->flags.vflag)
789             {
790                 dlt_log(LOG_INFO, "Serial init done\n");
791             }
792         }
793         else
794         {
795             close(daemon_local->fdserial);
796             fprintf(stderr,"Device is not a serial device, device = %s (%s) \n", daemon_local->flags.yvalue, strerror(errno));
797             daemon_local->flags.yvalue[0] = 0;
798             return -1;
799         }
800     }
801
802     return 0;
803 }
804
805
806 void dlt_daemon_local_cleanup(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
807 {
808     PRINT_FUNCTION_VERBOSE(verbose);
809
810     if ((daemon==0)  || (daemon_local==0))
811     {
812                 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_local_cleanup()\n");
813         return;
814     }
815
816         /* Ignore result */
817     dlt_receiver_free(&(daemon_local->receiver));
818     /* Ignore result */
819     dlt_receiver_free(&(daemon_local->receiverSock));
820
821         /* Ignore result */
822     dlt_message_free(&(daemon_local->msg),daemon_local->flags.vflag);
823     close(daemon_local->fp);
824
825         /* free shared memory */
826         if(daemon_local->flags.offlineTraceDirectory[0])
827                 dlt_offline_trace_free(&(daemon_local->offlineTrace));
828 #if 0
829     if (daemon_local->flags.ovalue[0])
830     {
831         close(daemon_local->ohandle);
832     } /* if */
833 #endif
834
835         /* Ignore result */
836     dlt_file_free(&(daemon_local->file),daemon_local->flags.vflag);
837
838     /* Try to delete existing pipe, ignore result of unlink() */
839     unlink(DLT_USER_FIFO);
840
841 #ifdef DLT_SHM_ENABLE
842         /* free shared memory */
843         dlt_shm_free_server(&(daemon_local->dlt_shm));
844 #endif
845
846     /* Try to delete lock file, ignore result of unlink() */
847     unlink(DLT_DAEMON_LOCK_FILE);
848 }
849
850 void dlt_daemon_signal_handler(int sig)
851 {
852     switch (sig)
853     {
854     case SIGHUP:
855     case SIGTERM:
856     case SIGINT:
857     case SIGQUIT:
858     {
859         /* finalize the server */
860         //dlt_log("terminate signal catched");
861         dlt_log(LOG_NOTICE, "Exiting DLT daemon\n");
862
863         /* Try to delete existing pipe, ignore result of unlink() */
864         unlink(DLT_USER_FIFO);
865
866         /* Try to delete lock file, ignore result of unlink() */
867         unlink(DLT_DAEMON_LOCK_FILE);
868
869                 /* Terminate program */
870         exit(0);
871         break;
872     }
873     default:
874     {
875         /* This case should never occur */
876         break;
877     }
878     } /* switch */
879 } /* dlt_daemon_signal_handler() */
880
881 void dlt_daemon_daemonize(int verbose)
882 {
883     int i,lfp,bytes_written,ret;
884
885     PRINT_FUNCTION_VERBOSE(verbose);
886
887     dlt_log(LOG_NOTICE, "Daemon mode\n");
888
889     /* Daemonize */
890     i=fork();
891     if (i<0)
892     {
893         dlt_log(LOG_CRIT, "Unable to fork(), exiting DLT daemon\n");
894         exit(-1); /* fork error */
895     }
896
897     if (i>0)
898     {
899         exit(0); /* parent exits */
900     }
901     /* child (daemon) continues */
902
903     /* Process independency */
904
905      /* obtain a new process group */
906     if (setsid()==-1)
907     {
908         dlt_log(LOG_CRIT, "setsid() failed, exiting DLT daemon\n");
909         exit(-1); /* fork error */
910     }
911
912     /* Close descriptors */
913     for (i=getdtablesize();i>=0;--i)
914     {
915         close(i); /* close all descriptors */
916     }
917
918     /* Open standard descriptors stdin, stdout, stderr */
919     i=open("/dev/null",O_RDWR); /* open stdin */
920     ret=dup(i); /* stdout */
921     ret=dup(i); /* stderr */
922
923     /* Set umask */
924     umask(DLT_DAEMON_UMASK);
925
926     /* Change to known directory */
927     ret=chdir(DLT_USER_DIR);
928
929     /* Ensure single copy of daemon;
930        run only one instance at a time */
931     lfp=open(DLT_DAEMON_LOCK_FILE,O_RDWR|O_CREAT,DLT_DAEMON_LOCK_FILE_PERM);
932     if (lfp<0)
933     {
934         dlt_log(LOG_CRIT, "can't open lock file, exiting DLT daemon\n");
935         exit(-1); /* can not open */
936     }
937     if (lockf(lfp,F_TLOCK,0)<0)
938     {
939         dlt_log(LOG_CRIT, "can't lock lock file, exiting DLT daemon\n");
940         exit(-1); /* can not lock */
941     }
942     /* only first instance continues */
943
944     sprintf(str,"%d\n",getpid());
945     bytes_written=write(lfp,str,strlen(str)); /* record pid to lockfile */
946
947     /* Catch signals */
948     signal(SIGCHLD,SIG_IGN); /* ignore child */
949     signal(SIGTSTP,SIG_IGN); /* ignore tty signals */
950     signal(SIGTTOU,SIG_IGN);
951     signal(SIGTTIN,SIG_IGN);
952
953 } /* dlt_daemon_daemonize() */
954
955 int dlt_daemon_process_client_connect(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
956 {
957     socklen_t cli_size;
958     struct sockaddr cli;
959
960     int in_sock = -1;
961
962     PRINT_FUNCTION_VERBOSE(verbose);
963
964     if ((daemon==0)  || (daemon_local==0))
965     {
966         dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_client_connect()\n");
967         return -1;
968     }
969
970     /* event from TCP server socket, new connection */
971     cli_size = sizeof(cli);
972     if ((in_sock  = accept(daemon_local->sock,&cli, &cli_size)) < 0)
973     {
974         dlt_log(LOG_ERR, "accept() failed!\n");
975         return -1 ;
976     }
977
978     /* check if file file descriptor was already used, and make it invalid if it is reused */
979     /* This prevents sending messages to wrong file descriptor */
980     dlt_daemon_applications_invalidate_fd(daemon,in_sock,verbose);
981     dlt_daemon_contexts_invalidate_fd(daemon,in_sock,verbose);
982
983     //sprintf("str,"Client Connection from %s\n", inet_ntoa(cli.sin_addr));
984     //dlt_log(str);
985     FD_SET(in_sock, &(daemon_local->master)); /* add to master set */
986     if (in_sock > daemon_local->fdmax)
987     {
988         /* keep track of the maximum */
989         daemon_local->fdmax = in_sock;
990     } /* if */
991
992     daemon_local->client_connections++;
993     if (daemon_local->flags.vflag)
994     {
995         sprintf(str, "New connection to client established, #connections: %d\n",daemon_local->client_connections);
996         dlt_log(LOG_INFO, str);
997     }
998
999     if (daemon_local->client_connections==1)
1000     {
1001         if (daemon_local->flags.vflag)
1002         {
1003             dlt_log(LOG_INFO, "Send ring-buffer to client\n");
1004         }
1005         if (dlt_daemon_send_ringbuffer_to_client(daemon, daemon_local, verbose)==-1)
1006         {
1007                 dlt_log(LOG_ERR,"Can't send contents of ringbuffer to clients\n");
1008                         return -1;
1009         }
1010                 
1011                 /* send new log state to all applications */
1012                 daemon->state = 1;              
1013                 dlt_daemon_user_send_all_log_state(daemon,verbose);
1014     }
1015
1016     return 0;
1017 }
1018
1019 int dlt_daemon_process_client_messages(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1020 {
1021     int bytes_to_be_removed=0;
1022
1023     PRINT_FUNCTION_VERBOSE(verbose);
1024
1025     if ((daemon==0)  || (daemon_local==0))
1026     {
1027         dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_client_messages()\n");
1028         return -1;
1029     }
1030
1031     if (dlt_receiver_receive_socket(&(daemon_local->receiverSock))<=0)
1032     {
1033         close(daemon_local->receiverSock.fd);
1034         FD_CLR(daemon_local->receiverSock.fd, &(daemon_local->master));
1035
1036         if (daemon_local->client_connections)
1037         {
1038             daemon_local->client_connections--;
1039         }
1040
1041                 if(daemon_local->client_connections==0)
1042                 {
1043                         /* send new log state to all applications */
1044                         daemon->state = 0;              
1045                         dlt_daemon_user_send_all_log_state(daemon,verbose);
1046                 }
1047                                 
1048         if (daemon_local->flags.vflag)
1049         {
1050             sprintf(str, "Connection to client lost, #connections: %d\n",daemon_local->client_connections);
1051             dlt_log(LOG_INFO, str);
1052         }
1053
1054         /* check: return 0; */
1055     }
1056
1057     /* Process all received messages */
1058     while (dlt_message_read(&(daemon_local->msg),(uint8_t*)daemon_local->receiverSock.buf,daemon_local->receiverSock.bytesRcvd,daemon_local->flags.nflag,daemon_local->flags.vflag)==0)
1059     {
1060         /* Check for control message */
1061         if (DLT_MSG_IS_CONTROL_REQUEST(&(daemon_local->msg)))
1062         {
1063             dlt_daemon_control_process_control(daemon_local->receiverSock.fd, daemon, &(daemon_local->msg), daemon_local->flags.vflag);
1064         }
1065
1066         bytes_to_be_removed = daemon_local->msg.headersize+daemon_local->msg.datasize-sizeof(DltStorageHeader);
1067         if (daemon_local->msg.found_serialheader)
1068         {
1069             bytes_to_be_removed += sizeof(dltSerialHeader);
1070         }
1071         if (daemon_local->msg.resync_offset)
1072         {
1073             bytes_to_be_removed += daemon_local->msg.resync_offset;
1074         }
1075
1076         if (dlt_receiver_remove(&(daemon_local->receiverSock),bytes_to_be_removed)==-1)
1077         {
1078                 dlt_log(LOG_ERR,"Can't remove bytes from receiver for sockets\n");
1079                         return -1;
1080         }
1081
1082     } /* while */
1083
1084
1085     if (dlt_receiver_move_to_begin(&(daemon_local->receiverSock))==-1)
1086     {
1087         dlt_log(LOG_ERR,"Can't move bytes to beginning of receiver buffer for sockets\n");
1088                 return -1;
1089     }
1090
1091     return 0;
1092 }
1093
1094 int dlt_daemon_process_client_messages_serial(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1095 {
1096     int bytes_to_be_removed=0;
1097
1098     PRINT_FUNCTION_VERBOSE(verbose);
1099
1100     if ((daemon==0)  || (daemon_local==0))
1101     {
1102                 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_client_messages_serial()\n");
1103         return -1;
1104     }
1105
1106     if (dlt_receiver_receive_fd(&(daemon_local->receiverSerial))<=0)
1107     {
1108                 dlt_log(LOG_ERR, "dlt_receiver_receive_fd() for messages from serial interface failed!\n");
1109         return -1;
1110     }
1111
1112     /* Process all received messages */
1113     while (dlt_message_read(&(daemon_local->msg),(uint8_t*)daemon_local->receiverSerial.buf,daemon_local->receiverSerial.bytesRcvd,daemon_local->flags.mflag,daemon_local->flags.vflag)==0)
1114     {
1115         /* Check for control message */
1116         if (DLT_MSG_IS_CONTROL_REQUEST(&(daemon_local->msg)))
1117         {
1118             if (dlt_daemon_control_process_control(daemon_local->receiverSerial.fd, daemon, &(daemon_local->msg), daemon_local->flags.vflag)==-1)
1119             {
1120                                 dlt_log(LOG_ERR,"Can't process control messages\n");
1121                                 return -1;
1122             }
1123         }
1124
1125         bytes_to_be_removed = daemon_local->msg.headersize+daemon_local->msg.datasize-sizeof(DltStorageHeader);
1126         if (daemon_local->msg.found_serialheader)
1127         {
1128             bytes_to_be_removed += sizeof(dltSerialHeader);
1129         }
1130         if (daemon_local->msg.resync_offset)
1131         {
1132             bytes_to_be_removed += daemon_local->msg.resync_offset;
1133         }
1134
1135         if (dlt_receiver_remove(&(daemon_local->receiverSerial),bytes_to_be_removed)==-1)
1136                 {
1137                 dlt_log(LOG_ERR,"Can't remove bytes from receiver for serial connection\n");
1138                         return -1;
1139         }
1140
1141     } /* while */
1142
1143
1144     if (dlt_receiver_move_to_begin(&(daemon_local->receiverSerial))==-1)
1145         {
1146         dlt_log(LOG_ERR,"Can't move bytes to beginning of receiver buffer for serial connection\n");
1147                 return -1;
1148     }
1149
1150     return 0;
1151 }
1152
1153 int dlt_daemon_process_user_messages(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1154 {
1155     int offset=0;
1156     int run_loop=1;
1157     DltUserHeader *userheader;
1158
1159     PRINT_FUNCTION_VERBOSE(verbose);
1160
1161     if ((daemon==0)  || (daemon_local==0))
1162     {
1163         dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_messages()\n");
1164         return -1;
1165     }
1166
1167     /* read data from FIFO */
1168     if (dlt_receiver_receive_fd(&(daemon_local->receiver))<0)
1169     {
1170         dlt_log(LOG_ERR, "dlt_receiver_receive_fd() for user messages failed!\n");
1171         return -1;
1172     }
1173
1174     /* look through buffer as long as data is in there */
1175     do
1176     {
1177         if (daemon_local->receiver.bytesRcvd < (int32_t)sizeof(DltUserHeader))
1178         {
1179             break;
1180         }
1181
1182         /* resync if necessary */
1183         offset=0;
1184         do
1185         {
1186             userheader = (DltUserHeader*) (daemon_local->receiver.buf+offset);
1187
1188             /* Check for user header pattern */
1189             if (dlt_user_check_userheader(userheader))
1190             {
1191                 break;
1192             }
1193
1194             offset++;
1195
1196         }
1197         while ((int32_t)(sizeof(DltUserHeader)+offset)<=daemon_local->receiver.bytesRcvd);
1198
1199         /* Check for user header pattern */
1200         if (dlt_user_check_userheader(userheader)==0)
1201         {
1202             break;
1203         }
1204
1205         /* Set new start offset */
1206         if (offset>0)
1207         {
1208             daemon_local->receiver.buf+=offset;
1209             daemon_local->receiver.bytesRcvd-=offset;
1210         }
1211
1212         switch (userheader->message)
1213         {
1214         case DLT_USER_MESSAGE_OVERFLOW:
1215         {
1216             if (dlt_daemon_process_user_message_overflow(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1217             {
1218                 run_loop=0;
1219             }
1220             break;
1221         }
1222         case DLT_USER_MESSAGE_REGISTER_CONTEXT:
1223         {
1224             if (dlt_daemon_process_user_message_register_context(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1225             {
1226                 run_loop=0;
1227             }
1228             break;
1229         }
1230         case DLT_USER_MESSAGE_UNREGISTER_CONTEXT:
1231         {
1232             if (dlt_daemon_process_user_message_unregister_context(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1233             {
1234                 run_loop=0;
1235             }
1236             break;
1237         }
1238         case DLT_USER_MESSAGE_LOG:
1239         {
1240             if (dlt_daemon_process_user_message_log(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1241             {
1242                 run_loop=0;
1243             }
1244             break;
1245         }
1246 #ifdef DLT_SHM_ENABLE
1247         case DLT_USER_MESSAGE_LOG_SHM:
1248         {
1249             if (dlt_daemon_process_user_message_log_shm(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1250             {
1251                 run_loop=0;
1252             }
1253             break;
1254         }
1255 #endif
1256         case DLT_USER_MESSAGE_REGISTER_APPLICATION:
1257         {
1258             if (dlt_daemon_process_user_message_register_application(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1259             {
1260                 run_loop=0;
1261             }
1262             break;
1263         }
1264         case DLT_USER_MESSAGE_UNREGISTER_APPLICATION:
1265         {
1266             if (dlt_daemon_process_user_message_unregister_application(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1267             {
1268                 run_loop=0;
1269             }
1270             break;
1271         }
1272         case DLT_USER_MESSAGE_APP_LL_TS:
1273         {
1274             if (dlt_daemon_process_user_message_set_app_ll_ts(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1275             {
1276                 run_loop=0;
1277             }
1278             break;
1279         }
1280         case DLT_USER_MESSAGE_LOG_MODE:
1281         {
1282             if (dlt_daemon_process_user_message_log_mode(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1283             {
1284                 run_loop=0;
1285             }
1286             break;
1287         }
1288         default:
1289         {
1290             dlt_log(LOG_ERR,"(Internal) Invalid user message type received!\n");
1291
1292             /* remove user header */
1293             if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader))==-1)
1294             {
1295                                 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user messages\n");
1296                                 return -1;
1297                         }
1298
1299             /* In next invocation of do-while loop, a resync will be triggered if additional data was received */
1300             run_loop=0;
1301
1302             break;
1303         }
1304         }
1305
1306     }
1307     while (run_loop);
1308
1309     /* keep not read data in buffer */
1310     if (dlt_receiver_move_to_begin(&(daemon_local->receiver))==-1)
1311         {
1312         dlt_log(LOG_ERR,"Can't move bytes to beginning of receiver buffer for user messages\n");
1313                 return -1;
1314     }
1315
1316     return 0;
1317 }
1318
1319 int dlt_daemon_process_user_message_overflow(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1320 {
1321     int j, sent;
1322
1323     PRINT_FUNCTION_VERBOSE(verbose);
1324
1325     if ((daemon==0)  || (daemon_local==0))
1326     {
1327         dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_overflow()\n");
1328         return -1;
1329     }
1330
1331     /* Store in daemon, that a message buffer overflow has occured */
1332     daemon->message_buffer_overflow = DLT_MESSAGE_BUFFER_OVERFLOW;
1333
1334     /* look if TCP connection to client is available */
1335     sent = 0;
1336
1337     for (j = 0; j <= daemon_local->fdmax; j++)
1338     {
1339         /* send to everyone! */
1340         if (FD_ISSET(j, &(daemon_local->master)))
1341         {
1342             /* except the listener and ourselves */
1343             if ((j != daemon_local->fp) && (j != daemon_local->sock))
1344             {
1345                 dlt_daemon_control_message_buffer_overflow(j, daemon, verbose);
1346                 sent=1;
1347                 /* Reset overflow state */
1348                 daemon->message_buffer_overflow = DLT_MESSAGE_BUFFER_NO_OVERFLOW;
1349             } /* if */
1350         } /* if */
1351     } /* for */
1352
1353     /* message was not sent, so store it in ringbuffer */
1354     if (sent==0)
1355     {
1356         dlt_daemon_control_message_buffer_overflow(DLT_DAEMON_STORE_TO_BUFFER, daemon, verbose);
1357     }
1358
1359     /* keep not read data in buffer */
1360     if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader))==-1)
1361     {
1362                 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message overflow\n");
1363                 return -1;
1364     }
1365
1366     return 0;
1367 }
1368
1369 int dlt_daemon_process_user_message_register_application(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1370 {
1371     uint32_t len=0;
1372     DltDaemonApplication *application;
1373     char description[DLT_DAEMON_DESCSIZE];
1374     DltUserControlMsgRegisterApplication *usercontext;
1375
1376     PRINT_FUNCTION_VERBOSE(verbose);
1377
1378     if ((daemon==0)  || (daemon_local==0))
1379     {
1380         dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_register_application()\n");
1381         return -1;
1382     }
1383
1384     if (daemon_local->receiver.bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterApplication)))
1385     {
1386         /* Not enough bytes received */
1387         return -1;
1388     }
1389
1390     usercontext = (DltUserControlMsgRegisterApplication*) (daemon_local->receiver.buf+sizeof(DltUserHeader));
1391
1392     memset(description,0,sizeof(description));
1393
1394     len=usercontext->description_length;
1395     if ((len>0) && (len<=DLT_DAEMON_DESCSIZE))
1396     {
1397         /* Read and store application description */
1398         strncpy(description, (daemon_local->receiver.buf+sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterApplication)), len);
1399     }
1400
1401     application=dlt_daemon_application_add(daemon,usercontext->apid,usercontext->pid,description,verbose);
1402
1403         /* send log state to new application */
1404         dlt_daemon_user_send_log_state(daemon,application,verbose);
1405
1406     /* keep not read data in buffer */
1407     if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterApplication)+len)==-1)
1408         {
1409                 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register application\n");
1410                 return -1;
1411     }
1412
1413     if (application==0)
1414     {
1415         dlt_log(LOG_CRIT,"Can't add application");
1416         return -1;
1417     }
1418
1419     return 0;
1420 }
1421
1422 int dlt_daemon_process_user_message_register_context(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1423 {
1424     uint32_t len=0;
1425     int8_t loglevel, tracestatus;
1426     DltUserControlMsgRegisterContext *usercontext;
1427     char description[DLT_DAEMON_DESCSIZE];
1428         DltDaemonApplication *application;
1429         DltDaemonContext *context;
1430         DltServiceGetLogInfoRequest *req;
1431
1432         DltMessage msg;
1433         int j;
1434         int sent;
1435
1436     PRINT_FUNCTION_VERBOSE(verbose);
1437
1438     if ((daemon==0)  || (daemon_local==0))
1439     {
1440         dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_register_context()\n");
1441         return -1;
1442     }
1443
1444     if (daemon_local->receiver.bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)))
1445     {
1446         /* Not enough bytes received */
1447         return -1;
1448     }
1449
1450     usercontext = (DltUserControlMsgRegisterContext*) (daemon_local->receiver.buf+sizeof(DltUserHeader));
1451
1452     memset(description,0,sizeof(description));
1453
1454     len=usercontext->description_length;
1455     if ((len>0) && (len<=DLT_DAEMON_DESCSIZE))
1456     {
1457         /* Read and store context description */
1458         strncpy(description, (daemon_local->receiver.buf+sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)), len);
1459     }
1460
1461     application = dlt_daemon_application_find(daemon,usercontext->apid,verbose);
1462
1463     if (application==0)
1464     {
1465         dlt_log(LOG_ERR, "Application not found in dlt_daemon_process_user_message_register_context()\n");
1466         if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)+len)==-1)
1467                 {
1468                         dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register context\n");
1469                         return -1;
1470                 }
1471         return 0;
1472     }
1473
1474     /* Pre-set loglevel */
1475     if (usercontext->log_level == DLT_USER_LOG_LEVEL_NOT_SET)
1476     {
1477         loglevel=DLT_LOG_DEFAULT;
1478     }
1479     else
1480     {
1481         loglevel=usercontext->log_level;
1482         /* Plausibility check */
1483         if ((loglevel<DLT_LOG_DEFAULT) || (loglevel>DLT_LOG_VERBOSE))
1484         {
1485             if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)+len)==-1)
1486             {
1487                                 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register context\n");
1488                         }
1489             return -1;
1490         }
1491     }
1492
1493     /* Pre-set tracestatus */
1494     if (usercontext->trace_status == DLT_USER_TRACE_STATUS_NOT_SET)
1495     {
1496         tracestatus=DLT_TRACE_STATUS_DEFAULT;
1497     }
1498     else
1499     {
1500         tracestatus=usercontext->trace_status;
1501
1502         /* Plausibility check */
1503         if ((tracestatus<DLT_TRACE_STATUS_DEFAULT) || (tracestatus>DLT_TRACE_STATUS_ON))
1504         {
1505             if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)+len)==-1)
1506                         {
1507                                 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register context\n");
1508                         }
1509             return -1;
1510         }
1511     }
1512
1513     context = dlt_daemon_context_add(daemon,usercontext->apid,usercontext->ctid, loglevel, tracestatus, usercontext->log_level_pos,application->user_handle,description,verbose);
1514
1515     if (context==0)
1516     {
1517         if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)+len)==-1)
1518                 {
1519                         dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register context\n");
1520                 }
1521
1522                 dlt_log(LOG_CRIT,"Can't add context");
1523         return -1;
1524     }
1525     /* Create automatic get log info response for registered context */
1526     if (daemon_local->flags.rflag)
1527     {
1528         /* Prepare request for get log info with one application and one context */
1529         if (dlt_message_init(&msg, verbose)==-1)
1530         {
1531                 dlt_log(LOG_ERR,"Can't initialize message");
1532                 return -1;
1533         }
1534
1535         msg.datasize = sizeof(DltServiceGetLogInfoRequest);
1536         if (msg.databuffer && (msg.databuffersize < msg.datasize))
1537         {
1538             free(msg.databuffer);
1539             msg.databuffer=0;
1540         }
1541         if (msg.databuffer == 0){
1542                 msg.databuffer = (uint8_t *) malloc(msg.datasize);
1543                 msg.databuffersize = msg.datasize;
1544         }
1545         if (msg.databuffer==0)
1546         {
1547                 dlt_log(LOG_ERR,"Can't allocate buffer for get log info message\n");
1548                         return -1;
1549         }
1550
1551         req = (DltServiceGetLogInfoRequest*) msg.databuffer;
1552
1553         req->service_id = DLT_SERVICE_ID_GET_LOG_INFO;
1554         req->options = 7;
1555         dlt_set_id(req->apid, usercontext->apid);
1556         dlt_set_id(req->ctid, usercontext->ctid);
1557         dlt_set_id(req->com,"remo");
1558
1559         sent=0;
1560
1561         /* Send response to get log info request to DLT clients */
1562         for (j = 0; j <= daemon_local->fdmax; j++)
1563         {
1564             /* send to everyone! */
1565             if (FD_ISSET(j, &(daemon_local->master)))
1566             {
1567                 /* except the listener and ourselves */
1568                 if ((j != daemon_local->fp) && (j != daemon_local->sock))
1569                 {
1570                     dlt_daemon_control_get_log_info(j , daemon, &msg, verbose);
1571                     sent=1;
1572                 }
1573             }
1574         }
1575
1576         if (sent==0)
1577         {
1578             /* Store to buffer */
1579             dlt_daemon_control_get_log_info(DLT_DAEMON_STORE_TO_BUFFER , daemon, &msg, verbose);
1580         }
1581
1582         dlt_message_free(&msg, verbose);
1583     }
1584
1585     if (context->user_handle >= DLT_FD_MINIMUM)
1586     {
1587         /* This call also replaces the default values with the values defined for default */
1588         if (dlt_daemon_user_send_log_level(daemon, context, verbose)==-1)
1589         {
1590                         dlt_log(LOG_ERR,"Can't send current log level as response to user message register context\n");
1591                         return -1;
1592         }
1593     }
1594
1595     /* keep not read data in buffer */
1596     if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)+len)==-1)
1597         {
1598                 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register context\n");
1599                 return -1;
1600         }
1601
1602     return 0;
1603 }
1604
1605 int dlt_daemon_process_user_message_unregister_application(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1606 {
1607     DltUserControlMsgUnregisterApplication *usercontext;
1608     DltDaemonApplication *application;
1609     DltDaemonContext *context;
1610     int i, offset_base;
1611
1612     PRINT_FUNCTION_VERBOSE(verbose);
1613
1614     if ((daemon==0)  || (daemon_local==0))
1615     {
1616         dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_unregister_application()\n");
1617         return -1;
1618     }
1619
1620     if (daemon_local->receiver.bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgUnregisterApplication)))
1621     {
1622         /* Not enough bytes received */
1623         return -1;
1624     }
1625
1626     if (daemon->num_applications>0)
1627     {
1628         usercontext = (DltUserControlMsgUnregisterApplication*) (daemon_local->receiver.buf+sizeof(DltUserHeader));
1629
1630         /* Delete this application and all corresponding contexts for this application from internal table */
1631         application = dlt_daemon_application_find(daemon,usercontext->apid, verbose);
1632
1633         if (application)
1634         {
1635             /* Calculate start offset within contexts[] */
1636             offset_base=0;
1637             for (i=0; i<(application-(daemon->applications)); i++)
1638             {
1639                 offset_base+=daemon->applications[i].num_contexts;
1640             }
1641
1642             for (i=application->num_contexts-1; i>=0; i--)
1643             {
1644                 context = &(daemon->contexts[offset_base+i]);
1645                 if (context)
1646                 {
1647                     /* Delete context */
1648                     if (dlt_daemon_context_del(daemon, context, verbose)==-1)
1649                     {
1650                         dlt_log(LOG_ERR,"Can't delete context for user message unregister application\n");
1651                         return -1;
1652                     }
1653                 }
1654             }
1655
1656             /* Delete this application entry from internal table*/
1657             if (dlt_daemon_application_del(daemon, application, verbose)==-1)
1658             {
1659                 dlt_log(LOG_ERR,"Can't delete application for user message unregister application\n");
1660                                 return -1;
1661             }
1662         }
1663     }
1664
1665     /* keep not read data in buffer */
1666     if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgUnregisterApplication))==-1)
1667     {
1668         dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message unregister application\n");
1669                 return -1;
1670     }
1671
1672     return 0;
1673 }
1674
1675 int dlt_daemon_process_user_message_unregister_context(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1676 {
1677         DltUserControlMsgUnregisterContext *usercontext;
1678         DltDaemonContext *context;
1679
1680     PRINT_FUNCTION_VERBOSE(verbose);
1681
1682     if ((daemon==0)  || (daemon_local==0))
1683     {
1684         dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_unregister_context()\n");
1685         return -1;
1686     }
1687
1688     if (daemon_local->receiver.bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgUnregisterContext)))
1689     {
1690         /* Not enough bytes received */
1691         return -1;
1692     }
1693
1694     usercontext = (DltUserControlMsgUnregisterContext*) (daemon_local->receiver.buf+sizeof(DltUserHeader));
1695     context = dlt_daemon_context_find(daemon,usercontext->apid, usercontext->ctid, verbose);
1696
1697     if (context)
1698     {
1699         /* Delete this connection entry from internal table*/
1700         if (dlt_daemon_context_del(daemon, context, verbose)==-1)
1701         {
1702                         dlt_log(LOG_ERR,"Can't delete context for user message unregister context\n");
1703                         return -1;
1704                 }
1705     }
1706
1707     /* keep not read data in buffer */
1708     if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgUnregisterContext))==-1)
1709     {
1710         dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message unregister context\n");
1711                 return -1;
1712     }
1713
1714     return 0;
1715 }
1716
1717 int dlt_daemon_process_user_message_log(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1718 {
1719     int bytes_to_be_removed;
1720     int j,sent,third_value;
1721     ssize_t ret;
1722
1723     static char text[DLT_DAEMON_TEXTSIZE];
1724
1725     PRINT_FUNCTION_VERBOSE(verbose);
1726
1727     if ((daemon==0)  || (daemon_local==0))
1728     {
1729         dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_log()\n");
1730         return -1;
1731     }
1732
1733     if (dlt_message_read(&(daemon_local->msg),(unsigned char*)daemon_local->receiver.buf+sizeof(DltUserHeader),daemon_local->receiver.bytesRcvd-sizeof(DltUserHeader),0,verbose)==0)
1734     {
1735         /* set overwrite ecu id */
1736         if (daemon_local->flags.evalue!=0)
1737         {
1738             /* Set header extra parameters */
1739             dlt_set_id(daemon_local->msg.headerextra.ecu, daemon->ecuid );
1740             //msg.headerextra.seid = 0;
1741             if (dlt_message_set_extraparameters(&(daemon_local->msg),0)==-1)
1742             {
1743                 dlt_log(LOG_ERR,"Can't set message extra parameters in process user message log\n");
1744                                 return -1;
1745             }
1746
1747             /* Correct value of timestamp, this was changed by dlt_message_set_extraparameters() */
1748             daemon_local->msg.headerextra.tmsp = DLT_BETOH_32(daemon_local->msg.headerextra.tmsp);
1749         }
1750
1751         /* prepare storage header */
1752         if (DLT_IS_HTYP_WEID(daemon_local->msg.standardheader->htyp))
1753         {
1754             if (dlt_set_storageheader(daemon_local->msg.storageheader,daemon_local->msg.headerextra.ecu)==-1)
1755             {
1756                                 dlt_log(LOG_ERR,"Can't set storage header in process user message log\n");
1757                                 return -1;
1758             }
1759         }
1760         else
1761         {
1762             if (dlt_set_storageheader(daemon_local->msg.storageheader,daemon->ecuid)==-1)
1763             {
1764                                 dlt_log(LOG_ERR,"Can't set storage header in process user message log\n");
1765                                 return -1;
1766             }
1767         }
1768
1769         {
1770             /* if no filter set or filter is matching display message */
1771             if (daemon_local->flags.xflag)
1772             {
1773                 if (dlt_message_print_hex(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1)
1774                                 {
1775                                         dlt_log(LOG_ERR,"dlt_message_print_hex() failed!\n");
1776                                 }
1777             } /*  if */
1778             else if (daemon_local->flags.aflag)
1779             {
1780                 if (dlt_message_print_ascii(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1)
1781                 {
1782                                         dlt_log(LOG_ERR,"dlt_message_print_ascii() failed!\n");
1783                                 }
1784             } /* if */
1785             else if (daemon_local->flags.sflag)
1786             {
1787                 if (dlt_message_print_header(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1)
1788                                 {
1789                                         dlt_log(LOG_ERR,"dlt_message_print_header() failed!\n");
1790                                 }
1791                 /* print message header only */
1792             } /* if */
1793
1794             sent=0;
1795
1796                         /* write message to offline trace */
1797                         if(((daemon->mode == DLT_USER_MODE_INTERNAL) || (daemon->mode == DLT_USER_MODE_BOTH)) && daemon_local->flags.offlineTraceDirectory[0])
1798                         {
1799                                 dlt_offline_trace_write(&(daemon_local->offlineTrace),daemon_local->msg.headerbuffer,daemon_local->msg.headersize,
1800                                                                                 daemon_local->msg.databuffer,daemon_local->msg.datasize,0,0);
1801                                 sent = 1;
1802                         }
1803
1804             /* look if TCP connection to client is available */
1805             for (j = 0;((daemon->mode == DLT_USER_MODE_EXTERNAL) || (daemon->mode == DLT_USER_MODE_BOTH)) &&  (j <= daemon_local->fdmax); j++)
1806             {
1807                 /* send to everyone! */
1808                 if (FD_ISSET(j, &(daemon_local->master)))
1809                 {
1810                     /* except the listener and ourselves */
1811                     if (daemon_local->flags.yvalue[0])
1812                     {
1813                         third_value = daemon_local->fdserial;
1814                     }
1815                     else
1816                     {
1817                         third_value = daemon_local->sock;
1818                     }
1819
1820                     if ((j != daemon_local->fp) && (j != daemon_local->sock) && (j != third_value))
1821                     {
1822                         DLT_DAEMON_SEM_LOCK();
1823
1824                         if (daemon_local->flags.lflag)
1825                         {
1826                             send(j,dltSerialHeader,sizeof(dltSerialHeader),0);
1827                         }
1828
1829                         send(j,daemon_local->msg.headerbuffer+sizeof(DltStorageHeader),daemon_local->msg.headersize-sizeof(DltStorageHeader),0);
1830                         send(j,daemon_local->msg.databuffer,daemon_local->msg.datasize,0);
1831
1832                         DLT_DAEMON_SEM_FREE();
1833
1834                         sent=1;
1835                     } /* if */
1836                     else if ((j == daemon_local->fdserial) && (daemon_local->flags.yvalue!=0))
1837                     {
1838                         DLT_DAEMON_SEM_LOCK();
1839
1840                         if (daemon_local->flags.lflag)
1841                         {
1842                             ret=write(j,dltSerialHeader,sizeof(dltSerialHeader));
1843                         }
1844
1845                         ret=write(j,daemon_local->msg.headerbuffer+sizeof(DltStorageHeader),daemon_local->msg.headersize-sizeof(DltStorageHeader));
1846                         ret=write(j,daemon_local->msg.databuffer,daemon_local->msg.datasize);
1847
1848                         DLT_DAEMON_SEM_FREE();
1849
1850                         sent=1;
1851                     }
1852                 } /* if */
1853             } /* for */
1854
1855             /* Message was not sent to client, so store it in client ringbuffer */
1856             if (sent==0)
1857             {
1858                 if (dlt_buffer_push3(&(daemon->client_ringbuffer),
1859                                     daemon_local->msg.headerbuffer+sizeof(DltStorageHeader),daemon_local->msg.headersize-sizeof(DltStorageHeader),
1860                                     daemon_local->msg.databuffer,daemon_local->msg.datasize,
1861                                     0, 0
1862                                    )<0)
1863                                 {
1864                                         dlt_log(LOG_ERR,"Storage of message in history buffer failed! Message discarded.\n");
1865                                 }
1866             }
1867
1868         }
1869         /* keep not read data in buffer */
1870         bytes_to_be_removed = daemon_local->msg.headersize+daemon_local->msg.datasize-sizeof(DltStorageHeader)+sizeof(DltUserHeader);
1871         if (daemon_local->msg.found_serialheader)
1872         {
1873             bytes_to_be_removed += sizeof(dltSerialHeader);
1874         }
1875
1876         if (dlt_receiver_remove(&(daemon_local->receiver),bytes_to_be_removed)==-1)
1877         {
1878                 dlt_log(LOG_ERR,"Can't remove bytes from receiver\n");
1879                 return -1;
1880         }
1881     }
1882     else
1883     {
1884         dlt_log(LOG_ERR,"Can't read messages from receiver\n");
1885         return -1;
1886     }
1887
1888     return 0;
1889 }
1890
1891 #ifdef DLT_SHM_ENABLE
1892 int dlt_daemon_process_user_message_log_shm(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1893 {
1894     int bytes_to_be_removed=0;
1895     int j,sent,third_value;
1896     ssize_t ret;
1897     uint8_t rcv_buffer[10000];
1898     int size;
1899     DltUserHeader *userheader;
1900
1901     static char text[DLT_DAEMON_TEXTSIZE];
1902
1903     PRINT_FUNCTION_VERBOSE(verbose);
1904
1905     if ((daemon==0)  || (daemon_local==0))
1906     {
1907         dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_log()\n");
1908         return -1;
1909     }
1910
1911     userheader = (DltUserHeader*) (daemon_local->receiver.buf);
1912   
1913         //dlt_shm_status(&(daemon_local->dlt_shm));
1914         while (1)
1915     {           
1916                 /* log message in SHM */
1917                 if((size = dlt_shm_copy(&(daemon_local->dlt_shm),rcv_buffer,10000)) <= 0)
1918                         break;
1919                 if (dlt_message_read(&(daemon_local->msg),rcv_buffer,size,0,verbose)!=0) {
1920                         break;
1921                         dlt_log(LOG_ERR,"Can't read messages from shm\n");
1922                         return -1;
1923                 }                               
1924                 bytes_to_be_removed = daemon_local->msg.headersize+daemon_local->msg.datasize-sizeof(DltStorageHeader)+sizeof(DltUserHeader);
1925                 if (daemon_local->msg.found_serialheader)
1926                 {
1927                         bytes_to_be_removed += sizeof(dltSerialHeader);
1928                 }
1929                 
1930                 /* set overwrite ecu id */
1931                 if (daemon_local->flags.evalue[0])
1932                 {
1933                         /* Set header extra parameters */
1934                         dlt_set_id(daemon_local->msg.headerextra.ecu, daemon->ecuid );
1935                         //msg.headerextra.seid = 0;
1936                         if (dlt_message_set_extraparameters(&(daemon_local->msg),0)==-1)
1937                         {
1938                                 dlt_log(LOG_ERR,"Can't set message extra parameters in process user message log\n");
1939                                 dlt_shm_remove(&(daemon_local->dlt_shm));
1940                                 return -1;
1941                         }
1942
1943                         /* Correct value of timestamp, this was changed by dlt_message_set_extraparameters() */
1944                         daemon_local->msg.headerextra.tmsp = DLT_BETOH_32(daemon_local->msg.headerextra.tmsp);
1945                 }
1946
1947                 /* prepare storage header */
1948                 if (DLT_IS_HTYP_WEID(daemon_local->msg.standardheader->htyp))
1949                 {
1950                         if (dlt_set_storageheader(daemon_local->msg.storageheader,daemon_local->msg.headerextra.ecu)==-1)
1951                         {
1952                                 dlt_log(LOG_ERR,"Can't set storage header in process user message log\n");
1953                                 dlt_shm_remove(&(daemon_local->dlt_shm));
1954                                 return -1;
1955                         }
1956                 }
1957                 else
1958                 {
1959                         if (dlt_set_storageheader(daemon_local->msg.storageheader,daemon->ecuid)==-1)
1960                         {
1961                                 dlt_log(LOG_ERR,"Can't set storage header in process user message log\n");
1962                                 dlt_shm_remove(&(daemon_local->dlt_shm));
1963                                 return -1;
1964                         }
1965                 }
1966
1967                 /* display message */
1968                 if (daemon_local->flags.xflag)
1969                 {
1970                         if (dlt_message_print_hex(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1)
1971                         {
1972                                 dlt_log(LOG_ERR,"dlt_message_print_hex() failed!\n");
1973                         }
1974                 } /*  if */
1975                 else if (daemon_local->flags.aflag)
1976                 {
1977                         if (dlt_message_print_ascii(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1)
1978                         {
1979                                 dlt_log(LOG_ERR,"dlt_message_print_ascii() failed!\n");
1980                         }
1981                 } /* if */
1982                 else if (daemon_local->flags.sflag)
1983                 {
1984                         if (dlt_message_print_header(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1)
1985                         {
1986                                 dlt_log(LOG_ERR,"dlt_message_print_header() failed!\n");
1987                         }
1988                         /* print message header only */
1989                 } /* if */
1990
1991                 sent=0;
1992
1993                 /* write message to offline trace */
1994                 if(((daemon->mode == DLT_USER_MODE_INTERNAL) || (daemon->mode == DLT_USER_MODE_BOTH)) && daemon_local->flags.offlineTraceDirectory[0])
1995                 {
1996                         dlt_offline_trace_write(&(daemon_local->offlineTrace),daemon_local->msg.headerbuffer,daemon_local->msg.headersize,
1997                                                                         daemon_local->msg.databuffer,daemon_local->msg.datasize,0,0);
1998                         sent = 1;
1999                 }
2000
2001                 /* look if TCP connection to client is available */
2002                 for (j = 0;((daemon->mode == DLT_USER_MODE_EXTERNAL) || (daemon->mode == DLT_USER_MODE_BOTH)) &&  (j <= daemon_local->fdmax); j++)
2003                 {
2004                         /* send to everyone! */
2005                         if (FD_ISSET(j, &(daemon_local->master)))
2006                         {
2007                                 /* except the listener and ourselves */
2008                                 if (daemon_local->flags.yvalue[0])
2009                                 {
2010                                         third_value = daemon_local->fdserial;
2011                                 }
2012                                 else
2013                                 {
2014                                         third_value = daemon_local->sock;
2015                                 }
2016
2017                                 if ((j != daemon_local->fp) && (j != daemon_local->sock) && (j != third_value))
2018                                 {
2019                                         DLT_DAEMON_SEM_LOCK();
2020
2021                                         if (daemon_local->flags.lflag)
2022                                         {
2023                                                 send(j,dltSerialHeader,sizeof(dltSerialHeader),0);
2024                                         }
2025
2026                                         send(j,daemon_local->msg.headerbuffer+sizeof(DltStorageHeader),daemon_local->msg.headersize-sizeof(DltStorageHeader),0);
2027                                         send(j,daemon_local->msg.databuffer,daemon_local->msg.datasize,0);
2028
2029                                         DLT_DAEMON_SEM_FREE();
2030
2031                                         sent=1;
2032                                 } /* if */
2033                                 else if ((j == daemon_local->fdserial) && (daemon_local->flags.yvalue[0]))
2034                                 {
2035                                         DLT_DAEMON_SEM_LOCK();
2036
2037                                         if (daemon_local->flags.lflag)
2038                                         {
2039                                                 ret=write(j,dltSerialHeader,sizeof(dltSerialHeader));
2040                                         }
2041
2042                                         ret=write(j,daemon_local->msg.headerbuffer+sizeof(DltStorageHeader),daemon_local->msg.headersize-sizeof(DltStorageHeader));
2043                                         ret=write(j,daemon_local->msg.databuffer,daemon_local->msg.datasize);
2044
2045                                         DLT_DAEMON_SEM_FREE();
2046
2047                                         sent=1;
2048                                 }
2049                         } /* if */
2050                 } /* for */
2051
2052                 /* Message was not sent to client, so store it in client ringbuffer */
2053                 if (sent==1 || (daemon->mode == DLT_USER_MODE_OFF))
2054                 {
2055                         if(userheader->message == DLT_USER_MESSAGE_LOG_SHM) {
2056                                 /* dlt message was sent, remove from buffer if log message from shm */
2057                                 dlt_shm_remove(&(daemon_local->dlt_shm));
2058                         }                       
2059                 }
2060                 else
2061                 {
2062                         /* dlt message was not sent, keep in buffer */
2063                         break;
2064                 }
2065                 
2066         }
2067
2068     /* keep not read data in buffer */
2069     if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader))==-1)
2070     {
2071                 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message overflow\n");
2072                 return -1;
2073     }
2074     
2075     return 0;
2076 }
2077 #endif
2078
2079 int dlt_daemon_process_user_message_set_app_ll_ts(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
2080 {
2081     DltUserControlMsgAppLogLevelTraceStatus *usercontext;
2082     DltDaemonApplication *application;
2083     DltDaemonContext *context;
2084     int i, offset_base;
2085     int8_t old_log_level, old_trace_status;
2086
2087     PRINT_FUNCTION_VERBOSE(verbose);
2088
2089     if ((daemon==0)  || (daemon_local==0))
2090     {
2091         dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_set_app_ll_ts()\n");
2092         return -1;
2093     }
2094
2095     if (daemon_local->receiver.bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgAppLogLevelTraceStatus )))
2096     {
2097         /* Not enough bytes receeived */
2098         return -1;
2099     }
2100
2101     if (daemon->num_applications>0)
2102     {
2103         usercontext = (DltUserControlMsgAppLogLevelTraceStatus*) (daemon_local->receiver.buf+sizeof(DltUserHeader));
2104
2105         /* Get all contexts with application id matching the received application id */
2106         application = dlt_daemon_application_find(daemon, usercontext->apid, verbose);
2107         if (application)
2108         {
2109             /* Calculate start offset within contexts[] */
2110             offset_base=0;
2111             for (i=0; i<(application-(daemon->applications)); i++)
2112             {
2113                 offset_base+=daemon->applications[i].num_contexts;
2114             }
2115
2116             for (i=0; i < application->num_contexts; i++)
2117             {
2118                 context = &(daemon->contexts[offset_base+i]);
2119                 if (context)
2120                 {
2121                     old_log_level = context->log_level;
2122                     context->log_level = usercontext->log_level; /* No endianess conversion necessary*/
2123
2124                     old_trace_status = context->trace_status;
2125                     context->trace_status = usercontext->trace_status;   /* No endianess conversion necessary */
2126
2127                     /* The folowing function sends also the trace status */
2128                     if (context->user_handle >= DLT_FD_MINIMUM && dlt_daemon_user_send_log_level(daemon, context, verbose)!=0)
2129                     {
2130                         context->log_level = old_log_level;
2131                         context->trace_status = old_trace_status;
2132                     }
2133                 }
2134             }
2135         }
2136     }
2137
2138     /* keep not read data in buffer */
2139     if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgAppLogLevelTraceStatus))==-1)
2140         {
2141                 dlt_log(LOG_ERR,"Can't remove bytes from receiver\n");
2142                 return -1;
2143         }
2144
2145     return 0;
2146 }
2147
2148 int dlt_daemon_process_user_message_log_mode(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
2149 {
2150         DltUserControlMsgLogMode *logmode;
2151
2152     PRINT_FUNCTION_VERBOSE(verbose);
2153
2154     if ((daemon==0)  || (daemon_local==0))
2155     {
2156         dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_log_mode()\n");
2157         return -1;
2158     }
2159
2160     if (daemon_local->receiver.bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgUnregisterContext)))
2161     {
2162         /* Not enough bytes received */
2163         return -1;
2164     }
2165
2166     logmode = (DltUserControlMsgLogMode*) (daemon_local->receiver.buf+sizeof(DltUserHeader));
2167
2168         /* set the new log mode */
2169         daemon->mode = logmode->log_mode;
2170
2171         /* write configuration persistantly */
2172         dlt_daemon_configuration_save(daemon, daemon->runtime_configuration, verbose);
2173
2174     /* keep not read data in buffer */
2175     if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogMode))==-1)
2176     {
2177         dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message log mode\n");
2178                 return -1;
2179     }
2180
2181     return 0;
2182 }
2183
2184 int dlt_daemon_send_ringbuffer_to_client(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
2185 {
2186     static uint8_t data[DLT_DAEMON_RCVBUFSIZE];
2187     int length;
2188     int j, third_value;
2189     ssize_t ret;
2190
2191     PRINT_FUNCTION_VERBOSE(verbose);
2192
2193     if ((daemon==0)  || (daemon_local==0))
2194     {
2195         dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_send_ringbuffer_to_client()\n");
2196         return -1;
2197     }
2198
2199         /* Attention: If the message can't be send at this time, it will be silently discarded. */
2200     while ((length = dlt_buffer_pull(&(daemon->client_ringbuffer), data, sizeof(data) )) > 0)
2201     {
2202         /* look if TCP connection to client is available */
2203         for (j = 0; j <= daemon_local->fdmax; j++)
2204         {
2205             /* send to everyone! */
2206             if (FD_ISSET(j, &(daemon_local->master)))
2207             {
2208                 /* except the listener and ourselves */
2209                 if (daemon_local->flags.yvalue[0])
2210                 {
2211                     third_value = daemon_local->fdserial;
2212                 }
2213                 else
2214                 {
2215                     third_value = daemon_local->sock;
2216                 }
2217
2218                 if ((j != daemon_local->fp) && (j != daemon_local->sock) && (j != third_value))
2219                 {
2220                     DLT_DAEMON_SEM_LOCK();
2221
2222                     if (daemon_local->flags.lflag)
2223                     {
2224                         send(j,dltSerialHeader,sizeof(dltSerialHeader),0);
2225                     }
2226                     send(j,data,length,0);
2227
2228                     DLT_DAEMON_SEM_FREE();
2229
2230                 } /* if */
2231                 else if ((j == daemon_local->fdserial) && (daemon_local->flags.yvalue[0]))
2232                 {
2233                     DLT_DAEMON_SEM_LOCK();
2234
2235                     if (daemon_local->flags.lflag)
2236                     {
2237                         ret=write(j,dltSerialHeader,sizeof(dltSerialHeader));
2238                     }
2239                     ret=write(j,data,length);
2240
2241                     DLT_DAEMON_SEM_LOCK();
2242                 }
2243             } /* if */
2244         } /* for */
2245         length = sizeof(data);
2246     }
2247
2248     return 0;
2249 }
2250
2251 void dlt_daemon_timingpacket_thread(void *ptr)
2252 {
2253     DltDaemonPeriodicData info;
2254     int j;
2255
2256     DltDaemonTimingPacketThreadData *data;
2257     DltDaemon *daemon;
2258     DltDaemonLocal *daemon_local;
2259
2260     if (ptr==0)
2261     {
2262         dlt_log(LOG_ERR, "No data pointer passed to timingpacket thread\n");
2263         return;
2264     }
2265
2266     data = (DltDaemonTimingPacketThreadData*)ptr;
2267     daemon = data->daemon;
2268     daemon_local = data->daemon_local;
2269
2270     if ((daemon==0) || (daemon_local==0))
2271     {
2272         dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_timingpacket_thread()");
2273         return;
2274     }
2275
2276     if (dlt_daemon_make_periodic (1000000, &info, daemon_local->flags.vflag)<0)
2277     {
2278         dlt_log(LOG_CRIT,"Can't initialize thread timer!\n");
2279         return;
2280     }
2281
2282     while (1)
2283     {
2284         /* If enabled, send timing packets to all clients */
2285         if (daemon->timingpackets)
2286         {
2287             for (j = 0; j <= daemon_local->fdmax; j++)
2288             {
2289                 /* send to everyone! */
2290                 if (FD_ISSET(j, &(daemon_local->master)))
2291                 {
2292                     /* except the listener and ourselves */
2293                     if ((j != daemon_local->fp) && (j != daemon_local->sock))
2294                     {
2295                         dlt_daemon_control_message_time(j, daemon, daemon_local->flags.vflag);
2296                     }
2297                 }
2298             }
2299         }
2300         /* Wait for next period */
2301         dlt_daemon_wait_period (&info, daemon_local->flags.vflag);
2302     }
2303 }
2304
2305 int dlt_daemon_make_periodic (unsigned int period, DltDaemonPeriodicData *info, int verbose)
2306 {
2307     int ret;
2308     unsigned int ns;
2309     unsigned int sec;
2310     int fd;
2311     struct itimerspec itval;
2312
2313     PRINT_FUNCTION_VERBOSE(verbose);
2314
2315     if (info==0)
2316     {
2317         dlt_log(LOG_ERR,"No data pointer passed!\n");
2318         return -1;
2319     }
2320
2321     /* Create the timer */
2322     fd = timerfd_create (CLOCK_MONOTONIC, 0);
2323
2324     info->wakeups_missed = 0;
2325     info->timer_fd = fd;
2326
2327     if (fd == -1)
2328     {
2329         dlt_log(LOG_ERR,"Can't create timer filedescriptor");
2330         return -1;
2331     }
2332
2333     /* Make the timer periodic */
2334     sec = period/1000000;
2335     ns = (period - (sec * 1000000)) * 1000;
2336     itval.it_interval.tv_sec = sec;
2337     itval.it_interval.tv_nsec = ns;
2338     itval.it_value.tv_sec = sec;
2339     itval.it_value.tv_nsec = ns;
2340
2341     ret = timerfd_settime (fd, 0, &itval, NULL);
2342
2343     return ret;
2344 }
2345
2346 void dlt_daemon_wait_period (DltDaemonPeriodicData *info, int verbose)
2347 {
2348     unsigned long long missed;
2349     int ret;
2350
2351     PRINT_FUNCTION_VERBOSE(verbose);
2352
2353     ret = read (info->timer_fd, &missed, sizeof (missed));
2354
2355     if (missed > 0)
2356     {
2357         info->wakeups_missed += (missed - 1);
2358     }
2359 }
2360
2361 /**
2362   \}
2363 */