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