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