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