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];
103 * Print usage information of tool.
107 char version[DLT_DAEMON_TEXTBUFSIZE];
108 dlt_get_version(version);
110 //printf("DLT logging daemon %s %s\n", _DLT_PACKAGE_VERSION, _DLT_PACKAGE_VERSION_STATE);
111 //printf("Compile options: %s %s %s %s",_DLT_SYSTEMD_ENABLE, _DLT_SYSTEMD_WATCHDOG_ENABLE, _DLT_TEST_ENABLE, _DLT_SHM_ENABLE);
112 printf("%s", version);
113 printf("Usage: dlt-daemon [options]\n");
114 printf("Options:\n");
115 printf(" -d Daemonize\n");
116 printf(" -h Usage\n");
117 printf(" -c filename DLT daemon configuration file (Default: /etc/dlt.conf)\n");
123 int option_handling(DltDaemonLocal *daemon_local,int argc, char* argv[])
129 fprintf (stderr, "Invalid parameter passed to option_handling()\n");
133 /* Initialize flags */
134 memset(daemon_local,0,sizeof(DltDaemonLocal));
138 while ((c = getopt (argc, argv, "hdc:")) != -1)
144 daemon_local->flags.dflag = 1;
149 strncpy(daemon_local->flags.cvalue,optarg,NAME_MAX);
155 return -2; /* return no error */
161 fprintf (stderr, "Option -%c requires an argument.\n", optopt);
163 else if (isprint (optopt))
165 fprintf (stderr, "Unknown option `-%c'.\n", optopt);
169 fprintf (stderr, "Unknown option character `\\x%x'.\n",optopt);
171 /* unknown or wrong option used, show usage information and terminate */
177 fprintf (stderr, "Invalid option, this should never occur!\n");
185 } /* option_handling() */
190 int option_file_parser(DltDaemonLocal *daemon_local)
193 int value_length = 1024;
194 char line[value_length-1];
195 char token[value_length];
196 char value[value_length];
198 const char *filename;
200 /* set default values for configuration */
201 daemon_local->flags.sharedMemorySize = DLT_SHM_SIZE;
202 daemon_local->flags.sendMessageTime = 0;
203 daemon_local->flags.offlineTraceDirectory[0] = 0;
204 daemon_local->flags.offlineTraceFileSize = 1000000;
205 daemon_local->flags.offlineTraceMaxSize = 0;
206 daemon_local->flags.loggingMode = 0;
207 daemon_local->flags.loggingLevel = 6;
208 strncpy(daemon_local->flags.loggingFilename, DLT_USER_DIR "/dlt.log",sizeof(daemon_local->flags.loggingFilename));
209 daemon_local->timeoutOnSend = 4;
210 daemon_local->flags.sendECUSoftwareVersion = 0;
211 memset(daemon_local->flags.pathToECUSoftwareVersion, 0, sizeof(daemon_local->flags.pathToECUSoftwareVersion));
213 /* open configuration file */
214 if(daemon_local->flags.cvalue[0])
215 filename = daemon_local->flags.cvalue;
217 filename = "/etc/dlt.conf";
218 //printf("Load configuration from file: %s\n",filename);
219 pFile = fopen (filename,"r");
225 /* fetch line from configuration file */
226 if ( fgets (line , value_length - 1 , pFile) != NULL )
228 pch = strtok (line," =\r\n");
234 if(strcmp(pch,"#")==0)
239 strncpy(token,pch,sizeof(token) - 1);
243 strncpy(value,pch,sizeof(value) - 1);
247 pch = strtok (NULL, " =\r\n");
250 if(token[0] && value[0])
252 /* parse arguments here */
253 if(strcmp(token,"Verbose")==0)
255 daemon_local->flags.vflag = atoi(value);
256 //printf("Option: %s=%s\n",token,value);
258 else if(strcmp(token,"PrintASCII")==0)
260 daemon_local->flags.aflag = atoi(value);
261 //printf("Option: %s=%s\n",token,value);
263 else if(strcmp(token,"PrintHex")==0)
265 daemon_local->flags.xflag = atoi(value);
266 //printf("Option: %s=%s\n",token,value);
268 else if(strcmp(token,"PrintHeadersOnly")==0)
270 daemon_local->flags.sflag = atoi(value);
271 //printf("Option: %s=%s\n",token,value);
273 else if(strcmp(token,"SendSerialHeader")==0)
275 daemon_local->flags.lflag = atoi(value);
276 //printf("Option: %s=%s\n",token,value);
278 else if(strcmp(token,"SendContextRegistration")==0)
280 daemon_local->flags.rflag = atoi(value);
281 //printf("Option: %s=%s\n",token,value);
283 else if(strcmp(token,"SendMessageTime")==0)
285 daemon_local->flags.sendMessageTime = atoi(value);
286 //printf("Option: %s=%s\n",token,value);
288 else if(strcmp(token,"RS232SyncSerialHeader")==0)
290 daemon_local->flags.mflag = atoi(value);
291 //printf("Option: %s=%s\n",token,value);
293 else if(strcmp(token,"TCPSyncSerialHeader")==0)
295 daemon_local->flags.nflag = atoi(value);
296 //printf("Option: %s=%s\n",token,value);
298 else if(strcmp(token,"RS232DeviceName")==0)
300 strncpy(daemon_local->flags.yvalue,value,NAME_MAX);
301 //printf("Option: %s=%s\n",token,value);
303 else if(strcmp(token,"RS232Baudrate")==0)
305 strncpy(daemon_local->flags.bvalue,value,NAME_MAX);
306 //printf("Option: %s=%s\n",token,value);
308 else if(strcmp(token,"ECUId")==0)
310 strncpy(daemon_local->flags.evalue,value,NAME_MAX);
311 //printf("Option: %s=%s\n",token,value);
313 else if(strcmp(token,"PersistanceStoragePath")==0)
315 strncpy(daemon_local->flags.ivalue,value,NAME_MAX);
316 //printf("Option: %s=%s\n",token,value);
318 else if(strcmp(token,"LoggingMode")==0)
320 daemon_local->flags.loggingMode = atoi(value);
321 //printf("Option: %s=%s\n",token,value);
323 else if(strcmp(token,"LoggingLevel")==0)
325 daemon_local->flags.loggingLevel = atoi(value);
326 //printf("Option: %s=%s\n",token,value);
328 else if(strcmp(token,"LoggingFilename")==0)
330 strncpy(daemon_local->flags.loggingFilename,value,sizeof(daemon_local->flags.loggingFilename) - 1);
331 //printf("Option: %s=%s\n",token,value);
333 else if(strcmp(token,"TimeOutOnSend")==0)
335 daemon_local->timeoutOnSend = atoi(value);
336 //printf("Option: %s=%s\n",token,value);
338 else if(strcmp(token,"SharedMemorySize")==0)
340 daemon_local->flags.sharedMemorySize = atoi(value);
341 //printf("Option: %s=%s\n",token,value);
343 else if(strcmp(token,"OfflineTraceDirectory")==0)
345 strncpy(daemon_local->flags.offlineTraceDirectory,value,sizeof(daemon_local->flags.offlineTraceDirectory) - 1);
346 //printf("Option: %s=%s\n",token,value);
348 else if(strcmp(token,"OfflineTraceFileSize")==0)
350 daemon_local->flags.offlineTraceFileSize = atoi(value);
351 //printf("Option: %s=%s\n",token,value);
353 else if(strcmp(token,"OfflineTraceMaxSize")==0)
355 daemon_local->flags.offlineTraceMaxSize = atoi(value);
356 //printf("Option: %s=%s\n",token,value);
358 else if(strcmp(token,"SendECUSoftwareVersion")==0)
360 daemon_local->flags.sendECUSoftwareVersion = atoi(value);
361 //printf("Option: %s=%s\n",token,value);
363 else if(strcmp(token,"PathToECUSoftwareVersion")==0)
365 strncpy(daemon_local->flags.pathToECUSoftwareVersion,value,sizeof(daemon_local->flags.pathToECUSoftwareVersion) - 1);
366 //printf("Option: %s=%s\n",token,value);
371 fprintf(stderr, "Unknown option: %s=%s\n",token,value);
384 fprintf(stderr, "Cannot open configuration file: %s\n",filename);
391 * Main function of tool.
393 int main(int argc, char* argv[])
395 char version[DLT_DAEMON_TEXTBUFSIZE];
396 DltDaemonLocal daemon_local;
400 /* Command line option handling */
401 if ((back = option_handling(&daemon_local,argc,argv))<0)
404 fprintf (stderr, "option_handling() failed!\n");
409 /* Configuration file option handling */
410 if ((back = option_file_parser(&daemon_local))<0)
413 fprintf (stderr, "option_file_parser() failed!\n");
418 /* Initialize internal logging facility */
419 dlt_log_set_filename(daemon_local.flags.loggingFilename);
420 dlt_log_set_level(daemon_local.flags.loggingLevel);
421 dlt_log_init(daemon_local.flags.loggingMode);
423 /* Print version information */
424 dlt_get_version(version);
426 sprintf(str,"Starting DLT Daemon; %s\n", version );
427 dlt_log(LOG_NOTICE, str);
429 PRINT_FUNCTION_VERBOSE(daemon_local.flags.vflag);
431 /* --- Daemon init phase 1 begin --- */
432 if (dlt_daemon_local_init_p1(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
434 dlt_log(LOG_CRIT,"Initialization of phase 1 failed!\n");
437 /* --- Daemon init phase 1 end --- */
439 /* --- Daemon connection init begin */
440 if (dlt_daemon_local_connection_init(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
442 dlt_log(LOG_CRIT,"Initialization of local connections failed!\n");
445 /* --- Daemon connection init end */
447 /* --- Daemon init phase 2 begin --- */
448 if (dlt_daemon_local_init_p2(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
450 dlt_log(LOG_CRIT,"Initialization of phase 2 failed!\n");
453 /* --- Daemon init phase 2 end --- */
455 // create fd for watchdog
456 #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE
458 char* watchdogUSec = getenv("WATCHDOG_USEC");
459 int watchdogTimeoutSeconds = 0;
461 dlt_log(LOG_DEBUG, "Systemd watchdog initialization\n");
464 watchdogTimeoutSeconds = atoi(watchdogUSec)/2000000;
466 create_timer_fd(&daemon_local, watchdogTimeoutSeconds, watchdogTimeoutSeconds, &daemon_local.timer_wd, "Systemd watchdog");
470 // create fd for timer timing packets
471 create_timer_fd(&daemon_local, 1, 1, &daemon_local.timer_timingpacket, "Timing packet");
473 // create fd for timer ecu version
474 if(daemon_local.flags.sendECUSoftwareVersion > 0)
476 //dlt_daemon_init_ecuversion(&daemon_local);
477 create_timer_fd(&daemon_local, 60, 60, &daemon_local.timer_ecuversion, "ECU version");
483 /* wait for events from all FIFO and sockets */
484 daemon_local.read_fds = daemon_local.master;
485 if (select(daemon_local.fdmax+1, &(daemon_local.read_fds), NULL, NULL, NULL) == -1)
487 dlt_log(LOG_CRIT, "select() failed!\n");
491 /* run through the existing FIFO and sockets to check for events */
492 for (i = 0; i <= daemon_local.fdmax; i++)
494 if (FD_ISSET(i, &(daemon_local.read_fds)))
496 if (i == daemon_local.sock && ((daemon.mode == DLT_USER_MODE_EXTERNAL) || (daemon.mode == DLT_USER_MODE_BOTH)))
498 /* event from TCP server socket, new connection */
499 if (dlt_daemon_process_client_connect(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
501 dlt_log(LOG_CRIT,"Connect to dlt client failed!\n");
505 else if (i == daemon_local.fp)
507 /* event from the FIFO happened */
508 if (dlt_daemon_process_user_messages(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
510 dlt_log(LOG_CRIT,"Processing of messages from user connection failed!\n");
514 else if ((i == daemon_local.fdserial) && (daemon_local.flags.yvalue[0]))
516 /* event from serial connection to client received */
517 if (dlt_daemon_process_client_messages_serial(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
519 dlt_log(LOG_CRIT,"Processing of messages from serial connection failed!\n");
523 #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE
524 else if (i == daemon_local.timer_wd)
527 ssize_t res = read(daemon_local.timer_wd, &expir, sizeof(expir));
529 sprintf(str,"Failed to read timer_wd; %s\n", strerror(errno) );
530 dlt_log(LOG_WARNING, str);
531 // Activity received on timer_wd, but unable to read the fd:
532 // let's go on sending notification
535 dlt_log(LOG_DEBUG, "Timer watchdog\n");
537 if(sd_notify(0, "WATCHDOG=1") < 0)
539 dlt_log(LOG_CRIT, "Could not reset systemd watchdog\n");
543 else if (i == daemon_local.timer_timingpacket)
546 ssize_t res = read(daemon_local.timer_timingpacket, &expir, sizeof(expir));
548 sprintf(str,"Failed to read timer_timingpacket; %s\n", strerror(errno) );
549 dlt_log(LOG_WARNING, str);
550 // Activity received on timer_wd, but unable to read the fd:
551 // let's go on sending notification
553 dlt_daemon_send_timingpacket(&daemon, &daemon_local);
554 dlt_log(LOG_DEBUG, "Timer timingpacket\n");
558 else if (i == daemon_local.timer_ecuversion)
561 ssize_t res = read(daemon_local.timer_ecuversion, &expir, sizeof(expir));
563 sprintf(str,"Failed to read timer_ecuversion; %s\n", strerror(errno) );
564 dlt_log(LOG_WARNING, str);
565 // Activity received on timer_wd, but unable to read the fd:
566 // let's go on sending notification
568 dlt_daemon_send_ecuversion(&daemon, &daemon_local);
569 dlt_log(LOG_DEBUG, "Timer ecuversion\n");
574 /* event from tcp connection to client received */
575 daemon_local.receiverSock.fd = i;
576 if (dlt_daemon_process_client_messages(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
578 dlt_log(LOG_CRIT,"Processing of messages from client connection failed!\n");
586 dlt_daemon_local_cleanup(&daemon, &daemon_local, daemon_local.flags.vflag);
588 dlt_log(LOG_NOTICE, "Leaving DLT daemon\n");
594 int dlt_daemon_local_init_p1(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
596 #if defined(DLT_SYSTEMD_WATCHDOG_ENABLE) || defined(DLT_SYSTEMD_ENABLE)
601 PRINT_FUNCTION_VERBOSE(verbose);
603 if ((daemon==0) || (daemon_local==0))
605 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_local_init_p1()\n");
609 #if defined(DLT_SYSTEMD_WATCHDOG_ENABLE) || defined(DLT_SYSTEMD_ENABLE)
613 dlt_log(LOG_CRIT, "system not booted with systemd!\n");
618 dlt_log(LOG_CRIT, "sd_booted failed!\n");
623 dlt_log(LOG_INFO, "system booted with systemd\n");
629 /* Check for daemon mode */
630 if (daemon_local->flags.dflag)
632 dlt_daemon_daemonize(daemon_local->flags.vflag);
635 /* initialise structure to use DLT file */
636 if (dlt_file_init(&(daemon_local->file),daemon_local->flags.vflag)==-1)
638 dlt_log(LOG_ERR,"Could not initialize file structure\n");
639 /* Return value ignored, dlt daemon will exit */
640 dlt_file_free(&(daemon_local->file),daemon_local->flags.vflag);
644 signal(SIGPIPE,SIG_IGN);
646 signal(SIGTERM, dlt_daemon_signal_handler); /* software termination signal from kill */
647 signal(SIGHUP, dlt_daemon_signal_handler); /* hangup signal */
648 signal(SIGQUIT, dlt_daemon_signal_handler);
649 signal(SIGINT, dlt_daemon_signal_handler);
654 int dlt_daemon_local_init_p2(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
656 PRINT_FUNCTION_VERBOSE(verbose);
658 if ((daemon==0) || (daemon_local==0))
660 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_local_init_p2()\n");
665 if (dlt_daemon_init(daemon,daemon_local->flags.ivalue,daemon_local->flags.vflag)==-1)
667 dlt_log(LOG_ERR,"Could not initialize daemon data\n");
671 /* init offline trace */
672 if(((daemon->mode == DLT_USER_MODE_INTERNAL) || (daemon->mode == DLT_USER_MODE_BOTH)) && daemon_local->flags.offlineTraceDirectory[0])
674 if (dlt_offline_trace_init(&(daemon_local->offlineTrace),daemon_local->flags.offlineTraceDirectory,daemon_local->flags.offlineTraceFileSize,daemon_local->flags.offlineTraceMaxSize)==-1)
676 dlt_log(LOG_ERR,"Could not initialize offline trace\n");
681 /* Set ECU id of daemon */
682 if (daemon_local->flags.evalue[0])
684 dlt_set_id(daemon->ecuid,daemon_local->flags.evalue);
688 dlt_set_id(daemon->ecuid,DLT_DAEMON_ECU_ID);
691 /* Set flag for optional sending of serial header */
692 daemon->sendserialheader = daemon_local->flags.lflag;
694 #ifdef DLT_SHM_ENABLE
695 /* init shared memory */
696 if (dlt_shm_init_server(&(daemon_local->dlt_shm),DLT_SHM_KEY,daemon_local->flags.sharedMemorySize)==-1)
698 dlt_log(LOG_ERR,"Could not initialize shared memory\n");
703 /* prepare main loop */
704 if (dlt_message_init(&(daemon_local->msg),daemon_local->flags.vflag)==-1)
706 dlt_log(LOG_ERR,"Could not initialize message\n");
710 if (dlt_receiver_init(&(daemon_local->receiver),daemon_local->fp,DLT_DAEMON_RCVBUFSIZE)==-1)
712 dlt_log(LOG_ERR,"Could not initialize receiver\n");
715 if (dlt_receiver_init(&(daemon_local->receiverSock),daemon_local->sock,DLT_DAEMON_RCVBUFSIZESOCK)==-1)
717 dlt_log(LOG_ERR,"Could not initialize receiver for socket\n");
720 if (daemon_local->flags.yvalue[0])
722 if (dlt_receiver_init(&(daemon_local->receiverSerial),daemon_local->fdserial,DLT_DAEMON_RCVBUFSIZESERIAL)==-1)
724 dlt_log(LOG_ERR,"Could not initialize receiver for serial connection\n");
729 /* configure sending timing packets */
730 if (daemon_local->flags.sendMessageTime)
732 daemon->timingpackets = 1;
735 /* Binary semaphore for thread */
736 if (sem_init(&dlt_daemon_mutex, 0, 1)==-1)
738 dlt_log(LOG_ERR,"Could not initialize binary semaphore\n");
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);
752 int dlt_daemon_local_connection_init(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
757 struct sockaddr_in servAddr;
758 unsigned int servPort = DLT_DAEMON_TCP_PORT;
760 PRINT_FUNCTION_VERBOSE(verbose);
762 if ((daemon==0) || (daemon_local==0))
764 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_local_connection_init()\n");
768 /* open named pipe(FIFO) to receive DLT messages from users */
771 ret=mkdir(DLT_USER_DIR, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH | S_ISVTX );
772 if (ret==-1 && errno != EEXIST)
774 sprintf(str,"FIFO user dir %s cannot be created!\n", DLT_USER_DIR);
775 dlt_log(LOG_ERR, str);
779 // S_ISGID cannot be set by mkdir, let's reassign right bits
780 ret=chmod(DLT_USER_DIR, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH | S_ISGID | S_ISVTX );
783 sprintf(str,"FIFO user dir %s cannot be chmoded!\n", DLT_USER_DIR);
784 dlt_log(LOG_ERR, str);
788 /* Try to delete existing pipe, ignore result of unlink */
789 unlink(DLT_USER_FIFO);
791 ret=mkfifo(DLT_USER_FIFO, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP );
794 sprintf(str,"FIFO user %s cannot be created!\n",DLT_USER_FIFO);
795 dlt_log(LOG_ERR, str);
799 daemon_local->fp = open(DLT_USER_FIFO, O_RDWR);
800 if (daemon_local->fp==-1)
802 sprintf(str,"FIFO user %s cannot be opened!\n",DLT_USER_FIFO);
803 dlt_log(LOG_ERR, str);
807 /* create and open socket to receive incoming connections from client */
808 if ((daemon_local->sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
810 dlt_log(LOG_ERR, "socket() failed!\n");
814 if ( -1 == setsockopt(daemon_local->sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)))
816 sprintf(str,"Setsockopt error in dlt_daemon_local_connection_init: %s\n",strerror(errno));
817 dlt_log(LOG_ERR, str);
820 memset(&servAddr, 0, sizeof(servAddr));
821 servAddr.sin_family = AF_INET;
822 servAddr.sin_addr.s_addr = INADDR_ANY;
823 servAddr.sin_port = htons(servPort);
825 if (bind(daemon_local->sock, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0)
827 dlt_log(LOG_ERR, "bind() failed!\n");
831 if (daemon_local->flags.vflag)
833 dlt_log(LOG_INFO, "Bind succesfull\n");
836 if (listen(daemon_local->sock, 3) < 0)
838 dlt_log(LOG_ERR, "listen() failed!\n");
842 if (daemon_local->flags.vflag)
844 dlt_log(LOG_INFO, "Listen succesfull\n");
847 /* prepare usage of select(), add FIFO and receiving socket */
848 FD_ZERO(&(daemon_local->master));
849 FD_ZERO(&(daemon_local->read_fds));
850 FD_SET(daemon_local->sock, &(daemon_local->master));
852 daemon_local->fdmax = daemon_local->sock;
854 FD_SET(daemon_local->fp, &(daemon_local->master));
856 if (daemon_local->fp > daemon_local->fdmax)
858 daemon_local->fdmax = daemon_local->fp;
861 if (daemon_local->flags.yvalue[0])
863 /* create and open serial connection from/to client */
864 /* open serial connection */
865 daemon_local->fdserial=open(daemon_local->flags.yvalue,O_RDWR);
866 if (daemon_local->fdserial<0)
868 sprintf(str,"Failed to open serial device %s\n", daemon_local->flags.yvalue);
869 daemon_local->flags.yvalue[0] = 0;
870 dlt_log(LOG_ERR, str);
874 if (isatty(daemon_local->fdserial))
876 if (daemon_local->flags.bvalue[0])
878 daemon_local->baudrate = dlt_convert_serial_speed(atoi(daemon_local->flags.bvalue));
882 daemon_local->baudrate = dlt_convert_serial_speed(DLT_DAEMON_SERIAL_DEFAULT_BAUDRATE);
885 if (dlt_setup_serial(daemon_local->fdserial,daemon_local->baudrate)<0)
887 close(daemon_local->fdserial);
888 sprintf(str,"Failed to configure serial device %s (%s) \n", daemon_local->flags.yvalue, strerror(errno));
889 daemon_local->flags.yvalue[0] = 0;
890 dlt_log(LOG_ERR, str);
894 FD_SET(daemon_local->fdserial, &(daemon_local->master));
896 if (daemon_local->fdserial > daemon_local->fdmax)
898 daemon_local->fdmax = daemon_local->fdserial;
901 if (daemon_local->flags.vflag)
903 dlt_log(LOG_INFO, "Serial init done\n");
908 close(daemon_local->fdserial);
909 fprintf(stderr,"Device is not a serial device, device = %s (%s) \n", daemon_local->flags.yvalue, strerror(errno));
910 daemon_local->flags.yvalue[0] = 0;
918 int dlt_daemon_local_ecu_version_init(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
920 char *version = NULL;
923 PRINT_FUNCTION_VERBOSE(verbose);
925 /* By default, version string is null. */
926 daemon->ECUVersionString = NULL;
928 /* Open the file. Bail out if error occurs */
929 f = fopen(daemon_local->flags.pathToECUSoftwareVersion, "r");
932 /* Error level notice, because this might be deliberate choice */
933 dlt_log(LOG_NOTICE, "Failed to open ECU Software version file.\n");
937 /* Get the file size. Bail out if stat fails. */
940 if(fstat(fd, &s_buf) < 0)
942 dlt_log(LOG_ERR, "Failed to stat ECU Software version file.\n");
947 /* Bail out if file is too large. Use DLT_DAEMON_TEXTBUFSIZE max.
948 * Reserve one byte for trailing '\0' */
949 off_t size = s_buf.st_size;
950 if(size >= DLT_DAEMON_TEXTBUFSIZE)
952 dlt_log(LOG_ERR, "Too large file for ECU version.\n");
957 /* Allocate permanent buffer for version info */
958 version = malloc(size + 1);
962 offset += fread(version + offset, 1, size, f);
965 dlt_log(LOG_ERR, "Failed to read ECU Software version file.\n");
972 dlt_log(LOG_ERR, "Too long file for ECU Software version info.\n");
978 version[offset] = '\0';//append null termination at end of version string
979 daemon->ECUVersionString = version;
984 void dlt_daemon_local_cleanup(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
986 PRINT_FUNCTION_VERBOSE(verbose);
988 if ((daemon==0) || (daemon_local==0))
990 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_local_cleanup()\n");
995 dlt_receiver_free(&(daemon_local->receiver));
997 dlt_receiver_free(&(daemon_local->receiverSock));
1000 dlt_message_free(&(daemon_local->msg),daemon_local->flags.vflag);
1001 close(daemon_local->fp);
1003 /* free shared memory */
1004 if(daemon_local->flags.offlineTraceDirectory[0])
1005 dlt_offline_trace_free(&(daemon_local->offlineTrace));
1007 if (daemon_local->flags.ovalue[0])
1009 close(daemon_local->ohandle);
1014 dlt_file_free(&(daemon_local->file),daemon_local->flags.vflag);
1016 /* Try to delete existing pipe, ignore result of unlink() */
1017 unlink(DLT_USER_FIFO);
1019 #ifdef DLT_SHM_ENABLE
1020 /* free shared memory */
1021 dlt_shm_free_server(&(daemon_local->dlt_shm));
1024 /* Try to delete lock file, ignore result of unlink() */
1025 unlink(DLT_DAEMON_LOCK_FILE);
1028 void dlt_daemon_signal_handler(int sig)
1037 /* finalize the server */
1038 //dlt_log("terminate signal catched");
1039 dlt_log(LOG_NOTICE, "Exiting DLT daemon\n");
1041 /* Try to delete existing pipe, ignore result of unlink() */
1042 unlink(DLT_USER_FIFO);
1044 /* Try to delete lock file, ignore result of unlink() */
1045 unlink(DLT_DAEMON_LOCK_FILE);
1047 /* Terminate program */
1053 /* This case should never occur */
1057 } /* dlt_daemon_signal_handler() */
1059 void dlt_daemon_daemonize(int verbose)
1064 PRINT_FUNCTION_VERBOSE(verbose);
1066 dlt_log(LOG_NOTICE, "Daemon mode\n");
1072 dlt_log(LOG_CRIT, "Unable to fork(), exiting DLT daemon\n");
1073 exit(-1); /* fork error */
1078 exit(0); /* parent exits */
1080 /* child (daemon) continues */
1082 /* Process independency */
1084 /* obtain a new process group */
1087 dlt_log(LOG_CRIT, "setsid() failed, exiting DLT daemon\n");
1088 exit(-1); /* fork error */
1091 /* Close descriptors */
1092 for (i=getdtablesize();i>=0;--i)
1094 close(i); /* close all descriptors */
1097 /* Open standard descriptors stdin, stdout, stderr */
1098 i=open("/dev/null",O_RDWR); /* open stdin */
1102 dlt_log(LOG_ERR, "Failed to direct stdout to /dev/null.\n");/* stdout */
1104 dlt_log(LOG_ERR, "Failed to direct stderr to /dev/null.\n"); /* stderr */
1108 umask(DLT_DAEMON_UMASK);
1110 /* Change to known directory */
1111 if(chdir(DLT_USER_DIR) < 0)
1112 dlt_log(LOG_ERR, "Failed to chdir to DLT_USER_DIR.\n");;
1114 /* Ensure single copy of daemon;
1115 run only one instance at a time */
1116 lfp=open(DLT_DAEMON_LOCK_FILE,O_RDWR|O_CREAT,DLT_DAEMON_LOCK_FILE_PERM);
1119 dlt_log(LOG_CRIT, "can't open lock file, exiting DLT daemon\n");
1120 exit(-1); /* can not open */
1122 if (lockf(lfp,F_TLOCK,0)<0)
1124 dlt_log(LOG_CRIT, "can't lock lock file, exiting DLT daemon\n");
1125 exit(-1); /* can not lock */
1127 /* only first instance continues */
1129 sprintf(str,"%d\n",getpid());
1130 pid_len = strlen(str);
1131 if(write(lfp,str,pid_len) != pid_len) /* record pid to lockfile */
1132 dlt_log(LOG_ERR, "Could not write pid to file in dlt_daemon_daemonize.\n");
1135 signal(SIGCHLD,SIG_IGN); /* ignore child */
1136 signal(SIGTSTP,SIG_IGN); /* ignore tty signals */
1137 signal(SIGTTOU,SIG_IGN);
1138 signal(SIGTTIN,SIG_IGN);
1140 } /* dlt_daemon_daemonize() */
1142 int dlt_daemon_process_client_connect(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1145 struct sockaddr cli;
1149 PRINT_FUNCTION_VERBOSE(verbose);
1151 if ((daemon==0) || (daemon_local==0))
1153 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_client_connect()\n");
1157 /* event from TCP server socket, new connection */
1158 cli_size = sizeof(cli);
1159 if ((in_sock = accept(daemon_local->sock,&cli, &cli_size)) < 0)
1161 dlt_log(LOG_ERR, "accept() failed!\n");
1165 /* check if file file descriptor was already used, and make it invalid if it is reused */
1166 /* This prevents sending messages to wrong file descriptor */
1167 dlt_daemon_applications_invalidate_fd(daemon,in_sock,verbose);
1168 dlt_daemon_contexts_invalidate_fd(daemon,in_sock,verbose);
1170 /* Set socket timeout in reception */
1171 struct timeval timeout_send;
1172 timeout_send.tv_sec = daemon_local->timeoutOnSend;
1173 timeout_send.tv_usec = 0;
1174 if (setsockopt (in_sock, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout_send, sizeof(timeout_send)) < 0)
1175 dlt_log(LOG_ERR, "setsockopt failed\n");
1177 //sprintf("str,"Client Connection from %s\n", inet_ntoa(cli.sin_addr));
1179 FD_SET(in_sock, &(daemon_local->master)); /* add to master set */
1180 if (in_sock > daemon_local->fdmax)
1182 /* keep track of the maximum */
1183 daemon_local->fdmax = in_sock;
1186 daemon_local->client_connections++;
1187 if (daemon_local->flags.vflag)
1189 sprintf(str, "New connection to client established, #connections: %d\n",daemon_local->client_connections);
1190 dlt_log(LOG_INFO, str);
1193 // send connection info about connected
1194 dlt_daemon_control_message_connection_info(in_sock,daemon,DLT_CONNECTION_STATUS_CONNECTED,"",verbose);
1196 // send ecu version string
1197 if(daemon_local->flags.sendECUSoftwareVersion > 0)
1199 dlt_daemon_send_ecuversion(daemon,daemon_local);
1202 if (daemon_local->client_connections==1)
1204 if (daemon_local->flags.vflag)
1206 dlt_log(LOG_INFO, "Send ring-buffer to client\n");
1208 if (dlt_daemon_send_ringbuffer_to_client(daemon, daemon_local, verbose)==-1)
1210 dlt_log(LOG_ERR,"Can't send contents of ringbuffer to clients\n");
1214 /* send new log state to all applications */
1216 dlt_daemon_user_send_all_log_state(daemon,verbose);
1222 int dlt_daemon_process_client_messages(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1224 int bytes_to_be_removed=0;
1226 PRINT_FUNCTION_VERBOSE(verbose);
1228 if ((daemon==0) || (daemon_local==0))
1230 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_client_messages()\n");
1234 if (dlt_receiver_receive_socket(&(daemon_local->receiverSock))<=0)
1236 dlt_daemon_close_socket(daemon_local->receiverSock.fd, daemon, daemon_local, verbose);
1237 daemon_local->receiverSock.fd = -1;
1238 /* check: return 0; */
1241 /* Process all received messages */
1242 while (dlt_message_read(&(daemon_local->msg),(uint8_t*)daemon_local->receiverSock.buf,daemon_local->receiverSock.bytesRcvd,daemon_local->flags.nflag,daemon_local->flags.vflag)==0)
1244 /* Check for control message */
1245 if ( 0 < daemon_local->receiverSock.fd && DLT_MSG_IS_CONTROL_REQUEST(&(daemon_local->msg)) )
1247 dlt_daemon_control_process_control(daemon_local->receiverSock.fd, daemon, &(daemon_local->msg), daemon_local->flags.vflag);
1250 bytes_to_be_removed = daemon_local->msg.headersize+daemon_local->msg.datasize-sizeof(DltStorageHeader);
1251 if (daemon_local->msg.found_serialheader)
1253 bytes_to_be_removed += sizeof(dltSerialHeader);
1255 if (daemon_local->msg.resync_offset)
1257 bytes_to_be_removed += daemon_local->msg.resync_offset;
1260 if (dlt_receiver_remove(&(daemon_local->receiverSock),bytes_to_be_removed)==-1)
1262 dlt_log(LOG_ERR,"Can't remove bytes from receiver for sockets\n");
1269 if (dlt_receiver_move_to_begin(&(daemon_local->receiverSock))==-1)
1271 dlt_log(LOG_ERR,"Can't move bytes to beginning of receiver buffer for sockets\n");
1278 int dlt_daemon_process_client_messages_serial(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1280 int bytes_to_be_removed=0;
1282 PRINT_FUNCTION_VERBOSE(verbose);
1284 if ((daemon==0) || (daemon_local==0))
1286 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_client_messages_serial()\n");
1290 if (dlt_receiver_receive_fd(&(daemon_local->receiverSerial))<=0)
1292 dlt_log(LOG_ERR, "dlt_receiver_receive_fd() for messages from serial interface failed!\n");
1296 /* Process all received messages */
1297 while (dlt_message_read(&(daemon_local->msg),(uint8_t*)daemon_local->receiverSerial.buf,daemon_local->receiverSerial.bytesRcvd,daemon_local->flags.mflag,daemon_local->flags.vflag)==0)
1299 /* Check for control message */
1300 if (DLT_MSG_IS_CONTROL_REQUEST(&(daemon_local->msg)))
1302 if (dlt_daemon_control_process_control(daemon_local->receiverSerial.fd, daemon, &(daemon_local->msg), daemon_local->flags.vflag)==-1)
1304 dlt_log(LOG_ERR,"Can't process control messages\n");
1309 bytes_to_be_removed = daemon_local->msg.headersize+daemon_local->msg.datasize-sizeof(DltStorageHeader);
1310 if (daemon_local->msg.found_serialheader)
1312 bytes_to_be_removed += sizeof(dltSerialHeader);
1314 if (daemon_local->msg.resync_offset)
1316 bytes_to_be_removed += daemon_local->msg.resync_offset;
1319 if (dlt_receiver_remove(&(daemon_local->receiverSerial),bytes_to_be_removed)==-1)
1321 dlt_log(LOG_ERR,"Can't remove bytes from receiver for serial connection\n");
1328 if (dlt_receiver_move_to_begin(&(daemon_local->receiverSerial))==-1)
1330 dlt_log(LOG_ERR,"Can't move bytes to beginning of receiver buffer for serial connection\n");
1337 int dlt_daemon_process_user_messages(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1341 DltUserHeader *userheader;
1343 PRINT_FUNCTION_VERBOSE(verbose);
1345 if ((daemon==0) || (daemon_local==0))
1347 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_messages()\n");
1351 /* read data from FIFO */
1352 if (dlt_receiver_receive_fd(&(daemon_local->receiver))<0)
1354 dlt_log(LOG_ERR, "dlt_receiver_receive_fd() for user messages failed!\n");
1358 /* look through buffer as long as data is in there */
1361 if (daemon_local->receiver.bytesRcvd < (int32_t)sizeof(DltUserHeader))
1366 /* resync if necessary */
1370 userheader = (DltUserHeader*) (daemon_local->receiver.buf+offset);
1372 /* Check for user header pattern */
1373 if (dlt_user_check_userheader(userheader))
1381 while ((int32_t)(sizeof(DltUserHeader)+offset)<=daemon_local->receiver.bytesRcvd);
1383 /* Check for user header pattern */
1384 if (dlt_user_check_userheader(userheader)==0)
1389 /* Set new start offset */
1392 daemon_local->receiver.buf+=offset;
1393 daemon_local->receiver.bytesRcvd-=offset;
1396 switch (userheader->message)
1398 case DLT_USER_MESSAGE_OVERFLOW:
1400 if (dlt_daemon_process_user_message_overflow(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1406 case DLT_USER_MESSAGE_REGISTER_CONTEXT:
1408 if (dlt_daemon_process_user_message_register_context(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1414 case DLT_USER_MESSAGE_UNREGISTER_CONTEXT:
1416 if (dlt_daemon_process_user_message_unregister_context(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1422 case DLT_USER_MESSAGE_LOG:
1424 if (dlt_daemon_process_user_message_log(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1430 #ifdef DLT_SHM_ENABLE
1431 case DLT_USER_MESSAGE_LOG_SHM:
1433 if (dlt_daemon_process_user_message_log_shm(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1440 case DLT_USER_MESSAGE_REGISTER_APPLICATION:
1442 if (dlt_daemon_process_user_message_register_application(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1448 case DLT_USER_MESSAGE_UNREGISTER_APPLICATION:
1450 if (dlt_daemon_process_user_message_unregister_application(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1456 case DLT_USER_MESSAGE_APP_LL_TS:
1458 if (dlt_daemon_process_user_message_set_app_ll_ts(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1464 case DLT_USER_MESSAGE_LOG_MODE:
1466 if (dlt_daemon_process_user_message_log_mode(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1474 dlt_log(LOG_ERR,"(Internal) Invalid user message type received!\n");
1476 /* remove user header */
1477 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader))==-1)
1479 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user messages\n");
1483 /* In next invocation of do-while loop, a resync will be triggered if additional data was received */
1493 /* keep not read data in buffer */
1494 if (dlt_receiver_move_to_begin(&(daemon_local->receiver))==-1)
1496 dlt_log(LOG_ERR,"Can't move bytes to beginning of receiver buffer for user messages\n");
1503 int dlt_daemon_process_user_message_overflow(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1506 DltUserControlMsgBufferOverflow *userpayload;
1508 PRINT_FUNCTION_VERBOSE(verbose);
1510 if ((daemon==0) || (daemon_local==0))
1512 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_overflow()\n");
1516 if (daemon_local->receiver.bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgBufferOverflow)))
1518 /* Not enough bytes received */
1522 /* get the payload of the user message */
1523 userpayload = (DltUserControlMsgBufferOverflow*) (daemon_local->receiver.buf+sizeof(DltUserHeader));
1525 /* Store in daemon, that a message buffer overflow has occured */
1526 daemon->message_buffer_overflow = DLT_MESSAGE_BUFFER_OVERFLOW;
1528 /* look if TCP connection to client is available */
1531 for (j = 0; j <= daemon_local->fdmax; j++)
1533 /* send to everyone! */
1534 if (FD_ISSET(j, &(daemon_local->master)))
1536 /* except the listener and ourselves */
1537 if ((j != daemon_local->fp) && (j != daemon_local->sock)
1538 #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE
1539 && (j!=daemon_local->timer_wd)
1541 && (j!=daemon_local->timer_timingpacket) && (j!=daemon_local->timer_ecuversion))
1543 dlt_daemon_control_message_buffer_overflow(j, daemon, userpayload->overflow_counter,userpayload->apid,verbose);
1545 /* Reset overflow state */
1546 daemon->message_buffer_overflow = DLT_MESSAGE_BUFFER_NO_OVERFLOW;
1551 /* message was not sent, so store it in ringbuffer */
1554 if(dlt_daemon_control_message_buffer_overflow(DLT_DAEMON_STORE_TO_BUFFER, daemon, userpayload->overflow_counter,
1555 userpayload->apid,verbose))
1557 /* there was an error when storing message */
1558 /* add the counter of lost messages to the daemon counter */
1559 daemon->overflow_counter+=userpayload->overflow_counter;
1563 /* keep not read data in buffer */
1564 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgBufferOverflow))==-1)
1566 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message overflow\n");
1573 int dlt_daemon_send_message_overflow(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1577 PRINT_FUNCTION_VERBOSE(verbose);
1579 if ((daemon==0) || (daemon_local==0))
1581 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_overflow()\n");
1585 /* Store in daemon, that a message buffer overflow has occured */
1586 daemon->message_buffer_overflow = DLT_MESSAGE_BUFFER_OVERFLOW;
1588 /* look if TCP connection to client is available */
1591 for (j = 0; j <= daemon_local->fdmax; j++)
1593 /* send to everyone! */
1594 if (FD_ISSET(j, &(daemon_local->master)))
1596 /* except the listener and ourselves */
1597 if ((j != daemon_local->fp) && (j != daemon_local->sock)
1598 #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE
1599 && (j!=daemon_local->timer_wd)
1601 && (j!=daemon_local->timer_timingpacket) && (j!=daemon_local->timer_ecuversion))
1603 dlt_daemon_control_message_buffer_overflow(j, daemon,daemon->overflow_counter,"", verbose);
1605 /* Reset overflow state */
1606 daemon->message_buffer_overflow = DLT_MESSAGE_BUFFER_NO_OVERFLOW;
1611 /* message was not sent, so report to caller that sending failed */
1620 int dlt_daemon_process_user_message_register_application(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1623 DltDaemonApplication *application;
1624 char description[DLT_DAEMON_DESCSIZE];
1625 DltUserControlMsgRegisterApplication *usercontext;
1627 PRINT_FUNCTION_VERBOSE(verbose);
1629 if ((daemon==0) || (daemon_local==0))
1631 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_register_application()\n");
1635 if (daemon_local->receiver.bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterApplication)))
1637 /* Not enough bytes received */
1641 usercontext = (DltUserControlMsgRegisterApplication*) (daemon_local->receiver.buf+sizeof(DltUserHeader));
1643 memset(description,0,sizeof(description));
1645 len=usercontext->description_length;
1646 if ((len>0) && (len<=DLT_DAEMON_DESCSIZE))
1648 /* Read and store application description */
1649 strncpy(description, (daemon_local->receiver.buf+sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterApplication)), len);
1652 application=dlt_daemon_application_add(daemon,usercontext->apid,usercontext->pid,description,verbose);
1654 /* send log state to new application */
1655 dlt_daemon_user_send_log_state(daemon,application,verbose);
1657 /* keep not read data in buffer */
1658 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterApplication)+len)==-1)
1660 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register application\n");
1666 dlt_log(LOG_CRIT,"Can't add application");
1673 int dlt_daemon_process_user_message_register_context(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1676 int8_t loglevel, tracestatus;
1677 DltUserControlMsgRegisterContext *usercontext;
1678 char description[DLT_DAEMON_DESCSIZE];
1679 DltDaemonApplication *application;
1680 DltDaemonContext *context;
1681 DltServiceGetLogInfoRequest *req;
1687 PRINT_FUNCTION_VERBOSE(verbose);
1689 if ((daemon==0) || (daemon_local==0))
1691 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_register_context()\n");
1695 if (daemon_local->receiver.bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)))
1697 /* Not enough bytes received */
1701 usercontext = (DltUserControlMsgRegisterContext*) (daemon_local->receiver.buf+sizeof(DltUserHeader));
1703 memset(description,0,sizeof(description));
1705 len=usercontext->description_length;
1706 if ((len>0) && (len<=DLT_DAEMON_DESCSIZE))
1708 /* Read and store context description */
1709 strncpy(description, (daemon_local->receiver.buf+sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)), len);
1712 application = dlt_daemon_application_find(daemon,usercontext->apid,verbose);
1716 dlt_log(LOG_ERR, "Application not found in dlt_daemon_process_user_message_register_context()\n");
1717 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)+len)==-1)
1719 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register context\n");
1725 /* Pre-set loglevel */
1726 if (usercontext->log_level == DLT_USER_LOG_LEVEL_NOT_SET)
1728 loglevel=DLT_LOG_DEFAULT;
1732 loglevel=usercontext->log_level;
1733 /* Plausibility check */
1734 if ((loglevel<DLT_LOG_DEFAULT) || (loglevel>DLT_LOG_VERBOSE))
1736 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)+len)==-1)
1738 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register context\n");
1744 /* Pre-set tracestatus */
1745 if (usercontext->trace_status == DLT_USER_TRACE_STATUS_NOT_SET)
1747 tracestatus=DLT_TRACE_STATUS_DEFAULT;
1751 tracestatus=usercontext->trace_status;
1753 /* Plausibility check */
1754 if ((tracestatus<DLT_TRACE_STATUS_DEFAULT) || (tracestatus>DLT_TRACE_STATUS_ON))
1756 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)+len)==-1)
1758 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register context\n");
1764 context = dlt_daemon_context_add(daemon,usercontext->apid,usercontext->ctid, loglevel, tracestatus, usercontext->log_level_pos,application->user_handle,description,verbose);
1768 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)+len)==-1)
1770 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register context\n");
1773 dlt_log(LOG_CRIT,"Can't add context");
1776 /* Create automatic get log info response for registered context */
1777 if (daemon_local->flags.rflag)
1779 /* Prepare request for get log info with one application and one context */
1780 if (dlt_message_init(&msg, verbose)==-1)
1782 dlt_log(LOG_ERR,"Can't initialize message");
1786 msg.datasize = sizeof(DltServiceGetLogInfoRequest);
1787 if (msg.databuffer && (msg.databuffersize < msg.datasize))
1789 free(msg.databuffer);
1792 if (msg.databuffer == 0){
1793 msg.databuffer = (uint8_t *) malloc(msg.datasize);
1794 msg.databuffersize = msg.datasize;
1796 if (msg.databuffer==0)
1798 dlt_log(LOG_ERR,"Can't allocate buffer for get log info message\n");
1802 req = (DltServiceGetLogInfoRequest*) msg.databuffer;
1804 req->service_id = DLT_SERVICE_ID_GET_LOG_INFO;
1806 dlt_set_id(req->apid, usercontext->apid);
1807 dlt_set_id(req->ctid, usercontext->ctid);
1808 dlt_set_id(req->com,"remo");
1812 /* Send response to get log info request to DLT clients */
1813 for (j = 0; j <= daemon_local->fdmax; j++)
1815 /* send to everyone! */
1816 if (FD_ISSET(j, &(daemon_local->master)))
1818 /* except the listener and ourselves */
1819 if ((j != daemon_local->fp) && (j != daemon_local->sock)
1820 #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE
1821 && (j!=daemon_local->timer_wd)
1823 && (j!=daemon_local->timer_timingpacket) && (j!=daemon_local->timer_ecuversion))
1825 dlt_daemon_control_get_log_info(j , daemon, &msg, verbose);
1833 /* Store to buffer */
1834 dlt_daemon_control_get_log_info(DLT_DAEMON_STORE_TO_BUFFER , daemon, &msg, verbose);
1837 dlt_message_free(&msg, verbose);
1840 if (context->user_handle >= DLT_FD_MINIMUM)
1842 /* This call also replaces the default values with the values defined for default */
1843 if (dlt_daemon_user_send_log_level(daemon, context, verbose)==-1)
1845 dlt_log(LOG_ERR,"Can't send current log level as response to user message register context\n");
1850 /* keep not read data in buffer */
1851 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)+len)==-1)
1853 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register context\n");
1860 int dlt_daemon_process_user_message_unregister_application(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1862 DltUserControlMsgUnregisterApplication *usercontext;
1863 DltDaemonApplication *application;
1864 DltDaemonContext *context;
1867 PRINT_FUNCTION_VERBOSE(verbose);
1869 if ((daemon==0) || (daemon_local==0))
1871 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_unregister_application()\n");
1875 if (daemon_local->receiver.bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgUnregisterApplication)))
1877 /* Not enough bytes received */
1881 if (daemon->num_applications>0)
1883 usercontext = (DltUserControlMsgUnregisterApplication*) (daemon_local->receiver.buf+sizeof(DltUserHeader));
1885 /* Delete this application and all corresponding contexts for this application from internal table */
1886 application = dlt_daemon_application_find(daemon,usercontext->apid, verbose);
1890 /* Calculate start offset within contexts[] */
1892 for (i=0; i<(application-(daemon->applications)); i++)
1894 offset_base+=daemon->applications[i].num_contexts;
1897 for (i=application->num_contexts-1; i>=0; i--)
1899 context = &(daemon->contexts[offset_base+i]);
1902 /* Delete context */
1903 if (dlt_daemon_context_del(daemon, context, verbose)==-1)
1905 dlt_log(LOG_ERR,"Can't delete context for user message unregister application\n");
1911 /* Delete this application entry from internal table*/
1912 if (dlt_daemon_application_del(daemon, application, verbose)==-1)
1914 dlt_log(LOG_ERR,"Can't delete application for user message unregister application\n");
1920 /* keep not read data in buffer */
1921 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgUnregisterApplication))==-1)
1923 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message unregister application\n");
1930 int dlt_daemon_process_user_message_unregister_context(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1932 DltUserControlMsgUnregisterContext *usercontext;
1933 DltDaemonContext *context;
1935 PRINT_FUNCTION_VERBOSE(verbose);
1937 if ((daemon==0) || (daemon_local==0))
1939 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_unregister_context()\n");
1943 if (daemon_local->receiver.bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgUnregisterContext)))
1945 /* Not enough bytes received */
1949 usercontext = (DltUserControlMsgUnregisterContext*) (daemon_local->receiver.buf+sizeof(DltUserHeader));
1950 context = dlt_daemon_context_find(daemon,usercontext->apid, usercontext->ctid, verbose);
1954 /* Delete this connection entry from internal table*/
1955 if (dlt_daemon_context_del(daemon, context, verbose)==-1)
1957 dlt_log(LOG_ERR,"Can't delete context for user message unregister context\n");
1962 /* Create automatic unregister context response for unregistered context */
1963 if (daemon_local->flags.rflag)
1968 /* Send response to get log info request to DLT clients */
1969 for (j = 0; j <= daemon_local->fdmax; j++)
1971 /* send to everyone! */
1972 if (FD_ISSET(j, &(daemon_local->master)))
1974 /* except the listener and ourselves */
1975 if ((j != daemon_local->fp) && (j != daemon_local->sock)
1976 #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE
1977 && (j!=daemon_local->timer_wd)
1979 && (j!=daemon_local->timer_timingpacket) && (j!=daemon_local->timer_ecuversion))
1981 dlt_daemon_control_message_unregister_context(j,daemon,usercontext->apid, usercontext->ctid, "remo",verbose);
1989 /* Store to buffer */
1990 dlt_daemon_control_message_unregister_context(DLT_DAEMON_STORE_TO_BUFFER,daemon,usercontext->apid, usercontext->ctid, "remo",verbose);
1994 /* keep not read data in buffer */
1995 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgUnregisterContext))==-1)
1997 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message unregister context\n");
2004 int dlt_daemon_process_user_message_log(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
2006 int bytes_to_be_removed;
2007 int j,sent,third_value;
2010 static char text[DLT_DAEMON_TEXTSIZE];
2012 PRINT_FUNCTION_VERBOSE(verbose);
2014 if ((daemon==0) || (daemon_local==0))
2016 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_log()\n");
2020 if (dlt_message_read(&(daemon_local->msg),(unsigned char*)daemon_local->receiver.buf+sizeof(DltUserHeader),daemon_local->receiver.bytesRcvd-sizeof(DltUserHeader),0,verbose)==0)
2022 /* set overwrite ecu id */
2023 if (daemon_local->flags.evalue!=0)
2025 /* Set header extra parameters */
2026 dlt_set_id(daemon_local->msg.headerextra.ecu, daemon->ecuid );
2027 //msg.headerextra.seid = 0;
2028 if (dlt_message_set_extraparameters(&(daemon_local->msg),0)==-1)
2030 dlt_log(LOG_ERR,"Can't set message extra parameters in process user message log\n");
2034 /* Correct value of timestamp, this was changed by dlt_message_set_extraparameters() */
2035 daemon_local->msg.headerextra.tmsp = DLT_BETOH_32(daemon_local->msg.headerextra.tmsp);
2038 /* prepare storage header */
2039 if (DLT_IS_HTYP_WEID(daemon_local->msg.standardheader->htyp))
2041 if (dlt_set_storageheader(daemon_local->msg.storageheader,daemon_local->msg.headerextra.ecu)==-1)
2043 dlt_log(LOG_ERR,"Can't set storage header in process user message log\n");
2049 if (dlt_set_storageheader(daemon_local->msg.storageheader,daemon->ecuid)==-1)
2051 dlt_log(LOG_ERR,"Can't set storage header in process user message log\n");
2057 /* if no filter set or filter is matching display message */
2058 if (daemon_local->flags.xflag)
2060 if (dlt_message_print_hex(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1)
2062 dlt_log(LOG_ERR,"dlt_message_print_hex() failed!\n");
2065 else if (daemon_local->flags.aflag)
2067 if (dlt_message_print_ascii(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1)
2069 dlt_log(LOG_ERR,"dlt_message_print_ascii() failed!\n");
2072 else if (daemon_local->flags.sflag)
2074 if (dlt_message_print_header(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1)
2076 dlt_log(LOG_ERR,"dlt_message_print_header() failed!\n");
2078 /* print message header only */
2083 /* write message to offline trace */
2084 if(((daemon->mode == DLT_USER_MODE_INTERNAL) || (daemon->mode == DLT_USER_MODE_BOTH)) && daemon_local->flags.offlineTraceDirectory[0])
2086 dlt_offline_trace_write(&(daemon_local->offlineTrace),daemon_local->msg.headerbuffer,daemon_local->msg.headersize,
2087 daemon_local->msg.databuffer,daemon_local->msg.datasize,0,0);
2091 /* check if overflow occurred */
2092 if(daemon->overflow_counter)
2094 if(dlt_daemon_send_message_overflow(daemon,daemon_local,verbose)==0)
2096 sprintf(str,"%u messages discarded!\n",daemon->overflow_counter);
2097 dlt_log(LOG_ERR, str);
2098 daemon->overflow_counter=0;
2102 /* look if TCP connection to client is available */
2103 for (j = 0;((daemon->mode == DLT_USER_MODE_EXTERNAL) || (daemon->mode == DLT_USER_MODE_BOTH)) && (j <= daemon_local->fdmax); j++)
2105 /* send to everyone! */
2106 if (FD_ISSET(j, &(daemon_local->master)))
2108 /* except the listener and ourselves */
2109 if (daemon_local->flags.yvalue[0])
2111 third_value = daemon_local->fdserial;
2115 third_value = daemon_local->sock;
2118 if ((j != daemon_local->fp) && (j != daemon_local->sock) && (j != third_value)
2119 #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE
2120 && (j!=daemon_local->timer_wd)
2122 && (j!=daemon_local->timer_timingpacket) && (j!=daemon_local->timer_ecuversion))
2126 DLT_DAEMON_SEM_LOCK();
2128 if (daemon_local->flags.lflag)
2130 if(0 > send(j,dltSerialHeader,sizeof(dltSerialHeader),0))
2132 dlt_daemon_close_socket(j, daemon, daemon_local, verbose);
2137 if(!failed && 0 > send(j,daemon_local->msg.headerbuffer+sizeof(DltStorageHeader),daemon_local->msg.headersize-sizeof(DltStorageHeader),0))
2139 dlt_daemon_close_socket(j, daemon, daemon_local, verbose);
2143 if(!failed && 0 > send(j,daemon_local->msg.databuffer,daemon_local->msg.datasize,0))
2145 dlt_daemon_close_socket(j, daemon, daemon_local, verbose);
2149 DLT_DAEMON_SEM_FREE();
2153 else if ((j == daemon_local->fdserial) && (daemon_local->flags.yvalue!=0))
2155 DLT_DAEMON_SEM_LOCK();
2157 if (daemon_local->flags.lflag)
2159 ret=write(j,dltSerialHeader,sizeof(dltSerialHeader));
2162 dlt_log(LOG_ERR,"write(j,dltSerialHeader failed\n");
2165 int32_t diff = daemon_local->msg.headersize-sizeof(DltStorageHeader);
2166 //extra calculation for coverity
2168 ret=write(j,daemon_local->msg.headerbuffer+sizeof(DltStorageHeader),diff);
2171 dlt_log(LOG_ERR,"write(j,daemon_local->msg.headerbuffer failed\n");
2173 ret=write(j,daemon_local->msg.databuffer,daemon_local->msg.datasize);
2176 dlt_log(LOG_ERR,"write(j,daemon_local->msg.databuffer failed\n");
2180 DLT_DAEMON_SEM_FREE();
2187 /* Message was not sent to client, so store it in client ringbuffer */
2190 DLT_DAEMON_SEM_LOCK();
2191 if (dlt_buffer_push3(&(daemon->client_ringbuffer),
2192 daemon_local->msg.headerbuffer+sizeof(DltStorageHeader),daemon_local->msg.headersize-sizeof(DltStorageHeader),
2193 daemon_local->msg.databuffer,daemon_local->msg.datasize,
2197 if(daemon->overflow_counter==0)
2198 dlt_log(LOG_ERR,"Buffer full! Messages will be discarded.\n");
2199 daemon->overflow_counter+=1;
2201 DLT_DAEMON_SEM_FREE();
2205 /* keep not read data in buffer */
2206 bytes_to_be_removed = daemon_local->msg.headersize+daemon_local->msg.datasize-sizeof(DltStorageHeader)+sizeof(DltUserHeader);
2207 if (daemon_local->msg.found_serialheader)
2209 bytes_to_be_removed += sizeof(dltSerialHeader);
2212 if (dlt_receiver_remove(&(daemon_local->receiver),bytes_to_be_removed)==-1)
2214 dlt_log(LOG_ERR,"Can't remove bytes from receiver\n");
2220 dlt_log(LOG_ERR,"Can't read messages from receiver\n");
2227 #ifdef DLT_SHM_ENABLE
2228 int dlt_daemon_process_user_message_log_shm(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
2230 int bytes_to_be_removed=0;
2231 int j,sent,third_value;
2233 uint8_t rcv_buffer[10000];
2235 DltUserHeader *userheader;
2237 static char text[DLT_DAEMON_TEXTSIZE];
2239 PRINT_FUNCTION_VERBOSE(verbose);
2241 if ((daemon==0) || (daemon_local==0))
2243 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_log()\n");
2247 userheader = (DltUserHeader*) (daemon_local->receiver.buf);
2249 //dlt_shm_status(&(daemon_local->dlt_shm));
2252 /* log message in SHM */
2253 if((size = dlt_shm_copy(&(daemon_local->dlt_shm),rcv_buffer,10000)) <= 0)
2255 if (dlt_message_read(&(daemon_local->msg),rcv_buffer,size,0,verbose)!=0) {
2257 dlt_log(LOG_ERR,"Can't read messages from shm\n");
2260 bytes_to_be_removed = daemon_local->msg.headersize+daemon_local->msg.datasize-sizeof(DltStorageHeader)+sizeof(DltUserHeader);
2261 if (daemon_local->msg.found_serialheader)
2263 bytes_to_be_removed += sizeof(dltSerialHeader);
2266 /* set overwrite ecu id */
2267 if (daemon_local->flags.evalue[0])
2269 /* Set header extra parameters */
2270 dlt_set_id(daemon_local->msg.headerextra.ecu, daemon->ecuid );
2271 //msg.headerextra.seid = 0;
2272 if (dlt_message_set_extraparameters(&(daemon_local->msg),0)==-1)
2274 dlt_log(LOG_ERR,"Can't set message extra parameters in process user message log\n");
2275 dlt_shm_remove(&(daemon_local->dlt_shm));
2279 /* Correct value of timestamp, this was changed by dlt_message_set_extraparameters() */
2280 daemon_local->msg.headerextra.tmsp = DLT_BETOH_32(daemon_local->msg.headerextra.tmsp);
2283 /* prepare storage header */
2284 if (DLT_IS_HTYP_WEID(daemon_local->msg.standardheader->htyp))
2286 if (dlt_set_storageheader(daemon_local->msg.storageheader,daemon_local->msg.headerextra.ecu)==-1)
2288 dlt_log(LOG_ERR,"Can't set storage header in process user message log\n");
2289 dlt_shm_remove(&(daemon_local->dlt_shm));
2295 if (dlt_set_storageheader(daemon_local->msg.storageheader,daemon->ecuid)==-1)
2297 dlt_log(LOG_ERR,"Can't set storage header in process user message log\n");
2298 dlt_shm_remove(&(daemon_local->dlt_shm));
2303 /* display message */
2304 if (daemon_local->flags.xflag)
2306 if (dlt_message_print_hex(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1)
2308 dlt_log(LOG_ERR,"dlt_message_print_hex() failed!\n");
2311 else if (daemon_local->flags.aflag)
2313 if (dlt_message_print_ascii(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1)
2315 dlt_log(LOG_ERR,"dlt_message_print_ascii() failed!\n");
2318 else if (daemon_local->flags.sflag)
2320 if (dlt_message_print_header(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1)
2322 dlt_log(LOG_ERR,"dlt_message_print_header() failed!\n");
2324 /* print message header only */
2329 /* write message to offline trace */
2330 if(((daemon->mode == DLT_USER_MODE_INTERNAL) || (daemon->mode == DLT_USER_MODE_BOTH)) && daemon_local->flags.offlineTraceDirectory[0])
2332 dlt_offline_trace_write(&(daemon_local->offlineTrace),daemon_local->msg.headerbuffer,daemon_local->msg.headersize,
2333 daemon_local->msg.databuffer,daemon_local->msg.datasize,0,0);
2337 /* look if TCP connection to client is available */
2338 for (j = 0;((daemon->mode == DLT_USER_MODE_EXTERNAL) || (daemon->mode == DLT_USER_MODE_BOTH)) && (j <= daemon_local->fdmax); j++)
2340 /* send to everyone! */
2341 if (FD_ISSET(j, &(daemon_local->master)))
2343 /* except the listener and ourselves */
2344 if (daemon_local->flags.yvalue[0])
2346 third_value = daemon_local->fdserial;
2350 third_value = daemon_local->sock;
2353 if ((j != daemon_local->fp) && (j != daemon_local->sock) && (j != third_value))
2355 DLT_DAEMON_SEM_LOCK();
2357 if (daemon_local->flags.lflag)
2359 send(j,dltSerialHeader,sizeof(dltSerialHeader),0);
2362 send(j,daemon_local->msg.headerbuffer+sizeof(DltStorageHeader),daemon_local->msg.headersize-sizeof(DltStorageHeader),0);
2363 send(j,daemon_local->msg.databuffer,daemon_local->msg.datasize,0);
2365 DLT_DAEMON_SEM_FREE();
2369 else if ((j == daemon_local->fdserial) && (daemon_local->flags.yvalue[0]))
2371 DLT_DAEMON_SEM_LOCK();
2373 if (daemon_local->flags.lflag)
2375 ret=write(j,dltSerialHeader,sizeof(dltSerialHeader));
2378 ret=write(j,daemon_local->msg.headerbuffer+sizeof(DltStorageHeader),daemon_local->msg.headersize-sizeof(DltStorageHeader));
2379 ret=write(j,daemon_local->msg.databuffer,daemon_local->msg.datasize);
2381 DLT_DAEMON_SEM_FREE();
2388 /* Message was not sent to client, so store it in client ringbuffer */
2389 if (sent==1 || (daemon->mode == DLT_USER_MODE_OFF))
2391 if(userheader->message == DLT_USER_MESSAGE_LOG_SHM) {
2392 /* dlt message was sent, remove from buffer if log message from shm */
2393 dlt_shm_remove(&(daemon_local->dlt_shm));
2398 /* dlt message was not sent, keep in buffer */
2404 /* keep not read data in buffer */
2405 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader))==-1)
2407 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message overflow\n");
2415 int dlt_daemon_process_user_message_set_app_ll_ts(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
2417 DltUserControlMsgAppLogLevelTraceStatus *usercontext;
2418 DltDaemonApplication *application;
2419 DltDaemonContext *context;
2421 int8_t old_log_level, old_trace_status;
2423 PRINT_FUNCTION_VERBOSE(verbose);
2425 if ((daemon==0) || (daemon_local==0))
2427 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_set_app_ll_ts()\n");
2431 if (daemon_local->receiver.bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgAppLogLevelTraceStatus )))
2433 /* Not enough bytes receeived */
2437 if (daemon->num_applications>0)
2439 usercontext = (DltUserControlMsgAppLogLevelTraceStatus*) (daemon_local->receiver.buf+sizeof(DltUserHeader));
2441 /* Get all contexts with application id matching the received application id */
2442 application = dlt_daemon_application_find(daemon, usercontext->apid, verbose);
2445 /* Calculate start offset within contexts[] */
2447 for (i=0; i<(application-(daemon->applications)); i++)
2449 offset_base+=daemon->applications[i].num_contexts;
2452 for (i=0; i < application->num_contexts; i++)
2454 context = &(daemon->contexts[offset_base+i]);
2457 old_log_level = context->log_level;
2458 context->log_level = usercontext->log_level; /* No endianess conversion necessary*/
2460 old_trace_status = context->trace_status;
2461 context->trace_status = usercontext->trace_status; /* No endianess conversion necessary */
2463 /* The folowing function sends also the trace status */
2464 if (context->user_handle >= DLT_FD_MINIMUM && dlt_daemon_user_send_log_level(daemon, context, verbose)!=0)
2466 context->log_level = old_log_level;
2467 context->trace_status = old_trace_status;
2474 /* keep not read data in buffer */
2475 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgAppLogLevelTraceStatus))==-1)
2477 dlt_log(LOG_ERR,"Can't remove bytes from receiver\n");
2484 int dlt_daemon_process_user_message_log_mode(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
2486 DltUserControlMsgLogMode *logmode;
2488 PRINT_FUNCTION_VERBOSE(verbose);
2490 if ((daemon==0) || (daemon_local==0))
2492 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_log_mode()\n");
2496 if (daemon_local->receiver.bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgUnregisterContext)))
2498 /* Not enough bytes received */
2502 logmode = (DltUserControlMsgLogMode*) (daemon_local->receiver.buf+sizeof(DltUserHeader));
2504 /* set the new log mode */
2505 daemon->mode = logmode->log_mode;
2507 /* write configuration persistantly */
2508 dlt_daemon_configuration_save(daemon, daemon->runtime_configuration, verbose);
2510 /* keep not read data in buffer */
2511 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogMode))==-1)
2513 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message log mode\n");
2520 int dlt_daemon_send_ringbuffer_to_client(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
2522 static uint8_t data[DLT_DAEMON_RCVBUFSIZE];
2527 PRINT_FUNCTION_VERBOSE(verbose);
2529 if ((daemon==0) || (daemon_local==0))
2531 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_send_ringbuffer_to_client()\n");
2535 /* Attention: If the message can't be send at this time, it will be silently discarded. */
2536 while ((length = dlt_buffer_pull(&(daemon->client_ringbuffer), data, sizeof(data) )) > 0)
2538 /* look if TCP connection to client is available */
2539 for (j = 0; j <= daemon_local->fdmax; j++)
2541 /* send to everyone! */
2542 if (FD_ISSET(j, &(daemon_local->master)))
2544 /* except the listener and ourselves */
2545 if (daemon_local->flags.yvalue[0])
2547 third_value = daemon_local->fdserial;
2551 third_value = daemon_local->sock;
2554 if ((j != daemon_local->fp) && (j != daemon_local->sock) && (j != third_value)
2555 #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE
2556 && (j!=daemon_local->timer_wd)
2558 && (j!=daemon_local->timer_timingpacket) && (j!=daemon_local->timer_ecuversion))
2561 DLT_DAEMON_SEM_LOCK();
2563 if (daemon_local->flags.lflag)
2565 if(!failed && 0 > send(j,dltSerialHeader,sizeof(dltSerialHeader),0))
2567 dlt_daemon_close_socket(j, daemon, daemon_local, verbose);
2571 if(!failed && 0 > send(j,data,length,0))
2573 dlt_daemon_close_socket(j, daemon, daemon_local, verbose);
2577 DLT_DAEMON_SEM_FREE();
2580 else if ((j == daemon_local->fdserial) && (daemon_local->flags.yvalue[0]))
2582 DLT_DAEMON_SEM_LOCK();
2584 if (daemon_local->flags.lflag)
2586 ret=write(j,dltSerialHeader,sizeof(dltSerialHeader));
2589 dlt_log(LOG_ERR, "dlt_daemon_send_ringbuffer_to_client: write(j,dltSerialHeader,sizeof(dltSerialHeader)) failed!\n");
2590 DLT_DAEMON_SEM_FREE();
2594 ret=write(j,data,length);
2597 dlt_log(LOG_ERR, "dlt_daemon_send_ringbuffer_to_client: write(j,data,length) failed!\n");
2598 DLT_DAEMON_SEM_FREE();
2601 DLT_DAEMON_SEM_FREE();
2606 length = sizeof(data);
2612 int dlt_daemon_make_periodic (unsigned int period, DltDaemonPeriodicData *info, int verbose)
2618 struct itimerspec itval;
2620 PRINT_FUNCTION_VERBOSE(verbose);
2624 dlt_log(LOG_ERR,"No data pointer passed!\n");
2628 /* Create the timer */
2629 fd = timerfd_create (CLOCK_MONOTONIC, 0);
2631 info->wakeups_missed = 0;
2632 info->timer_fd = fd;
2636 dlt_log(LOG_ERR,"Can't create timer filedescriptor");
2640 /* Make the timer periodic */
2641 sec = period/1000000;
2642 ns = (period - (sec * 1000000)) * 1000;
2643 itval.it_interval.tv_sec = sec;
2644 itval.it_interval.tv_nsec = ns;
2645 itval.it_value.tv_sec = sec;
2646 itval.it_value.tv_nsec = ns;
2648 ret = timerfd_settime (fd, 0, &itval, NULL);
2653 void dlt_daemon_wait_period (DltDaemonPeriodicData *info, int verbose)
2655 unsigned long long missed;
2658 PRINT_FUNCTION_VERBOSE(verbose);
2660 ret = read (info->timer_fd, &missed, sizeof (missed));
2662 dlt_log(LOG_ERR,"dlt_daemon_wait_period: Read failed");
2667 info->wakeups_missed += (missed - 1);
2671 int create_timer_fd(DltDaemonLocal *daemon_local, int period_sec, int starts_in, int* fd, const char* timer_name)
2674 struct itimerspec l_timer_spec;
2676 if(timer_name == NULL)
2678 timer_name = "timer_not_named";
2683 snprintf(str, sizeof(str), "<%s> fd is NULL pointer\n", timer_name );
2684 dlt_log(DLT_LOG_ERROR, str);
2688 if( period_sec > 0 ) {
2689 local_fd = timerfd_create(CLOCK_MONOTONIC, 0);
2692 snprintf(str, sizeof(str), "<%s> timerfd_create failed: %s\n", timer_name, strerror(errno));
2693 dlt_log(DLT_LOG_ERROR, str);
2696 l_timer_spec.it_interval.tv_sec = period_sec;
2697 l_timer_spec.it_interval.tv_nsec = 0;
2698 l_timer_spec.it_value.tv_sec = starts_in;
2699 l_timer_spec.it_value.tv_nsec = 0;
2701 if( timerfd_settime( local_fd, 0, &l_timer_spec, NULL) < 0)
2703 snprintf(str, sizeof(str), "<%s> timerfd_settime failed: %s\n", timer_name, strerror(errno));
2704 dlt_log(DLT_LOG_ERROR, str);
2709 // timer not activated via the service file
2710 snprintf(str, sizeof(str), "<%s> not set: period=0\n", timer_name);
2711 dlt_log(DLT_LOG_INFO, str);
2715 // If fd is fully initialized, let's add it to the fd sets
2718 snprintf(str, sizeof(str), "<%s> initialized with %ds timer\n", timer_name, period_sec);
2719 dlt_log(DLT_LOG_INFO, str);
2721 FD_SET(local_fd, &(daemon_local->master));
2722 //FD_SET(local_fd, &(daemon_local->timer_fds));
2723 if (local_fd > daemon_local->fdmax)
2725 daemon_local->fdmax = local_fd;
2734 void dlt_daemon_send_timingpacket(DltDaemon *daemon, DltDaemonLocal *daemon_local)
2738 if (daemon->timingpackets)
2740 for (j = 0; j <= daemon_local->fdmax; j++)
2742 /* send to everyone! */
2743 if (FD_ISSET(j, &(daemon_local->master)))
2745 /* except the listener and ourselves */
2746 if ((j != daemon_local->fp) && (j != daemon_local->sock)
2747 #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE
2748 && (j!=daemon_local->timer_wd)
2750 && (j!=daemon_local->timer_timingpacket) && (j!=daemon_local->timer_ecuversion) )
2752 dlt_log(LOG_DEBUG, "timingpacket\n");
2753 dlt_daemon_control_message_time(j, daemon, daemon_local->flags.vflag);
2760 void dlt_daemon_send_ecuversion(DltDaemon *daemon, DltDaemonLocal *daemon_local)
2764 for (j = 0; j <= daemon_local->fdmax; j++)
2766 /* send to everyone! */
2767 if (FD_ISSET(j, &(daemon_local->master)))
2769 /* except the listener and ourselves */
2770 if ((j != daemon_local->fp) && (j != daemon_local->sock)
2771 #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE
2772 && (j!=daemon_local->timer_wd)
2774 && (j!=daemon_local->timer_timingpacket) && (j!=daemon_local->timer_ecuversion))
2776 dlt_log(LOG_DEBUG, "ecu_version\n");
2777 dlt_daemon_control_get_software_version(j, daemon, daemon_local->flags.vflag);
2783 /* Close connection function */
2784 int dlt_daemon_close_socket(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
2787 FD_CLR(sock, &(daemon_local->master));
2789 if (daemon_local->client_connections)
2791 daemon_local->client_connections--;
2794 if(daemon_local->client_connections==0)
2796 /* send new log state to all applications */
2798 dlt_daemon_user_send_all_log_state(daemon,verbose);
2801 if (daemon_local->flags.vflag)
2803 sprintf(str, "Connection to client lost, #connections: %d\n",daemon_local->client_connections);
2804 dlt_log(LOG_INFO, str);
2807 dlt_daemon_control_message_connection_info(DLT_DAEMON_STORE_TO_BUFFER,daemon,DLT_CONNECTION_STATUS_DISCONNECTED,"",verbose);