3 * Copyright (C) 2012 BMW AG
5 * This file is part of GENIVI Project Dlt - Diagnostic Log and Trace console apps.
7 * Contributions are licensed to the GENIVI Alliance under one or more
8 * Contribution License Agreements.
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/.
16 * \author Alexander Wenzel <alexander.aw.wenzel@bmw.de> BMW 2011-2012
19 * For further information see http://www.genivi.org/.
23 /*******************************************************************************
25 ** SRC-MODULE: dlt-daemon.c **
31 ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de **
38 ** PLATFORM DEPENDANT [yes/no]: yes **
40 ** TO BE CHANGED BY USER [yes/no]: no **
42 *******************************************************************************/
44 /*******************************************************************************
46 ********************************************************************************
48 ** Initials Name Company **
49 ** -------- ------------------------- ---------------------------------- **
50 ** aw Alexander Wenzel BMW **
51 ** mk Markus Klein Fraunhofer ESK **
52 *******************************************************************************/
54 /*******************************************************************************
55 ** Revision Control History **
56 *******************************************************************************/
59 * $LastChangedRevision: 1670 $
60 * $LastChangedDate: 2011-04-08 15:12:06 +0200 (Fr, 08. Apr 2011) $
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() */
80 #include <sys/timerfd.h>
83 #include <linux/stat.h>
85 #include "dlt_types.h"
86 #include "dlt-daemon.h"
87 #include "dlt-daemon_cfg.h"
89 #if defined(DLT_SYSTEMD_WATCHDOG_ENABLE) || defined(DLT_SYSTEMD_ENABLE)
90 #include "sd-daemon.h"
94 \defgroup daemon DLT Daemon
99 /** Global text output buffer, mainly used for creation of error/warning strings */
100 static char str[DLT_DAEMON_TEXTBUFSIZE];
102 static DltDaemonTimingPacketThreadData dlt_daemon_timingpacket_thread_data;
104 static pthread_t dlt_daemon_timingpacket_thread_handle;
105 static pthread_attr_t dlt_daemon_timingpacket_thread_attr;
107 static DltDaemonECUVersionThreadData dlt_daemon_ecu_version_thread_data;
108 static pthread_t dlt_daemon_ecu_version_thread_handle;
110 #if defined(DLT_SYSTEMD_WATCHDOG_ENABLE)
111 // Allow main loop to execute every 100ms
112 #define DLT_SELECT_TIMEOUT_USEC (1000 * 100)
113 static DltDaemonTimingPacketThreadData dlt_daemon_systemd_watchdog_thread_data;
114 static pthread_t dlt_daemon_systemd_watchdog_thread_handle;
118 * Print usage information of tool.
122 char version[DLT_DAEMON_TEXTBUFSIZE];
123 dlt_get_version(version);
125 //printf("DLT logging daemon %s %s\n", _DLT_PACKAGE_VERSION, _DLT_PACKAGE_VERSION_STATE);
126 //printf("Compile options: %s %s %s %s",_DLT_SYSTEMD_ENABLE, _DLT_SYSTEMD_WATCHDOG_ENABLE, _DLT_TEST_ENABLE, _DLT_SHM_ENABLE);
127 printf("%s", version);
128 printf("Usage: dlt-daemon [options]\n");
129 printf("Options:\n");
130 printf(" -d Daemonize\n");
131 printf(" -h Usage\n");
132 printf(" -c filename DLT daemon configuration file (Default: /etc/dlt.conf)\n");
138 int option_handling(DltDaemonLocal *daemon_local,int argc, char* argv[])
144 fprintf (stderr, "Invalid parameter passed to option_handling()\n");
148 /* Initialize flags */
149 memset(daemon_local,0,sizeof(DltDaemonLocal));
153 while ((c = getopt (argc, argv, "hdc:")) != -1)
159 daemon_local->flags.dflag = 1;
164 strncpy(daemon_local->flags.cvalue,optarg,NAME_MAX);
170 return -2; /* return no error */
176 fprintf (stderr, "Option -%c requires an argument.\n", optopt);
178 else if (isprint (optopt))
180 fprintf (stderr, "Unknown option `-%c'.\n", optopt);
184 fprintf (stderr, "Unknown option character `\\x%x'.\n",optopt);
186 /* unknown or wrong option used, show usage information and terminate */
192 fprintf (stderr, "Invalid option, this should never occur!\n");
200 } /* option_handling() */
205 int option_file_parser(DltDaemonLocal *daemon_local)
208 int value_length = 1024;
209 char line[value_length-1];
210 char token[value_length];
211 char value[value_length];
213 const char *filename;
215 /* set default values for configuration */
216 daemon_local->flags.sharedMemorySize = DLT_SHM_SIZE;
217 daemon_local->flags.sendMessageTime = 0;
218 daemon_local->flags.offlineTraceDirectory[0] = 0;
219 daemon_local->flags.offlineTraceFileSize = 1000000;
220 daemon_local->flags.offlineTraceMaxSize = 0;
221 daemon_local->flags.loggingMode = 0;
222 daemon_local->flags.loggingLevel = 6;
223 strncpy(daemon_local->flags.loggingFilename, DLT_USER_DIR "/dlt.log",sizeof(daemon_local->flags.loggingFilename));
224 daemon_local->flags.sendECUSoftwareVersion = 0;
225 memset(daemon_local->flags.pathToECUSoftwareVersion, 0, sizeof(daemon_local->flags.pathToECUSoftwareVersion));
227 /* open configuration file */
228 if(daemon_local->flags.cvalue[0])
229 filename = daemon_local->flags.cvalue;
231 filename = "/etc/dlt.conf";
232 //printf("Load configuration from file: %s\n",filename);
233 pFile = fopen (filename,"r");
239 /* fetch line from configuration file */
240 if ( fgets (line , value_length - 1 , pFile) != NULL )
242 pch = strtok (line," =\r\n");
248 if(strcmp(pch,"#")==0)
253 strncpy(token,pch,sizeof(token) - 1);
257 strncpy(value,pch,sizeof(value) - 1);
261 pch = strtok (NULL, " =\r\n");
264 if(token[0] && value[0])
266 /* parse arguments here */
267 if(strcmp(token,"Verbose")==0)
269 daemon_local->flags.vflag = atoi(value);
270 //printf("Option: %s=%s\n",token,value);
272 else if(strcmp(token,"PrintASCII")==0)
274 daemon_local->flags.aflag = atoi(value);
275 //printf("Option: %s=%s\n",token,value);
277 else if(strcmp(token,"PrintHex")==0)
279 daemon_local->flags.xflag = atoi(value);
280 //printf("Option: %s=%s\n",token,value);
282 else if(strcmp(token,"PrintHeadersOnly")==0)
284 daemon_local->flags.sflag = atoi(value);
285 //printf("Option: %s=%s\n",token,value);
287 else if(strcmp(token,"SendSerialHeader")==0)
289 daemon_local->flags.lflag = atoi(value);
290 //printf("Option: %s=%s\n",token,value);
292 else if(strcmp(token,"SendContextRegistration")==0)
294 daemon_local->flags.rflag = atoi(value);
295 //printf("Option: %s=%s\n",token,value);
297 else if(strcmp(token,"SendMessageTime")==0)
299 daemon_local->flags.sendMessageTime = atoi(value);
300 //printf("Option: %s=%s\n",token,value);
302 else if(strcmp(token,"RS232SyncSerialHeader")==0)
304 daemon_local->flags.mflag = atoi(value);
305 //printf("Option: %s=%s\n",token,value);
307 else if(strcmp(token,"TCPSyncSerialHeader")==0)
309 daemon_local->flags.nflag = atoi(value);
310 //printf("Option: %s=%s\n",token,value);
312 else if(strcmp(token,"RS232DeviceName")==0)
314 strncpy(daemon_local->flags.yvalue,value,NAME_MAX);
315 //printf("Option: %s=%s\n",token,value);
317 else if(strcmp(token,"RS232Baudrate")==0)
319 strncpy(daemon_local->flags.bvalue,value,NAME_MAX);
320 //printf("Option: %s=%s\n",token,value);
322 else if(strcmp(token,"ECUId")==0)
324 strncpy(daemon_local->flags.evalue,value,NAME_MAX);
325 //printf("Option: %s=%s\n",token,value);
327 else if(strcmp(token,"PersistanceStoragePath")==0)
329 strncpy(daemon_local->flags.ivalue,value,NAME_MAX);
330 //printf("Option: %s=%s\n",token,value);
332 else if(strcmp(token,"LoggingMode")==0)
334 daemon_local->flags.loggingMode = atoi(value);
335 //printf("Option: %s=%s\n",token,value);
337 else if(strcmp(token,"LoggingLevel")==0)
339 daemon_local->flags.loggingLevel = atoi(value);
340 //printf("Option: %s=%s\n",token,value);
342 else if(strcmp(token,"LoggingFilename")==0)
344 strncpy(daemon_local->flags.loggingFilename,value,sizeof(daemon_local->flags.loggingFilename) - 1);
345 //printf("Option: %s=%s\n",token,value);
347 else if(strcmp(token,"SharedMemorySize")==0)
349 daemon_local->flags.sharedMemorySize = atoi(value);
350 //printf("Option: %s=%s\n",token,value);
352 else if(strcmp(token,"OfflineTraceDirectory")==0)
354 strncpy(daemon_local->flags.offlineTraceDirectory,value,sizeof(daemon_local->flags.offlineTraceDirectory) - 1);
355 //printf("Option: %s=%s\n",token,value);
357 else if(strcmp(token,"OfflineTraceFileSize")==0)
359 daemon_local->flags.offlineTraceFileSize = atoi(value);
360 //printf("Option: %s=%s\n",token,value);
362 else if(strcmp(token,"OfflineTraceMaxSize")==0)
364 daemon_local->flags.offlineTraceMaxSize = atoi(value);
365 //printf("Option: %s=%s\n",token,value);
367 else if(strcmp(token,"SendECUSoftwareVersion")==0)
369 daemon_local->flags.sendECUSoftwareVersion = atoi(value);
370 //printf("Option: %s=%s\n",token,value);
372 else if(strcmp(token,"PathToECUSoftwareVersion")==0)
374 strncpy(daemon_local->flags.pathToECUSoftwareVersion,value,sizeof(daemon_local->flags.pathToECUSoftwareVersion) - 1);
375 //printf("Option: %s=%s\n",token,value);
380 fprintf(stderr, "Unknown option: %s=%s\n",token,value);
393 fprintf(stderr, "Cannot open configuration file: %s\n",filename);
400 * Main function of tool.
402 int main(int argc, char* argv[])
404 char version[DLT_DAEMON_TEXTBUFSIZE];
405 DltDaemonLocal daemon_local;
409 #if defined(DLT_SYSTEMD_WATCHDOG_ENABLE)
410 /* Timeout for select */
411 struct timeval tvTimeout;
412 tvTimeout.tv_sec = 0;
413 tvTimeout.tv_usec = DLT_SELECT_TIMEOUT_USEC;
415 /* Set watchdog flag immediately, not to timeout while init */
416 if(sd_notify(0, "WATCHDOG=1") < 0)
418 fprintf (stderr, "Could not initialize systemd watchdog\n");
422 /* Command line option handling */
423 if ((back = option_handling(&daemon_local,argc,argv))<0)
426 fprintf (stderr, "option_handling() failed!\n");
431 /* Configuration file option handling */
432 if ((back = option_file_parser(&daemon_local))<0)
435 fprintf (stderr, "option_file_parser() failed!\n");
440 /* Initialize internal logging facility */
441 dlt_log_set_filename(daemon_local.flags.loggingFilename);
442 dlt_log_set_level(daemon_local.flags.loggingLevel);
443 dlt_log_init(daemon_local.flags.loggingMode);
445 /* Print version information */
446 dlt_get_version(version);
448 sprintf(str,"Starting DLT Daemon; %s\n", version );
449 dlt_log(LOG_NOTICE, str);
451 PRINT_FUNCTION_VERBOSE(daemon_local.flags.vflag);
453 /* --- Daemon init phase 1 begin --- */
454 if (dlt_daemon_local_init_p1(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
456 dlt_log(LOG_CRIT,"Initialization of phase 1 failed!\n");
459 /* --- Daemon init phase 1 end --- */
461 /* --- Daemon connection init begin */
462 if (dlt_daemon_local_connection_init(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
464 dlt_log(LOG_CRIT,"Initialization of local connections failed!\n");
467 /* --- Daemon connection init end */
469 /* --- Daemon init phase 2 begin --- */
470 if (dlt_daemon_local_init_p2(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
472 dlt_log(LOG_CRIT,"Initialization of phase 2 failed!\n");
475 /* --- Daemon init phase 2 end --- */
479 #if defined(DLT_SYSTEMD_WATCHDOG_ENABLE)
480 /* Set timeout to defined usecs
481 * select might modify this value: POSIX.1-2001 */
482 tvTimeout.tv_sec = 0;
483 tvTimeout.tv_usec = DLT_SELECT_TIMEOUT_USEC;
485 /* update the watchdog time structure */
486 daemon_local.lastOperationTime = dlt_uptime();
488 /* wait for events from all FIFO and sockets, with timeout */
489 daemon_local.read_fds = daemon_local.master;
490 int selectRet = select(daemon_local.fdmax+1, &(daemon_local.read_fds), NULL, NULL, &tvTimeout);
493 dlt_log(LOG_CRIT, "select() failed!\n");
496 else if(selectRet == 0)
498 /* No pending reads, continue while(1)*/
503 /* wait for events from all FIFO and sockets */
504 daemon_local.read_fds = daemon_local.master;
505 if (select(daemon_local.fdmax+1, &(daemon_local.read_fds), NULL, NULL, NULL) == -1)
507 dlt_log(LOG_CRIT, "select() failed!\n");
511 /* run through the existing FIFO and sockets to check for events */
512 for (i = 0; i <= daemon_local.fdmax; i++)
514 if (FD_ISSET(i, &(daemon_local.read_fds)))
516 if (i == daemon_local.sock && ((daemon.mode == DLT_USER_MODE_EXTERNAL) || (daemon.mode == DLT_USER_MODE_BOTH)))
518 /* event from TCP server socket, new connection */
519 if (dlt_daemon_process_client_connect(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
521 dlt_log(LOG_CRIT,"Connect to dlt client failed!\n");
525 else if (i == daemon_local.fp)
527 /* event from the FIFO happened */
528 if (dlt_daemon_process_user_messages(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
530 dlt_log(LOG_CRIT,"Processing of messages from user connection failed!\n");
534 else if ((i == daemon_local.fdserial) && (daemon_local.flags.yvalue[0]))
536 /* event from serial connection to client received */
537 if (dlt_daemon_process_client_messages_serial(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
539 dlt_log(LOG_CRIT,"Processing of messages from serial connection failed!\n");
545 /* event from tcp connection to client received */
546 daemon_local.receiverSock.fd = i;
547 if (dlt_daemon_process_client_messages(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
549 dlt_log(LOG_CRIT,"Processing of messages from client connection failed!\n");
557 dlt_daemon_local_cleanup(&daemon, &daemon_local, daemon_local.flags.vflag);
559 dlt_log(LOG_NOTICE, "Leaving DLT daemon\n");
565 int dlt_daemon_local_init_p1(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
567 #if defined(DLT_SYSTEMD_WATCHDOG_ENABLE) || defined(DLT_SYSTEMD_ENABLE)
572 PRINT_FUNCTION_VERBOSE(verbose);
574 if ((daemon==0) || (daemon_local==0))
576 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_local_init_p1()\n");
580 #if defined(DLT_SYSTEMD_WATCHDOG_ENABLE) || defined(DLT_SYSTEMD_ENABLE)
584 dlt_log(LOG_CRIT, "system not booted with systemd!\n");
589 dlt_log(LOG_CRIT, "sd_booted failed!\n");
594 dlt_log(LOG_INFO, "system booted with systemd\n");
600 /* Check for daemon mode */
601 if (daemon_local->flags.dflag)
603 dlt_daemon_daemonize(daemon_local->flags.vflag);
606 /* initialise structure to use DLT file */
607 if (dlt_file_init(&(daemon_local->file),daemon_local->flags.vflag)==-1)
609 dlt_log(LOG_ERR,"Could not initialize file structure\n");
610 /* Return value ignored, dlt daemon will exit */
611 dlt_file_free(&(daemon_local->file),daemon_local->flags.vflag);
615 signal(SIGPIPE,SIG_IGN);
617 signal(SIGTERM, dlt_daemon_signal_handler); /* software termination signal from kill */
618 signal(SIGHUP, dlt_daemon_signal_handler); /* hangup signal */
619 signal(SIGQUIT, dlt_daemon_signal_handler);
620 signal(SIGINT, dlt_daemon_signal_handler);
625 int dlt_daemon_local_init_p2(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
627 PRINT_FUNCTION_VERBOSE(verbose);
629 if ((daemon==0) || (daemon_local==0))
631 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_local_init_p2()\n");
636 if (dlt_daemon_init(daemon,daemon_local->flags.ivalue,daemon_local->flags.vflag)==-1)
638 dlt_log(LOG_ERR,"Could not initialize daemon data\n");
642 /* init offline trace */
643 if(((daemon->mode == DLT_USER_MODE_INTERNAL) || (daemon->mode == DLT_USER_MODE_BOTH)) && daemon_local->flags.offlineTraceDirectory[0])
645 if (dlt_offline_trace_init(&(daemon_local->offlineTrace),daemon_local->flags.offlineTraceDirectory,daemon_local->flags.offlineTraceFileSize,daemon_local->flags.offlineTraceMaxSize)==-1)
647 dlt_log(LOG_ERR,"Could not initialize offline trace\n");
652 /* Set ECU id of daemon */
653 if (daemon_local->flags.evalue[0])
655 dlt_set_id(daemon->ecuid,daemon_local->flags.evalue);
659 dlt_set_id(daemon->ecuid,DLT_DAEMON_ECU_ID);
662 /* Set flag for optional sending of serial header */
663 daemon->sendserialheader = daemon_local->flags.lflag;
665 #ifdef DLT_SHM_ENABLE
666 /* init shared memory */
667 if (dlt_shm_init_server(&(daemon_local->dlt_shm),DLT_SHM_KEY,daemon_local->flags.sharedMemorySize)==-1)
669 dlt_log(LOG_ERR,"Could not initialize shared memory\n");
674 /* prepare main loop */
675 if (dlt_message_init(&(daemon_local->msg),daemon_local->flags.vflag)==-1)
677 dlt_log(LOG_ERR,"Could not initialize message\n");
681 if (dlt_receiver_init(&(daemon_local->receiver),daemon_local->fp,DLT_DAEMON_RCVBUFSIZE)==-1)
683 dlt_log(LOG_ERR,"Could not initialize receiver\n");
686 if (dlt_receiver_init(&(daemon_local->receiverSock),daemon_local->sock,DLT_DAEMON_RCVBUFSIZESOCK)==-1)
688 dlt_log(LOG_ERR,"Could not initialize receiver for socket\n");
691 if (daemon_local->flags.yvalue[0])
693 if (dlt_receiver_init(&(daemon_local->receiverSerial),daemon_local->fdserial,DLT_DAEMON_RCVBUFSIZESERIAL)==-1)
695 dlt_log(LOG_ERR,"Could not initialize receiver for serial connection\n");
700 /* setup period thread for timing packets */
701 if (pthread_attr_init(&dlt_daemon_timingpacket_thread_attr)<0)
703 dlt_log(LOG_WARNING, "Initialization of default thread stack size failed!\n");
707 if (pthread_attr_setstacksize(&dlt_daemon_timingpacket_thread_attr,DLT_DAEMON_TIMINGPACKET_THREAD_STACKSIZE)<0)
709 dlt_log(LOG_WARNING, "Setting of default thread stack size failed!\n");
713 /* configure sending timing packets */
714 if (daemon_local->flags.sendMessageTime)
716 daemon->timingpackets = 1;
719 /* Binary semaphore for thread */
720 if (sem_init(&dlt_daemon_mutex, 0, 1)==-1)
722 dlt_log(LOG_ERR,"Could not initialize binary semaphore\n");
727 dlt_daemon_timingpacket_thread_data.daemon = daemon;
728 dlt_daemon_timingpacket_thread_data.daemon_local = daemon_local;
730 if (pthread_create(&(dlt_daemon_timingpacket_thread_handle),
731 &dlt_daemon_timingpacket_thread_attr,
732 (void *) &dlt_daemon_timingpacket_thread,
733 (void *)&dlt_daemon_timingpacket_thread_data)!=0)
735 dlt_log(LOG_ERR,"Could not initialize timing packet thread\n");
736 pthread_attr_destroy(&dlt_daemon_timingpacket_thread_attr);
740 pthread_attr_destroy(&dlt_daemon_timingpacket_thread_attr);
742 /* Get ECU version info from a file. If it fails, use dlt_version as fallback. */
743 if(dlt_daemon_local_ecu_version_init(daemon, daemon_local, daemon_local->flags.vflag) < 0)
745 daemon->ECUVersionString = malloc(DLT_DAEMON_TEXTBUFSIZE);
746 dlt_get_version(daemon->ECUVersionString);
749 /* start thread for ECU version, if enabled */
750 if(daemon_local->flags.sendECUSoftwareVersion > 0)
752 dlt_daemon_ecu_version_thread_data.daemon = daemon;
753 dlt_daemon_ecu_version_thread_data.daemon_local = daemon_local;
755 if (pthread_create(&(dlt_daemon_ecu_version_thread_handle),
757 (void *) &dlt_daemon_ecu_version_thread,
758 (void *)&dlt_daemon_ecu_version_thread_data)!=0)
760 dlt_log(LOG_ERR,"Could not initialize ECU version thread\n");
765 #if defined(DLT_SYSTEMD_WATCHDOG_ENABLE)
767 dlt_daemon_systemd_watchdog_thread_data.daemon = daemon;
768 dlt_daemon_systemd_watchdog_thread_data.daemon_local = daemon_local;
770 if (pthread_create(&(dlt_daemon_systemd_watchdog_thread_handle),
772 (void *) &dlt_daemon_systemd_watchdog_thread,
773 (void *) &dlt_daemon_systemd_watchdog_thread_data)!=0)
775 dlt_log(LOG_ERR,"Could not initialize systemd watchdog thread\n");
784 int dlt_daemon_local_connection_init(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
789 struct sockaddr_in servAddr;
790 unsigned int servPort = DLT_DAEMON_TCP_PORT;
792 PRINT_FUNCTION_VERBOSE(verbose);
794 if ((daemon==0) || (daemon_local==0))
796 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_local_connection_init()\n");
800 /* open named pipe(FIFO) to receive DLT messages from users */
803 /* Try to delete existing pipe, ignore result of unlink */
804 unlink(DLT_USER_FIFO);
806 ret=mkfifo(DLT_USER_FIFO, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH );
809 sprintf(str,"FIFO user %s cannot be created!\n",DLT_USER_FIFO);
810 dlt_log(LOG_ERR, str);
814 daemon_local->fp = open(DLT_USER_FIFO, O_RDWR);
815 if (daemon_local->fp==-1)
817 sprintf(str,"FIFO user %s cannot be opened!\n",DLT_USER_FIFO);
818 dlt_log(LOG_ERR, str);
822 /* create and open socket to receive incoming connections from client */
823 if ((daemon_local->sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
825 dlt_log(LOG_ERR, "socket() failed!\n");
829 if ( -1 == setsockopt(daemon_local->sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)))
831 sprintf(str,"Setsockopt error in dlt_daemon_local_connection_init: %s\n",strerror(errno));
832 dlt_log(LOG_ERR, str);
835 memset(&servAddr, 0, sizeof(servAddr));
836 servAddr.sin_family = AF_INET;
837 servAddr.sin_addr.s_addr = INADDR_ANY;
838 servAddr.sin_port = htons(servPort);
840 if (bind(daemon_local->sock, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0)
842 dlt_log(LOG_ERR, "bind() failed!\n");
846 if (daemon_local->flags.vflag)
848 dlt_log(LOG_INFO, "Bind succesfull\n");
851 if (listen(daemon_local->sock, 3) < 0)
853 dlt_log(LOG_ERR, "listen() failed!\n");
857 if (daemon_local->flags.vflag)
859 dlt_log(LOG_INFO, "Listen succesfull\n");
862 /* prepare usage of select(), add FIFO and receiving socket */
863 FD_ZERO(&(daemon_local->master));
864 FD_ZERO(&(daemon_local->read_fds));
865 FD_SET(daemon_local->sock, &(daemon_local->master));
867 daemon_local->fdmax = daemon_local->sock;
869 FD_SET(daemon_local->fp, &(daemon_local->master));
871 if (daemon_local->fp > daemon_local->fdmax)
873 daemon_local->fdmax = daemon_local->fp;
876 if (daemon_local->flags.yvalue[0])
878 /* create and open serial connection from/to client */
879 /* open serial connection */
880 daemon_local->fdserial=open(daemon_local->flags.yvalue,O_RDWR);
881 if (daemon_local->fdserial<0)
883 sprintf(str,"Failed to open serial device %s\n", daemon_local->flags.yvalue);
884 daemon_local->flags.yvalue[0] = 0;
885 dlt_log(LOG_ERR, str);
889 if (isatty(daemon_local->fdserial))
891 if (daemon_local->flags.bvalue[0])
893 daemon_local->baudrate = dlt_convert_serial_speed(atoi(daemon_local->flags.bvalue));
897 daemon_local->baudrate = dlt_convert_serial_speed(DLT_DAEMON_SERIAL_DEFAULT_BAUDRATE);
900 if (dlt_setup_serial(daemon_local->fdserial,daemon_local->baudrate)<0)
902 close(daemon_local->fdserial);
903 sprintf(str,"Failed to configure serial device %s (%s) \n", daemon_local->flags.yvalue, strerror(errno));
904 daemon_local->flags.yvalue[0] = 0;
905 dlt_log(LOG_ERR, str);
909 FD_SET(daemon_local->fdserial, &(daemon_local->master));
911 if (daemon_local->fdserial > daemon_local->fdmax)
913 daemon_local->fdmax = daemon_local->fdserial;
916 if (daemon_local->flags.vflag)
918 dlt_log(LOG_INFO, "Serial init done\n");
923 close(daemon_local->fdserial);
924 fprintf(stderr,"Device is not a serial device, device = %s (%s) \n", daemon_local->flags.yvalue, strerror(errno));
925 daemon_local->flags.yvalue[0] = 0;
933 int dlt_daemon_local_ecu_version_init(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
935 char *version = NULL;
938 PRINT_FUNCTION_VERBOSE(verbose);
940 /* By default, version string is null. */
941 daemon->ECUVersionString = NULL;
943 /* Open the file. Bail out if error occurs */
944 f = fopen(daemon_local->flags.pathToECUSoftwareVersion, "r");
947 /* Error level notice, because this might be deliberate choice */
948 dlt_log(LOG_NOTICE, "Failed to open ECU Software version file.\n");
952 /* Get the file size. Bail out if stat fails. */
955 if(fstat(fd, &s_buf) < 0)
957 dlt_log(LOG_ERR, "Failed to stat ECU Software version file.\n");
962 /* Bail out if file is too large. Use DLT_DAEMON_TEXTBUFSIZE max.
963 * Reserve one byte for trailing '\0' */
964 off_t size = s_buf.st_size;
965 if(size >= DLT_DAEMON_TEXTBUFSIZE)
967 dlt_log(LOG_ERR, "Too large file for ECU version.\n");
972 /* Allocate permanent buffer for version info */
973 version = malloc(size + 1);
977 offset += fread(version + offset, 1, size, f);
980 dlt_log(LOG_ERR, "Failed to read ECU Software version file.\n");
987 dlt_log(LOG_ERR, "Too long file for ECU Software version info.\n");
993 version[offset] = '\0';//append null termination at end of version string
994 daemon->ECUVersionString = version;
999 void dlt_daemon_local_cleanup(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1001 PRINT_FUNCTION_VERBOSE(verbose);
1003 if ((daemon==0) || (daemon_local==0))
1005 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_local_cleanup()\n");
1010 dlt_receiver_free(&(daemon_local->receiver));
1012 dlt_receiver_free(&(daemon_local->receiverSock));
1015 dlt_message_free(&(daemon_local->msg),daemon_local->flags.vflag);
1016 close(daemon_local->fp);
1018 /* free shared memory */
1019 if(daemon_local->flags.offlineTraceDirectory[0])
1020 dlt_offline_trace_free(&(daemon_local->offlineTrace));
1022 if (daemon_local->flags.ovalue[0])
1024 close(daemon_local->ohandle);
1029 dlt_file_free(&(daemon_local->file),daemon_local->flags.vflag);
1031 /* Try to delete existing pipe, ignore result of unlink() */
1032 unlink(DLT_USER_FIFO);
1034 #ifdef DLT_SHM_ENABLE
1035 /* free shared memory */
1036 dlt_shm_free_server(&(daemon_local->dlt_shm));
1039 /* Try to delete lock file, ignore result of unlink() */
1040 unlink(DLT_DAEMON_LOCK_FILE);
1043 void dlt_daemon_signal_handler(int sig)
1052 /* finalize the server */
1053 //dlt_log("terminate signal catched");
1054 dlt_log(LOG_NOTICE, "Exiting DLT daemon\n");
1056 /* Try to delete existing pipe, ignore result of unlink() */
1057 unlink(DLT_USER_FIFO);
1059 /* Try to delete lock file, ignore result of unlink() */
1060 unlink(DLT_DAEMON_LOCK_FILE);
1062 /* Terminate program */
1068 /* This case should never occur */
1072 } /* dlt_daemon_signal_handler() */
1074 void dlt_daemon_daemonize(int verbose)
1079 PRINT_FUNCTION_VERBOSE(verbose);
1081 dlt_log(LOG_NOTICE, "Daemon mode\n");
1087 dlt_log(LOG_CRIT, "Unable to fork(), exiting DLT daemon\n");
1088 exit(-1); /* fork error */
1093 exit(0); /* parent exits */
1095 /* child (daemon) continues */
1097 /* Process independency */
1099 /* obtain a new process group */
1102 dlt_log(LOG_CRIT, "setsid() failed, exiting DLT daemon\n");
1103 exit(-1); /* fork error */
1106 /* Close descriptors */
1107 for (i=getdtablesize();i>=0;--i)
1109 close(i); /* close all descriptors */
1112 /* Open standard descriptors stdin, stdout, stderr */
1113 i=open("/dev/null",O_RDWR); /* open stdin */
1117 dlt_log(LOG_ERR, "Failed to direct stdout to /dev/null.\n");/* stdout */
1119 dlt_log(LOG_ERR, "Failed to direct stderr to /dev/null.\n"); /* stderr */
1123 umask(DLT_DAEMON_UMASK);
1125 /* Change to known directory */
1126 if(chdir(DLT_USER_DIR) < 0)
1127 dlt_log(LOG_ERR, "Failed to chdir to DLT_USER_DIR.\n");;
1129 /* Ensure single copy of daemon;
1130 run only one instance at a time */
1131 lfp=open(DLT_DAEMON_LOCK_FILE,O_RDWR|O_CREAT,DLT_DAEMON_LOCK_FILE_PERM);
1134 dlt_log(LOG_CRIT, "can't open lock file, exiting DLT daemon\n");
1135 exit(-1); /* can not open */
1137 if (lockf(lfp,F_TLOCK,0)<0)
1139 dlt_log(LOG_CRIT, "can't lock lock file, exiting DLT daemon\n");
1140 exit(-1); /* can not lock */
1142 /* only first instance continues */
1144 sprintf(str,"%d\n",getpid());
1145 pid_len = strlen(str);
1146 if(write(lfp,str,pid_len) != pid_len) /* record pid to lockfile */
1147 dlt_log(LOG_ERR, "Could not write pid to file in dlt_daemon_daemonize.\n");
1150 signal(SIGCHLD,SIG_IGN); /* ignore child */
1151 signal(SIGTSTP,SIG_IGN); /* ignore tty signals */
1152 signal(SIGTTOU,SIG_IGN);
1153 signal(SIGTTIN,SIG_IGN);
1155 } /* dlt_daemon_daemonize() */
1157 int dlt_daemon_process_client_connect(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1160 struct sockaddr cli;
1164 PRINT_FUNCTION_VERBOSE(verbose);
1166 if ((daemon==0) || (daemon_local==0))
1168 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_client_connect()\n");
1172 /* event from TCP server socket, new connection */
1173 cli_size = sizeof(cli);
1174 if ((in_sock = accept(daemon_local->sock,&cli, &cli_size)) < 0)
1176 dlt_log(LOG_ERR, "accept() failed!\n");
1180 /* check if file file descriptor was already used, and make it invalid if it is reused */
1181 /* This prevents sending messages to wrong file descriptor */
1182 dlt_daemon_applications_invalidate_fd(daemon,in_sock,verbose);
1183 dlt_daemon_contexts_invalidate_fd(daemon,in_sock,verbose);
1185 //sprintf("str,"Client Connection from %s\n", inet_ntoa(cli.sin_addr));
1187 FD_SET(in_sock, &(daemon_local->master)); /* add to master set */
1188 if (in_sock > daemon_local->fdmax)
1190 /* keep track of the maximum */
1191 daemon_local->fdmax = in_sock;
1194 daemon_local->client_connections++;
1195 if (daemon_local->flags.vflag)
1197 sprintf(str, "New connection to client established, #connections: %d\n",daemon_local->client_connections);
1198 dlt_log(LOG_INFO, str);
1201 if (daemon_local->client_connections==1)
1203 if (daemon_local->flags.vflag)
1205 dlt_log(LOG_INFO, "Send ring-buffer to client\n");
1207 if (dlt_daemon_send_ringbuffer_to_client(daemon, daemon_local, verbose)==-1)
1209 dlt_log(LOG_ERR,"Can't send contents of ringbuffer to clients\n");
1213 /* send new log state to all applications */
1215 dlt_daemon_user_send_all_log_state(daemon,verbose);
1221 int dlt_daemon_process_client_messages(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1223 int bytes_to_be_removed=0;
1225 PRINT_FUNCTION_VERBOSE(verbose);
1227 if ((daemon==0) || (daemon_local==0))
1229 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_client_messages()\n");
1233 if (dlt_receiver_receive_socket(&(daemon_local->receiverSock))<=0)
1235 close(daemon_local->receiverSock.fd);
1236 FD_CLR(daemon_local->receiverSock.fd, &(daemon_local->master));
1237 daemon_local->receiverSock.fd = -1;
1239 if (daemon_local->client_connections)
1241 daemon_local->client_connections--;
1244 if(daemon_local->client_connections==0)
1246 /* send new log state to all applications */
1248 dlt_daemon_user_send_all_log_state(daemon,verbose);
1251 if (daemon_local->flags.vflag)
1253 sprintf(str, "Connection to client lost, #connections: %d\n",daemon_local->client_connections);
1254 dlt_log(LOG_INFO, str);
1257 /* check: return 0; */
1260 /* Process all received messages */
1261 while (dlt_message_read(&(daemon_local->msg),(uint8_t*)daemon_local->receiverSock.buf,daemon_local->receiverSock.bytesRcvd,daemon_local->flags.nflag,daemon_local->flags.vflag)==0)
1263 /* Check for control message */
1264 if ( 0 < daemon_local->receiverSock.fd && DLT_MSG_IS_CONTROL_REQUEST(&(daemon_local->msg)) )
1266 dlt_daemon_control_process_control(daemon_local->receiverSock.fd, daemon, &(daemon_local->msg), daemon_local->flags.vflag);
1269 bytes_to_be_removed = daemon_local->msg.headersize+daemon_local->msg.datasize-sizeof(DltStorageHeader);
1270 if (daemon_local->msg.found_serialheader)
1272 bytes_to_be_removed += sizeof(dltSerialHeader);
1274 if (daemon_local->msg.resync_offset)
1276 bytes_to_be_removed += daemon_local->msg.resync_offset;
1279 if (dlt_receiver_remove(&(daemon_local->receiverSock),bytes_to_be_removed)==-1)
1281 dlt_log(LOG_ERR,"Can't remove bytes from receiver for sockets\n");
1288 if (dlt_receiver_move_to_begin(&(daemon_local->receiverSock))==-1)
1290 dlt_log(LOG_ERR,"Can't move bytes to beginning of receiver buffer for sockets\n");
1297 int dlt_daemon_process_client_messages_serial(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1299 int bytes_to_be_removed=0;
1301 PRINT_FUNCTION_VERBOSE(verbose);
1303 if ((daemon==0) || (daemon_local==0))
1305 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_client_messages_serial()\n");
1309 if (dlt_receiver_receive_fd(&(daemon_local->receiverSerial))<=0)
1311 dlt_log(LOG_ERR, "dlt_receiver_receive_fd() for messages from serial interface failed!\n");
1315 /* Process all received messages */
1316 while (dlt_message_read(&(daemon_local->msg),(uint8_t*)daemon_local->receiverSerial.buf,daemon_local->receiverSerial.bytesRcvd,daemon_local->flags.mflag,daemon_local->flags.vflag)==0)
1318 /* Check for control message */
1319 if (DLT_MSG_IS_CONTROL_REQUEST(&(daemon_local->msg)))
1321 if (dlt_daemon_control_process_control(daemon_local->receiverSerial.fd, daemon, &(daemon_local->msg), daemon_local->flags.vflag)==-1)
1323 dlt_log(LOG_ERR,"Can't process control messages\n");
1328 bytes_to_be_removed = daemon_local->msg.headersize+daemon_local->msg.datasize-sizeof(DltStorageHeader);
1329 if (daemon_local->msg.found_serialheader)
1331 bytes_to_be_removed += sizeof(dltSerialHeader);
1333 if (daemon_local->msg.resync_offset)
1335 bytes_to_be_removed += daemon_local->msg.resync_offset;
1338 if (dlt_receiver_remove(&(daemon_local->receiverSerial),bytes_to_be_removed)==-1)
1340 dlt_log(LOG_ERR,"Can't remove bytes from receiver for serial connection\n");
1347 if (dlt_receiver_move_to_begin(&(daemon_local->receiverSerial))==-1)
1349 dlt_log(LOG_ERR,"Can't move bytes to beginning of receiver buffer for serial connection\n");
1356 int dlt_daemon_process_user_messages(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1360 DltUserHeader *userheader;
1362 PRINT_FUNCTION_VERBOSE(verbose);
1364 if ((daemon==0) || (daemon_local==0))
1366 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_messages()\n");
1370 /* read data from FIFO */
1371 if (dlt_receiver_receive_fd(&(daemon_local->receiver))<0)
1373 dlt_log(LOG_ERR, "dlt_receiver_receive_fd() for user messages failed!\n");
1377 /* look through buffer as long as data is in there */
1380 if (daemon_local->receiver.bytesRcvd < (int32_t)sizeof(DltUserHeader))
1385 /* resync if necessary */
1389 userheader = (DltUserHeader*) (daemon_local->receiver.buf+offset);
1391 /* Check for user header pattern */
1392 if (dlt_user_check_userheader(userheader))
1400 while ((int32_t)(sizeof(DltUserHeader)+offset)<=daemon_local->receiver.bytesRcvd);
1402 /* Check for user header pattern */
1403 if (dlt_user_check_userheader(userheader)==0)
1408 /* Set new start offset */
1411 daemon_local->receiver.buf+=offset;
1412 daemon_local->receiver.bytesRcvd-=offset;
1415 switch (userheader->message)
1417 case DLT_USER_MESSAGE_OVERFLOW:
1419 if (dlt_daemon_process_user_message_overflow(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1425 case DLT_USER_MESSAGE_REGISTER_CONTEXT:
1427 if (dlt_daemon_process_user_message_register_context(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1433 case DLT_USER_MESSAGE_UNREGISTER_CONTEXT:
1435 if (dlt_daemon_process_user_message_unregister_context(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1441 case DLT_USER_MESSAGE_LOG:
1443 if (dlt_daemon_process_user_message_log(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1449 #ifdef DLT_SHM_ENABLE
1450 case DLT_USER_MESSAGE_LOG_SHM:
1452 if (dlt_daemon_process_user_message_log_shm(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1459 case DLT_USER_MESSAGE_REGISTER_APPLICATION:
1461 if (dlt_daemon_process_user_message_register_application(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1467 case DLT_USER_MESSAGE_UNREGISTER_APPLICATION:
1469 if (dlt_daemon_process_user_message_unregister_application(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1475 case DLT_USER_MESSAGE_APP_LL_TS:
1477 if (dlt_daemon_process_user_message_set_app_ll_ts(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1483 case DLT_USER_MESSAGE_LOG_MODE:
1485 if (dlt_daemon_process_user_message_log_mode(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1493 dlt_log(LOG_ERR,"(Internal) Invalid user message type received!\n");
1495 /* remove user header */
1496 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader))==-1)
1498 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user messages\n");
1502 /* In next invocation of do-while loop, a resync will be triggered if additional data was received */
1512 /* keep not read data in buffer */
1513 if (dlt_receiver_move_to_begin(&(daemon_local->receiver))==-1)
1515 dlt_log(LOG_ERR,"Can't move bytes to beginning of receiver buffer for user messages\n");
1522 int dlt_daemon_process_user_message_overflow(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1526 PRINT_FUNCTION_VERBOSE(verbose);
1528 if ((daemon==0) || (daemon_local==0))
1530 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_overflow()\n");
1534 /* Store in daemon, that a message buffer overflow has occured */
1535 daemon->message_buffer_overflow = DLT_MESSAGE_BUFFER_OVERFLOW;
1537 /* look if TCP connection to client is available */
1540 for (j = 0; j <= daemon_local->fdmax; j++)
1542 /* send to everyone! */
1543 if (FD_ISSET(j, &(daemon_local->master)))
1545 /* except the listener and ourselves */
1546 if ((j != daemon_local->fp) && (j != daemon_local->sock))
1548 dlt_daemon_control_message_buffer_overflow(j, daemon, verbose);
1550 /* Reset overflow state */
1551 daemon->message_buffer_overflow = DLT_MESSAGE_BUFFER_NO_OVERFLOW;
1556 /* message was not sent, so store it in ringbuffer */
1559 dlt_daemon_control_message_buffer_overflow(DLT_DAEMON_STORE_TO_BUFFER, daemon, verbose);
1562 /* keep not read data in buffer */
1563 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader))==-1)
1565 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message overflow\n");
1572 int dlt_daemon_process_user_message_register_application(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1575 DltDaemonApplication *application;
1576 char description[DLT_DAEMON_DESCSIZE];
1577 DltUserControlMsgRegisterApplication *usercontext;
1579 PRINT_FUNCTION_VERBOSE(verbose);
1581 if ((daemon==0) || (daemon_local==0))
1583 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_register_application()\n");
1587 if (daemon_local->receiver.bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterApplication)))
1589 /* Not enough bytes received */
1593 usercontext = (DltUserControlMsgRegisterApplication*) (daemon_local->receiver.buf+sizeof(DltUserHeader));
1595 memset(description,0,sizeof(description));
1597 len=usercontext->description_length;
1598 if ((len>0) && (len<=DLT_DAEMON_DESCSIZE))
1600 /* Read and store application description */
1601 strncpy(description, (daemon_local->receiver.buf+sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterApplication)), len);
1604 application=dlt_daemon_application_add(daemon,usercontext->apid,usercontext->pid,description,verbose);
1606 /* send log state to new application */
1607 dlt_daemon_user_send_log_state(daemon,application,verbose);
1609 /* keep not read data in buffer */
1610 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterApplication)+len)==-1)
1612 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register application\n");
1618 dlt_log(LOG_CRIT,"Can't add application");
1625 int dlt_daemon_process_user_message_register_context(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1628 int8_t loglevel, tracestatus;
1629 DltUserControlMsgRegisterContext *usercontext;
1630 char description[DLT_DAEMON_DESCSIZE];
1631 DltDaemonApplication *application;
1632 DltDaemonContext *context;
1633 DltServiceGetLogInfoRequest *req;
1639 PRINT_FUNCTION_VERBOSE(verbose);
1641 if ((daemon==0) || (daemon_local==0))
1643 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_register_context()\n");
1647 if (daemon_local->receiver.bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)))
1649 /* Not enough bytes received */
1653 usercontext = (DltUserControlMsgRegisterContext*) (daemon_local->receiver.buf+sizeof(DltUserHeader));
1655 memset(description,0,sizeof(description));
1657 len=usercontext->description_length;
1658 if ((len>0) && (len<=DLT_DAEMON_DESCSIZE))
1660 /* Read and store context description */
1661 strncpy(description, (daemon_local->receiver.buf+sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)), len);
1664 application = dlt_daemon_application_find(daemon,usercontext->apid,verbose);
1668 dlt_log(LOG_ERR, "Application not found in dlt_daemon_process_user_message_register_context()\n");
1669 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)+len)==-1)
1671 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register context\n");
1677 /* Pre-set loglevel */
1678 if (usercontext->log_level == DLT_USER_LOG_LEVEL_NOT_SET)
1680 loglevel=DLT_LOG_DEFAULT;
1684 loglevel=usercontext->log_level;
1685 /* Plausibility check */
1686 if ((loglevel<DLT_LOG_DEFAULT) || (loglevel>DLT_LOG_VERBOSE))
1688 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)+len)==-1)
1690 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register context\n");
1696 /* Pre-set tracestatus */
1697 if (usercontext->trace_status == DLT_USER_TRACE_STATUS_NOT_SET)
1699 tracestatus=DLT_TRACE_STATUS_DEFAULT;
1703 tracestatus=usercontext->trace_status;
1705 /* Plausibility check */
1706 if ((tracestatus<DLT_TRACE_STATUS_DEFAULT) || (tracestatus>DLT_TRACE_STATUS_ON))
1708 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)+len)==-1)
1710 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register context\n");
1716 context = dlt_daemon_context_add(daemon,usercontext->apid,usercontext->ctid, loglevel, tracestatus, usercontext->log_level_pos,application->user_handle,description,verbose);
1720 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)+len)==-1)
1722 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register context\n");
1725 dlt_log(LOG_CRIT,"Can't add context");
1728 /* Create automatic get log info response for registered context */
1729 if (daemon_local->flags.rflag)
1731 /* Prepare request for get log info with one application and one context */
1732 if (dlt_message_init(&msg, verbose)==-1)
1734 dlt_log(LOG_ERR,"Can't initialize message");
1738 msg.datasize = sizeof(DltServiceGetLogInfoRequest);
1739 if (msg.databuffer && (msg.databuffersize < msg.datasize))
1741 free(msg.databuffer);
1744 if (msg.databuffer == 0){
1745 msg.databuffer = (uint8_t *) malloc(msg.datasize);
1746 msg.databuffersize = msg.datasize;
1748 if (msg.databuffer==0)
1750 dlt_log(LOG_ERR,"Can't allocate buffer for get log info message\n");
1754 req = (DltServiceGetLogInfoRequest*) msg.databuffer;
1756 req->service_id = DLT_SERVICE_ID_GET_LOG_INFO;
1758 dlt_set_id(req->apid, usercontext->apid);
1759 dlt_set_id(req->ctid, usercontext->ctid);
1760 dlt_set_id(req->com,"remo");
1764 /* Send response to get log info request to DLT clients */
1765 for (j = 0; j <= daemon_local->fdmax; j++)
1767 /* send to everyone! */
1768 if (FD_ISSET(j, &(daemon_local->master)))
1770 /* except the listener and ourselves */
1771 if ((j != daemon_local->fp) && (j != daemon_local->sock))
1773 dlt_daemon_control_get_log_info(j , daemon, &msg, verbose);
1781 /* Store to buffer */
1782 dlt_daemon_control_get_log_info(DLT_DAEMON_STORE_TO_BUFFER , daemon, &msg, verbose);
1785 dlt_message_free(&msg, verbose);
1788 if (context->user_handle >= DLT_FD_MINIMUM)
1790 /* This call also replaces the default values with the values defined for default */
1791 if (dlt_daemon_user_send_log_level(daemon, context, verbose)==-1)
1793 dlt_log(LOG_ERR,"Can't send current log level as response to user message register context\n");
1798 /* keep not read data in buffer */
1799 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)+len)==-1)
1801 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register context\n");
1808 int dlt_daemon_process_user_message_unregister_application(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1810 DltUserControlMsgUnregisterApplication *usercontext;
1811 DltDaemonApplication *application;
1812 DltDaemonContext *context;
1815 PRINT_FUNCTION_VERBOSE(verbose);
1817 if ((daemon==0) || (daemon_local==0))
1819 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_unregister_application()\n");
1823 if (daemon_local->receiver.bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgUnregisterApplication)))
1825 /* Not enough bytes received */
1829 if (daemon->num_applications>0)
1831 usercontext = (DltUserControlMsgUnregisterApplication*) (daemon_local->receiver.buf+sizeof(DltUserHeader));
1833 /* Delete this application and all corresponding contexts for this application from internal table */
1834 application = dlt_daemon_application_find(daemon,usercontext->apid, verbose);
1838 /* Calculate start offset within contexts[] */
1840 for (i=0; i<(application-(daemon->applications)); i++)
1842 offset_base+=daemon->applications[i].num_contexts;
1845 for (i=application->num_contexts-1; i>=0; i--)
1847 context = &(daemon->contexts[offset_base+i]);
1850 /* Delete context */
1851 if (dlt_daemon_context_del(daemon, context, verbose)==-1)
1853 dlt_log(LOG_ERR,"Can't delete context for user message unregister application\n");
1859 /* Delete this application entry from internal table*/
1860 if (dlt_daemon_application_del(daemon, application, verbose)==-1)
1862 dlt_log(LOG_ERR,"Can't delete application for user message unregister application\n");
1868 /* keep not read data in buffer */
1869 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgUnregisterApplication))==-1)
1871 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message unregister application\n");
1878 int dlt_daemon_process_user_message_unregister_context(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1880 DltUserControlMsgUnregisterContext *usercontext;
1881 DltDaemonContext *context;
1883 PRINT_FUNCTION_VERBOSE(verbose);
1885 if ((daemon==0) || (daemon_local==0))
1887 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_unregister_context()\n");
1891 if (daemon_local->receiver.bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgUnregisterContext)))
1893 /* Not enough bytes received */
1897 usercontext = (DltUserControlMsgUnregisterContext*) (daemon_local->receiver.buf+sizeof(DltUserHeader));
1898 context = dlt_daemon_context_find(daemon,usercontext->apid, usercontext->ctid, verbose);
1902 /* Delete this connection entry from internal table*/
1903 if (dlt_daemon_context_del(daemon, context, verbose)==-1)
1905 dlt_log(LOG_ERR,"Can't delete context for user message unregister context\n");
1910 /* keep not read data in buffer */
1911 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgUnregisterContext))==-1)
1913 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message unregister context\n");
1920 int dlt_daemon_process_user_message_log(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1922 int bytes_to_be_removed;
1923 int j,sent,third_value;
1926 static char text[DLT_DAEMON_TEXTSIZE];
1928 PRINT_FUNCTION_VERBOSE(verbose);
1930 if ((daemon==0) || (daemon_local==0))
1932 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_log()\n");
1936 if (dlt_message_read(&(daemon_local->msg),(unsigned char*)daemon_local->receiver.buf+sizeof(DltUserHeader),daemon_local->receiver.bytesRcvd-sizeof(DltUserHeader),0,verbose)==0)
1938 /* set overwrite ecu id */
1939 if (daemon_local->flags.evalue!=0)
1941 /* Set header extra parameters */
1942 dlt_set_id(daemon_local->msg.headerextra.ecu, daemon->ecuid );
1943 //msg.headerextra.seid = 0;
1944 if (dlt_message_set_extraparameters(&(daemon_local->msg),0)==-1)
1946 dlt_log(LOG_ERR,"Can't set message extra parameters in process user message log\n");
1950 /* Correct value of timestamp, this was changed by dlt_message_set_extraparameters() */
1951 daemon_local->msg.headerextra.tmsp = DLT_BETOH_32(daemon_local->msg.headerextra.tmsp);
1954 /* prepare storage header */
1955 if (DLT_IS_HTYP_WEID(daemon_local->msg.standardheader->htyp))
1957 if (dlt_set_storageheader(daemon_local->msg.storageheader,daemon_local->msg.headerextra.ecu)==-1)
1959 dlt_log(LOG_ERR,"Can't set storage header in process user message log\n");
1965 if (dlt_set_storageheader(daemon_local->msg.storageheader,daemon->ecuid)==-1)
1967 dlt_log(LOG_ERR,"Can't set storage header in process user message log\n");
1973 /* if no filter set or filter is matching display message */
1974 if (daemon_local->flags.xflag)
1976 if (dlt_message_print_hex(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1)
1978 dlt_log(LOG_ERR,"dlt_message_print_hex() failed!\n");
1981 else if (daemon_local->flags.aflag)
1983 if (dlt_message_print_ascii(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1)
1985 dlt_log(LOG_ERR,"dlt_message_print_ascii() failed!\n");
1988 else if (daemon_local->flags.sflag)
1990 if (dlt_message_print_header(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1)
1992 dlt_log(LOG_ERR,"dlt_message_print_header() failed!\n");
1994 /* print message header only */
1999 /* write message to offline trace */
2000 if(((daemon->mode == DLT_USER_MODE_INTERNAL) || (daemon->mode == DLT_USER_MODE_BOTH)) && daemon_local->flags.offlineTraceDirectory[0])
2002 dlt_offline_trace_write(&(daemon_local->offlineTrace),daemon_local->msg.headerbuffer,daemon_local->msg.headersize,
2003 daemon_local->msg.databuffer,daemon_local->msg.datasize,0,0);
2007 /* look if TCP connection to client is available */
2008 for (j = 0;((daemon->mode == DLT_USER_MODE_EXTERNAL) || (daemon->mode == DLT_USER_MODE_BOTH)) && (j <= daemon_local->fdmax); j++)
2010 /* send to everyone! */
2011 if (FD_ISSET(j, &(daemon_local->master)))
2013 /* except the listener and ourselves */
2014 if (daemon_local->flags.yvalue[0])
2016 third_value = daemon_local->fdserial;
2020 third_value = daemon_local->sock;
2023 if ((j != daemon_local->fp) && (j != daemon_local->sock) && (j != third_value))
2025 DLT_DAEMON_SEM_LOCK();
2027 if (daemon_local->flags.lflag)
2029 send(j,dltSerialHeader,sizeof(dltSerialHeader),0);
2032 send(j,daemon_local->msg.headerbuffer+sizeof(DltStorageHeader),daemon_local->msg.headersize-sizeof(DltStorageHeader),0);
2033 send(j,daemon_local->msg.databuffer,daemon_local->msg.datasize,0);
2035 DLT_DAEMON_SEM_FREE();
2039 else if ((j == daemon_local->fdserial) && (daemon_local->flags.yvalue!=0))
2041 DLT_DAEMON_SEM_LOCK();
2043 if (daemon_local->flags.lflag)
2045 ret=write(j,dltSerialHeader,sizeof(dltSerialHeader));
2048 dlt_log(LOG_ERR,"write(j,dltSerialHeader failed\n");
2051 int32_t diff = daemon_local->msg.headersize-sizeof(DltStorageHeader);
2052 //extra calculation for coverity
2054 ret=write(j,daemon_local->msg.headerbuffer+sizeof(DltStorageHeader),diff);
2057 dlt_log(LOG_ERR,"write(j,daemon_local->msg.headerbuffer failed\n");
2059 ret=write(j,daemon_local->msg.databuffer,daemon_local->msg.datasize);
2062 dlt_log(LOG_ERR,"write(j,daemon_local->msg.databuffer failed\n");
2066 DLT_DAEMON_SEM_FREE();
2073 /* Message was not sent to client, so store it in client ringbuffer */
2076 DLT_DAEMON_SEM_LOCK();
2077 if (dlt_buffer_push3(&(daemon->client_ringbuffer),
2078 daemon_local->msg.headerbuffer+sizeof(DltStorageHeader),daemon_local->msg.headersize-sizeof(DltStorageHeader),
2079 daemon_local->msg.databuffer,daemon_local->msg.datasize,
2083 dlt_log(LOG_ERR,"Storage of message in history buffer failed! Message discarded.\n");
2085 DLT_DAEMON_SEM_FREE();
2089 /* keep not read data in buffer */
2090 bytes_to_be_removed = daemon_local->msg.headersize+daemon_local->msg.datasize-sizeof(DltStorageHeader)+sizeof(DltUserHeader);
2091 if (daemon_local->msg.found_serialheader)
2093 bytes_to_be_removed += sizeof(dltSerialHeader);
2096 if (dlt_receiver_remove(&(daemon_local->receiver),bytes_to_be_removed)==-1)
2098 dlt_log(LOG_ERR,"Can't remove bytes from receiver\n");
2104 dlt_log(LOG_ERR,"Can't read messages from receiver\n");
2111 #ifdef DLT_SHM_ENABLE
2112 int dlt_daemon_process_user_message_log_shm(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
2114 int bytes_to_be_removed=0;
2115 int j,sent,third_value;
2117 uint8_t rcv_buffer[10000];
2119 DltUserHeader *userheader;
2121 static char text[DLT_DAEMON_TEXTSIZE];
2123 PRINT_FUNCTION_VERBOSE(verbose);
2125 if ((daemon==0) || (daemon_local==0))
2127 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_log()\n");
2131 userheader = (DltUserHeader*) (daemon_local->receiver.buf);
2133 //dlt_shm_status(&(daemon_local->dlt_shm));
2136 /* log message in SHM */
2137 if((size = dlt_shm_copy(&(daemon_local->dlt_shm),rcv_buffer,10000)) <= 0)
2139 if (dlt_message_read(&(daemon_local->msg),rcv_buffer,size,0,verbose)!=0) {
2141 dlt_log(LOG_ERR,"Can't read messages from shm\n");
2144 bytes_to_be_removed = daemon_local->msg.headersize+daemon_local->msg.datasize-sizeof(DltStorageHeader)+sizeof(DltUserHeader);
2145 if (daemon_local->msg.found_serialheader)
2147 bytes_to_be_removed += sizeof(dltSerialHeader);
2150 /* set overwrite ecu id */
2151 if (daemon_local->flags.evalue[0])
2153 /* Set header extra parameters */
2154 dlt_set_id(daemon_local->msg.headerextra.ecu, daemon->ecuid );
2155 //msg.headerextra.seid = 0;
2156 if (dlt_message_set_extraparameters(&(daemon_local->msg),0)==-1)
2158 dlt_log(LOG_ERR,"Can't set message extra parameters in process user message log\n");
2159 dlt_shm_remove(&(daemon_local->dlt_shm));
2163 /* Correct value of timestamp, this was changed by dlt_message_set_extraparameters() */
2164 daemon_local->msg.headerextra.tmsp = DLT_BETOH_32(daemon_local->msg.headerextra.tmsp);
2167 /* prepare storage header */
2168 if (DLT_IS_HTYP_WEID(daemon_local->msg.standardheader->htyp))
2170 if (dlt_set_storageheader(daemon_local->msg.storageheader,daemon_local->msg.headerextra.ecu)==-1)
2172 dlt_log(LOG_ERR,"Can't set storage header in process user message log\n");
2173 dlt_shm_remove(&(daemon_local->dlt_shm));
2179 if (dlt_set_storageheader(daemon_local->msg.storageheader,daemon->ecuid)==-1)
2181 dlt_log(LOG_ERR,"Can't set storage header in process user message log\n");
2182 dlt_shm_remove(&(daemon_local->dlt_shm));
2187 /* display message */
2188 if (daemon_local->flags.xflag)
2190 if (dlt_message_print_hex(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1)
2192 dlt_log(LOG_ERR,"dlt_message_print_hex() failed!\n");
2195 else if (daemon_local->flags.aflag)
2197 if (dlt_message_print_ascii(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1)
2199 dlt_log(LOG_ERR,"dlt_message_print_ascii() failed!\n");
2202 else if (daemon_local->flags.sflag)
2204 if (dlt_message_print_header(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1)
2206 dlt_log(LOG_ERR,"dlt_message_print_header() failed!\n");
2208 /* print message header only */
2213 /* write message to offline trace */
2214 if(((daemon->mode == DLT_USER_MODE_INTERNAL) || (daemon->mode == DLT_USER_MODE_BOTH)) && daemon_local->flags.offlineTraceDirectory[0])
2216 dlt_offline_trace_write(&(daemon_local->offlineTrace),daemon_local->msg.headerbuffer,daemon_local->msg.headersize,
2217 daemon_local->msg.databuffer,daemon_local->msg.datasize,0,0);
2221 /* look if TCP connection to client is available */
2222 for (j = 0;((daemon->mode == DLT_USER_MODE_EXTERNAL) || (daemon->mode == DLT_USER_MODE_BOTH)) && (j <= daemon_local->fdmax); j++)
2224 /* send to everyone! */
2225 if (FD_ISSET(j, &(daemon_local->master)))
2227 /* except the listener and ourselves */
2228 if (daemon_local->flags.yvalue[0])
2230 third_value = daemon_local->fdserial;
2234 third_value = daemon_local->sock;
2237 if ((j != daemon_local->fp) && (j != daemon_local->sock) && (j != third_value))
2239 DLT_DAEMON_SEM_LOCK();
2241 if (daemon_local->flags.lflag)
2243 send(j,dltSerialHeader,sizeof(dltSerialHeader),0);
2246 send(j,daemon_local->msg.headerbuffer+sizeof(DltStorageHeader),daemon_local->msg.headersize-sizeof(DltStorageHeader),0);
2247 send(j,daemon_local->msg.databuffer,daemon_local->msg.datasize,0);
2249 DLT_DAEMON_SEM_FREE();
2253 else if ((j == daemon_local->fdserial) && (daemon_local->flags.yvalue[0]))
2255 DLT_DAEMON_SEM_LOCK();
2257 if (daemon_local->flags.lflag)
2259 ret=write(j,dltSerialHeader,sizeof(dltSerialHeader));
2262 ret=write(j,daemon_local->msg.headerbuffer+sizeof(DltStorageHeader),daemon_local->msg.headersize-sizeof(DltStorageHeader));
2263 ret=write(j,daemon_local->msg.databuffer,daemon_local->msg.datasize);
2265 DLT_DAEMON_SEM_FREE();
2272 /* Message was not sent to client, so store it in client ringbuffer */
2273 if (sent==1 || (daemon->mode == DLT_USER_MODE_OFF))
2275 if(userheader->message == DLT_USER_MESSAGE_LOG_SHM) {
2276 /* dlt message was sent, remove from buffer if log message from shm */
2277 dlt_shm_remove(&(daemon_local->dlt_shm));
2282 /* dlt message was not sent, keep in buffer */
2288 /* keep not read data in buffer */
2289 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader))==-1)
2291 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message overflow\n");
2299 int dlt_daemon_process_user_message_set_app_ll_ts(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
2301 DltUserControlMsgAppLogLevelTraceStatus *usercontext;
2302 DltDaemonApplication *application;
2303 DltDaemonContext *context;
2305 int8_t old_log_level, old_trace_status;
2307 PRINT_FUNCTION_VERBOSE(verbose);
2309 if ((daemon==0) || (daemon_local==0))
2311 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_set_app_ll_ts()\n");
2315 if (daemon_local->receiver.bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgAppLogLevelTraceStatus )))
2317 /* Not enough bytes receeived */
2321 if (daemon->num_applications>0)
2323 usercontext = (DltUserControlMsgAppLogLevelTraceStatus*) (daemon_local->receiver.buf+sizeof(DltUserHeader));
2325 /* Get all contexts with application id matching the received application id */
2326 application = dlt_daemon_application_find(daemon, usercontext->apid, verbose);
2329 /* Calculate start offset within contexts[] */
2331 for (i=0; i<(application-(daemon->applications)); i++)
2333 offset_base+=daemon->applications[i].num_contexts;
2336 for (i=0; i < application->num_contexts; i++)
2338 context = &(daemon->contexts[offset_base+i]);
2341 old_log_level = context->log_level;
2342 context->log_level = usercontext->log_level; /* No endianess conversion necessary*/
2344 old_trace_status = context->trace_status;
2345 context->trace_status = usercontext->trace_status; /* No endianess conversion necessary */
2347 /* The folowing function sends also the trace status */
2348 if (context->user_handle >= DLT_FD_MINIMUM && dlt_daemon_user_send_log_level(daemon, context, verbose)!=0)
2350 context->log_level = old_log_level;
2351 context->trace_status = old_trace_status;
2358 /* keep not read data in buffer */
2359 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgAppLogLevelTraceStatus))==-1)
2361 dlt_log(LOG_ERR,"Can't remove bytes from receiver\n");
2368 int dlt_daemon_process_user_message_log_mode(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
2370 DltUserControlMsgLogMode *logmode;
2372 PRINT_FUNCTION_VERBOSE(verbose);
2374 if ((daemon==0) || (daemon_local==0))
2376 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_log_mode()\n");
2380 if (daemon_local->receiver.bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgUnregisterContext)))
2382 /* Not enough bytes received */
2386 logmode = (DltUserControlMsgLogMode*) (daemon_local->receiver.buf+sizeof(DltUserHeader));
2388 /* set the new log mode */
2389 daemon->mode = logmode->log_mode;
2391 /* write configuration persistantly */
2392 dlt_daemon_configuration_save(daemon, daemon->runtime_configuration, verbose);
2394 /* keep not read data in buffer */
2395 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogMode))==-1)
2397 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message log mode\n");
2404 int dlt_daemon_send_ringbuffer_to_client(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
2406 static uint8_t data[DLT_DAEMON_RCVBUFSIZE];
2411 PRINT_FUNCTION_VERBOSE(verbose);
2413 if ((daemon==0) || (daemon_local==0))
2415 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_send_ringbuffer_to_client()\n");
2419 /* Attention: If the message can't be send at this time, it will be silently discarded. */
2420 while ((length = dlt_buffer_pull(&(daemon->client_ringbuffer), data, sizeof(data) )) > 0)
2422 /* look if TCP connection to client is available */
2423 for (j = 0; j <= daemon_local->fdmax; j++)
2425 /* send to everyone! */
2426 if (FD_ISSET(j, &(daemon_local->master)))
2428 /* except the listener and ourselves */
2429 if (daemon_local->flags.yvalue[0])
2431 third_value = daemon_local->fdserial;
2435 third_value = daemon_local->sock;
2438 if ((j != daemon_local->fp) && (j != daemon_local->sock) && (j != third_value))
2440 DLT_DAEMON_SEM_LOCK();
2442 if (daemon_local->flags.lflag)
2444 send(j,dltSerialHeader,sizeof(dltSerialHeader),0);
2446 send(j,data,length,0);
2448 DLT_DAEMON_SEM_FREE();
2451 else if ((j == daemon_local->fdserial) && (daemon_local->flags.yvalue[0]))
2453 DLT_DAEMON_SEM_LOCK();
2455 if (daemon_local->flags.lflag)
2457 ret=write(j,dltSerialHeader,sizeof(dltSerialHeader));
2460 dlt_log(LOG_ERR, "dlt_daemon_send_ringbuffer_to_client: write(j,dltSerialHeader,sizeof(dltSerialHeader)) failed!\n");
2461 DLT_DAEMON_SEM_FREE();
2465 ret=write(j,data,length);
2468 dlt_log(LOG_ERR, "dlt_daemon_send_ringbuffer_to_client: write(j,data,length) failed!\n");
2469 DLT_DAEMON_SEM_FREE();
2472 DLT_DAEMON_SEM_FREE();
2477 length = sizeof(data);
2483 void dlt_daemon_timingpacket_thread(void *ptr)
2485 DltDaemonPeriodicData info;
2488 DltDaemonTimingPacketThreadData *data;
2490 DltDaemonLocal *daemon_local;
2494 dlt_log(LOG_ERR, "No data pointer passed to timingpacket thread\n");
2498 data = (DltDaemonTimingPacketThreadData*)ptr;
2499 daemon = data->daemon;
2500 daemon_local = data->daemon_local;
2502 if ((daemon==0) || (daemon_local==0))
2504 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_timingpacket_thread()");
2508 if (dlt_daemon_make_periodic (1000000, &info, daemon_local->flags.vflag)<0)
2510 dlt_log(LOG_CRIT,"Can't initialize thread timer!\n");
2516 /* If enabled, send timing packets to all clients */
2517 if (daemon->timingpackets)
2519 for (j = 0; j <= daemon_local->fdmax; j++)
2521 /* send to everyone! */
2522 if (FD_ISSET(j, &(daemon_local->master)))
2524 /* except the listener and ourselves */
2525 if ((j != daemon_local->fp) && (j != daemon_local->sock))
2527 dlt_daemon_control_message_time(j, daemon, daemon_local->flags.vflag);
2532 /* Wait for next period */
2533 dlt_daemon_wait_period (&info, daemon_local->flags.vflag);
2537 void dlt_daemon_ecu_version_thread(void *ptr)
2539 DltDaemonECUVersionThreadData *data = (DltDaemonECUVersionThreadData *)ptr;
2540 DltDaemonPeriodicData info;
2541 const unsigned int DLT_ECU_VERSION_PERIOD_TIME = 1000000*60; // 60 Seconds
2543 if (dlt_daemon_make_periodic (DLT_ECU_VERSION_PERIOD_TIME, &info, data->daemon_local->flags.vflag)<0)
2545 dlt_log(LOG_CRIT,"Can't initialize thread timer!\n");
2552 for (i = 0; i <= data->daemon_local->fdmax; i++)
2554 /* send to everyone! */
2555 if (FD_ISSET(i, &(data->daemon_local->master)))
2557 /* except the listener and ourselves */
2558 if ((i != data->daemon_local->fp) && (i != data->daemon_local->sock))
2560 dlt_daemon_control_get_software_version(i, data->daemon, data->daemon_local->flags.vflag);
2564 dlt_daemon_wait_period (&info, data->daemon_local->flags.vflag);
2568 #if defined(DLT_SYSTEMD_WATCHDOG_ENABLE)
2569 void dlt_daemon_systemd_watchdog_thread(void *ptr)
2572 int watchdogTimeoutSeconds;
2573 int notifyPeriodNSec;
2574 DltDaemonPeriodicData info;
2575 DltDaemonTimingPacketThreadData *data;
2577 DltDaemonLocal *daemon_local;
2578 static uint32_t lastDaemonOperation;
2582 dlt_log(LOG_ERR, "No data pointer passed to systemd watchdog thread\n");
2586 data = (DltDaemonTimingPacketThreadData*)ptr;
2587 daemon = data->daemon;
2588 daemon_local = data->daemon_local;
2590 if ((daemon==0) || (daemon_local==0))
2592 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_timingpacket_thread()");
2596 watchdogUSec = getenv("WATCHDOG_USEC");
2600 watchdogTimeoutSeconds = atoi(watchdogUSec);
2601 // Calculate half of WATCHDOG_USEC in ns for timer tick
2602 notifyPeriodNSec = watchdogTimeoutSeconds / 2 ;
2604 if( notifyPeriodNSec > 0 )
2606 sprintf(str,"systemd watchdog timeout: %i nsec - timer will be initialized: %i nsec\n", watchdogTimeoutSeconds, notifyPeriodNSec );
2607 dlt_log(LOG_INFO, str);
2609 if (dlt_daemon_make_periodic (notifyPeriodNSec, &info, daemon_local->flags.vflag)<0)
2611 dlt_log(LOG_CRIT, "Could not initialize systemd watchdog timer");
2617 /* If main thread has changed its last operation time, reset watchdog */
2618 if(daemon_local->lastOperationTime != lastDaemonOperation)
2620 if(sd_notify(0, "WATCHDOG=1") < 0)
2622 dlt_log(LOG_CRIT, "Could not reset systemd watchdog\n");
2624 lastDaemonOperation = daemon_local->lastOperationTime;
2627 /* Wait for next period */
2628 dlt_daemon_wait_period (&info, daemon_local->flags.vflag);
2633 sprintf(str,"systemd watchdog timeout incorrect: %i\n", watchdogTimeoutSeconds);
2634 dlt_log(LOG_CRIT, str);
2639 dlt_log(LOG_CRIT, "systemd watchdog timeout (WATCHDOG_USEC) is null!\n");
2644 int dlt_daemon_make_periodic (unsigned int period, DltDaemonPeriodicData *info, int verbose)
2650 struct itimerspec itval;
2652 PRINT_FUNCTION_VERBOSE(verbose);
2656 dlt_log(LOG_ERR,"No data pointer passed!\n");
2660 /* Create the timer */
2661 fd = timerfd_create (CLOCK_MONOTONIC, 0);
2663 info->wakeups_missed = 0;
2664 info->timer_fd = fd;
2668 dlt_log(LOG_ERR,"Can't create timer filedescriptor");
2672 /* Make the timer periodic */
2673 sec = period/1000000;
2674 ns = (period - (sec * 1000000)) * 1000;
2675 itval.it_interval.tv_sec = sec;
2676 itval.it_interval.tv_nsec = ns;
2677 itval.it_value.tv_sec = sec;
2678 itval.it_value.tv_nsec = ns;
2680 ret = timerfd_settime (fd, 0, &itval, NULL);
2685 void dlt_daemon_wait_period (DltDaemonPeriodicData *info, int verbose)
2687 unsigned long long missed;
2690 PRINT_FUNCTION_VERBOSE(verbose);
2692 ret = read (info->timer_fd, &missed, sizeof (missed));
2694 dlt_log(LOG_ERR,"dlt_daemon_wait_period: Read failed");
2699 info->wakeups_missed += (missed - 1);