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