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));
212 daemon_local->flags.sendTimezone = 0;
214 /* open configuration file */
215 if(daemon_local->flags.cvalue[0])
216 filename = daemon_local->flags.cvalue;
218 filename = "/etc/dlt.conf";
219 //printf("Load configuration from file: %s\n",filename);
220 pFile = fopen (filename,"r");
226 /* fetch line from configuration file */
227 if ( fgets (line , value_length - 1 , pFile) != NULL )
229 pch = strtok (line," =\r\n");
235 if(strcmp(pch,"#")==0)
240 strncpy(token,pch,sizeof(token) - 1);
244 strncpy(value,pch,sizeof(value) - 1);
248 pch = strtok (NULL, " =\r\n");
251 if(token[0] && value[0])
253 /* parse arguments here */
254 if(strcmp(token,"Verbose")==0)
256 daemon_local->flags.vflag = atoi(value);
257 //printf("Option: %s=%s\n",token,value);
259 else if(strcmp(token,"PrintASCII")==0)
261 daemon_local->flags.aflag = atoi(value);
262 //printf("Option: %s=%s\n",token,value);
264 else if(strcmp(token,"PrintHex")==0)
266 daemon_local->flags.xflag = atoi(value);
267 //printf("Option: %s=%s\n",token,value);
269 else if(strcmp(token,"PrintHeadersOnly")==0)
271 daemon_local->flags.sflag = atoi(value);
272 //printf("Option: %s=%s\n",token,value);
274 else if(strcmp(token,"SendSerialHeader")==0)
276 daemon_local->flags.lflag = atoi(value);
277 //printf("Option: %s=%s\n",token,value);
279 else if(strcmp(token,"SendContextRegistration")==0)
281 daemon_local->flags.rflag = atoi(value);
282 //printf("Option: %s=%s\n",token,value);
284 else if(strcmp(token,"SendMessageTime")==0)
286 daemon_local->flags.sendMessageTime = atoi(value);
287 //printf("Option: %s=%s\n",token,value);
289 else if(strcmp(token,"RS232SyncSerialHeader")==0)
291 daemon_local->flags.mflag = atoi(value);
292 //printf("Option: %s=%s\n",token,value);
294 else if(strcmp(token,"TCPSyncSerialHeader")==0)
296 daemon_local->flags.nflag = atoi(value);
297 //printf("Option: %s=%s\n",token,value);
299 else if(strcmp(token,"RS232DeviceName")==0)
301 strncpy(daemon_local->flags.yvalue,value,NAME_MAX);
302 //printf("Option: %s=%s\n",token,value);
304 else if(strcmp(token,"RS232Baudrate")==0)
306 strncpy(daemon_local->flags.bvalue,value,NAME_MAX);
307 //printf("Option: %s=%s\n",token,value);
309 else if(strcmp(token,"ECUId")==0)
311 strncpy(daemon_local->flags.evalue,value,NAME_MAX);
312 //printf("Option: %s=%s\n",token,value);
314 else if(strcmp(token,"PersistanceStoragePath")==0)
316 strncpy(daemon_local->flags.ivalue,value,NAME_MAX);
317 //printf("Option: %s=%s\n",token,value);
319 else if(strcmp(token,"LoggingMode")==0)
321 daemon_local->flags.loggingMode = atoi(value);
322 //printf("Option: %s=%s\n",token,value);
324 else if(strcmp(token,"LoggingLevel")==0)
326 daemon_local->flags.loggingLevel = atoi(value);
327 //printf("Option: %s=%s\n",token,value);
329 else if(strcmp(token,"LoggingFilename")==0)
331 strncpy(daemon_local->flags.loggingFilename,value,sizeof(daemon_local->flags.loggingFilename) - 1);
332 //printf("Option: %s=%s\n",token,value);
334 else if(strcmp(token,"TimeOutOnSend")==0)
336 daemon_local->timeoutOnSend = atoi(value);
337 //printf("Option: %s=%s\n",token,value);
339 else if(strcmp(token,"SharedMemorySize")==0)
341 daemon_local->flags.sharedMemorySize = atoi(value);
342 //printf("Option: %s=%s\n",token,value);
344 else if(strcmp(token,"OfflineTraceDirectory")==0)
346 strncpy(daemon_local->flags.offlineTraceDirectory,value,sizeof(daemon_local->flags.offlineTraceDirectory) - 1);
347 //printf("Option: %s=%s\n",token,value);
349 else if(strcmp(token,"OfflineTraceFileSize")==0)
351 daemon_local->flags.offlineTraceFileSize = atoi(value);
352 //printf("Option: %s=%s\n",token,value);
354 else if(strcmp(token,"OfflineTraceMaxSize")==0)
356 daemon_local->flags.offlineTraceMaxSize = atoi(value);
357 //printf("Option: %s=%s\n",token,value);
359 else if(strcmp(token,"SendECUSoftwareVersion")==0)
361 daemon_local->flags.sendECUSoftwareVersion = atoi(value);
362 //printf("Option: %s=%s\n",token,value);
364 else if(strcmp(token,"PathToECUSoftwareVersion")==0)
366 strncpy(daemon_local->flags.pathToECUSoftwareVersion,value,sizeof(daemon_local->flags.pathToECUSoftwareVersion) - 1);
367 //printf("Option: %s=%s\n",token,value);
369 else if(strcmp(token,"SendTimezone")==0)
371 daemon_local->flags.sendTimezone = atoi(value);
372 //printf("Option: %s=%s\n",token,value);
376 fprintf(stderr, "Unknown option: %s=%s\n",token,value);
389 fprintf(stderr, "Cannot open configuration file: %s\n",filename);
396 * Main function of tool.
398 int main(int argc, char* argv[])
400 char version[DLT_DAEMON_TEXTBUFSIZE];
401 DltDaemonLocal daemon_local;
405 /* Command line option handling */
406 if ((back = option_handling(&daemon_local,argc,argv))<0)
409 fprintf (stderr, "option_handling() failed!\n");
414 /* Configuration file option handling */
415 if ((back = option_file_parser(&daemon_local))<0)
418 fprintf (stderr, "option_file_parser() failed!\n");
423 /* Initialize internal logging facility */
424 dlt_log_set_filename(daemon_local.flags.loggingFilename);
425 dlt_log_set_level(daemon_local.flags.loggingLevel);
426 dlt_log_init(daemon_local.flags.loggingMode);
428 /* Print version information */
429 dlt_get_version(version);
431 sprintf(str,"Starting DLT Daemon; %s\n", version );
432 dlt_log(LOG_NOTICE, str);
434 PRINT_FUNCTION_VERBOSE(daemon_local.flags.vflag);
436 /* --- Daemon init phase 1 begin --- */
437 if (dlt_daemon_local_init_p1(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
439 dlt_log(LOG_CRIT,"Initialization of phase 1 failed!\n");
442 /* --- Daemon init phase 1 end --- */
444 /* --- Daemon connection init begin */
445 if (dlt_daemon_local_connection_init(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
447 dlt_log(LOG_CRIT,"Initialization of local connections failed!\n");
450 /* --- Daemon connection init end */
452 /* --- Daemon init phase 2 begin --- */
453 if (dlt_daemon_local_init_p2(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
455 dlt_log(LOG_CRIT,"Initialization of phase 2 failed!\n");
458 /* --- Daemon init phase 2 end --- */
460 // create fd for watchdog
461 #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE
463 char* watchdogUSec = getenv("WATCHDOG_USEC");
464 int watchdogTimeoutSeconds = 0;
466 dlt_log(LOG_DEBUG, "Systemd watchdog initialization\n");
469 watchdogTimeoutSeconds = atoi(watchdogUSec)/2000000;
471 create_timer_fd(&daemon_local, watchdogTimeoutSeconds, watchdogTimeoutSeconds, &daemon_local.timer_wd, "Systemd watchdog");
475 // create fd for timer timing packets
476 create_timer_fd(&daemon_local, 1, 1, &daemon_local.timer_timingpacket, "Timing packet");
478 // create fd for timer ecu version
479 if(daemon_local.flags.sendECUSoftwareVersion > 0 || daemon_local.flags.sendTimezone > 0)
481 //dlt_daemon_init_ecuversion(&daemon_local);
482 create_timer_fd(&daemon_local, 60, 60, &daemon_local.timer_ecuversion, "ECU version");
488 /* wait for events from all FIFO and sockets */
489 daemon_local.read_fds = daemon_local.master;
490 if (select(daemon_local.fdmax+1, &(daemon_local.read_fds), NULL, NULL, NULL) == -1)
492 dlt_log(LOG_CRIT, "select() failed!\n");
496 /* run through the existing FIFO and sockets to check for events */
497 for (i = 0; i <= daemon_local.fdmax; i++)
499 if (FD_ISSET(i, &(daemon_local.read_fds)))
501 if (i == daemon_local.sock && ((daemon.mode == DLT_USER_MODE_EXTERNAL) || (daemon.mode == DLT_USER_MODE_BOTH)))
503 /* event from TCP server socket, new connection */
504 if (dlt_daemon_process_client_connect(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
506 dlt_log(LOG_CRIT,"Connect to dlt client failed!\n");
510 else if (i == daemon_local.fp)
512 /* event from the FIFO happened */
513 if (dlt_daemon_process_user_messages(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
515 dlt_log(LOG_CRIT,"Processing of messages from user connection failed!\n");
519 else if ((i == daemon_local.fdserial) && (daemon_local.flags.yvalue[0]))
521 /* event from serial connection to client received */
522 if (dlt_daemon_process_client_messages_serial(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
524 dlt_log(LOG_CRIT,"Processing of messages from serial connection failed!\n");
528 #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE
529 else if (i == daemon_local.timer_wd)
532 ssize_t res = read(daemon_local.timer_wd, &expir, sizeof(expir));
534 sprintf(str,"Failed to read timer_wd; %s\n", strerror(errno) );
535 dlt_log(LOG_WARNING, str);
536 // Activity received on timer_wd, but unable to read the fd:
537 // let's go on sending notification
540 dlt_log(LOG_DEBUG, "Timer watchdog\n");
542 if(sd_notify(0, "WATCHDOG=1") < 0)
544 dlt_log(LOG_CRIT, "Could not reset systemd watchdog\n");
548 else if (i == daemon_local.timer_timingpacket)
551 ssize_t res = read(daemon_local.timer_timingpacket, &expir, sizeof(expir));
553 sprintf(str,"Failed to read timer_timingpacket; %s\n", strerror(errno) );
554 dlt_log(LOG_WARNING, str);
555 // Activity received on timer_wd, but unable to read the fd:
556 // let's go on sending notification
558 dlt_daemon_send_timingpacket(&daemon, &daemon_local);
559 dlt_log(LOG_DEBUG, "Timer timingpacket\n");
563 else if (i == daemon_local.timer_ecuversion)
566 ssize_t res = read(daemon_local.timer_ecuversion, &expir, sizeof(expir));
568 sprintf(str,"Failed to read timer_ecuversion; %s\n", strerror(errno) );
569 dlt_log(LOG_WARNING, str);
570 // Activity received on timer_wd, but unable to read the fd:
571 // let's go on sending notification
573 dlt_daemon_send_ecuversion(&daemon, &daemon_local);
574 dlt_log(LOG_DEBUG, "Timer ecuversion\n");
579 /* event from tcp connection to client received */
580 daemon_local.receiverSock.fd = i;
581 if (dlt_daemon_process_client_messages(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
583 dlt_log(LOG_CRIT,"Processing of messages from client connection failed!\n");
591 dlt_daemon_local_cleanup(&daemon, &daemon_local, daemon_local.flags.vflag);
593 dlt_log(LOG_NOTICE, "Leaving DLT daemon\n");
599 int dlt_daemon_local_init_p1(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
601 #if defined(DLT_SYSTEMD_WATCHDOG_ENABLE) || defined(DLT_SYSTEMD_ENABLE)
606 PRINT_FUNCTION_VERBOSE(verbose);
608 if ((daemon==0) || (daemon_local==0))
610 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_local_init_p1()\n");
614 #if defined(DLT_SYSTEMD_WATCHDOG_ENABLE) || defined(DLT_SYSTEMD_ENABLE)
618 dlt_log(LOG_CRIT, "system not booted with systemd!\n");
623 dlt_log(LOG_CRIT, "sd_booted failed!\n");
628 dlt_log(LOG_INFO, "system booted with systemd\n");
634 /* Check for daemon mode */
635 if (daemon_local->flags.dflag)
637 dlt_daemon_daemonize(daemon_local->flags.vflag);
640 /* initialise structure to use DLT file */
641 if (dlt_file_init(&(daemon_local->file),daemon_local->flags.vflag)==-1)
643 dlt_log(LOG_ERR,"Could not initialize file structure\n");
644 /* Return value ignored, dlt daemon will exit */
645 dlt_file_free(&(daemon_local->file),daemon_local->flags.vflag);
649 signal(SIGPIPE,SIG_IGN);
651 signal(SIGTERM, dlt_daemon_signal_handler); /* software termination signal from kill */
652 signal(SIGHUP, dlt_daemon_signal_handler); /* hangup signal */
653 signal(SIGQUIT, dlt_daemon_signal_handler);
654 signal(SIGINT, dlt_daemon_signal_handler);
659 int dlt_daemon_local_init_p2(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
661 PRINT_FUNCTION_VERBOSE(verbose);
663 if ((daemon==0) || (daemon_local==0))
665 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_local_init_p2()\n");
670 if (dlt_daemon_init(daemon,daemon_local->flags.ivalue,daemon_local->flags.vflag)==-1)
672 dlt_log(LOG_ERR,"Could not initialize daemon data\n");
676 /* init offline trace */
677 if(((daemon->mode == DLT_USER_MODE_INTERNAL) || (daemon->mode == DLT_USER_MODE_BOTH)) && daemon_local->flags.offlineTraceDirectory[0])
679 if (dlt_offline_trace_init(&(daemon_local->offlineTrace),daemon_local->flags.offlineTraceDirectory,daemon_local->flags.offlineTraceFileSize,daemon_local->flags.offlineTraceMaxSize)==-1)
681 dlt_log(LOG_ERR,"Could not initialize offline trace\n");
686 /* Set ECU id of daemon */
687 if (daemon_local->flags.evalue[0])
689 dlt_set_id(daemon->ecuid,daemon_local->flags.evalue);
693 dlt_set_id(daemon->ecuid,DLT_DAEMON_ECU_ID);
696 /* Set flag for optional sending of serial header */
697 daemon->sendserialheader = daemon_local->flags.lflag;
699 #ifdef DLT_SHM_ENABLE
700 /* init shared memory */
701 if (dlt_shm_init_server(&(daemon_local->dlt_shm),DLT_SHM_KEY,daemon_local->flags.sharedMemorySize)==-1)
703 dlt_log(LOG_ERR,"Could not initialize shared memory\n");
708 /* prepare main loop */
709 if (dlt_message_init(&(daemon_local->msg),daemon_local->flags.vflag)==-1)
711 dlt_log(LOG_ERR,"Could not initialize message\n");
715 if (dlt_receiver_init(&(daemon_local->receiver),daemon_local->fp,DLT_DAEMON_RCVBUFSIZE)==-1)
717 dlt_log(LOG_ERR,"Could not initialize receiver\n");
720 if (dlt_receiver_init(&(daemon_local->receiverSock),daemon_local->sock,DLT_DAEMON_RCVBUFSIZESOCK)==-1)
722 dlt_log(LOG_ERR,"Could not initialize receiver for socket\n");
725 if (daemon_local->flags.yvalue[0])
727 if (dlt_receiver_init(&(daemon_local->receiverSerial),daemon_local->fdserial,DLT_DAEMON_RCVBUFSIZESERIAL)==-1)
729 dlt_log(LOG_ERR,"Could not initialize receiver for serial connection\n");
734 /* configure sending timing packets */
735 if (daemon_local->flags.sendMessageTime)
737 daemon->timingpackets = 1;
740 /* Binary semaphore for thread */
741 if (sem_init(&dlt_daemon_mutex, 0, 1)==-1)
743 dlt_log(LOG_ERR,"Could not initialize binary semaphore\n");
747 /* Get ECU version info from a file. If it fails, use dlt_version as fallback. */
748 if(dlt_daemon_local_ecu_version_init(daemon, daemon_local, daemon_local->flags.vflag) < 0)
750 daemon->ECUVersionString = malloc(DLT_DAEMON_TEXTBUFSIZE);
751 dlt_get_version(daemon->ECUVersionString);
757 int dlt_daemon_local_connection_init(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
762 struct sockaddr_in servAddr;
763 unsigned int servPort = DLT_DAEMON_TCP_PORT;
765 PRINT_FUNCTION_VERBOSE(verbose);
767 if ((daemon==0) || (daemon_local==0))
769 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_local_connection_init()\n");
773 /* open named pipe(FIFO) to receive DLT messages from users */
776 ret=mkdir(DLT_USER_DIR, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH | S_ISVTX );
777 if (ret==-1 && errno != EEXIST)
779 sprintf(str,"FIFO user dir %s cannot be created!\n", DLT_USER_DIR);
780 dlt_log(LOG_ERR, str);
784 // S_ISGID cannot be set by mkdir, let's reassign right bits
785 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 );
788 sprintf(str,"FIFO user dir %s cannot be chmoded!\n", DLT_USER_DIR);
789 dlt_log(LOG_ERR, str);
793 /* Try to delete existing pipe, ignore result of unlink */
794 unlink(DLT_USER_FIFO);
796 ret=mkfifo(DLT_USER_FIFO, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP );
799 sprintf(str,"FIFO user %s cannot be created!\n",DLT_USER_FIFO);
800 dlt_log(LOG_ERR, str);
804 daemon_local->fp = open(DLT_USER_FIFO, O_RDWR);
805 if (daemon_local->fp==-1)
807 sprintf(str,"FIFO user %s cannot be opened!\n",DLT_USER_FIFO);
808 dlt_log(LOG_ERR, str);
812 /* create and open socket to receive incoming connections from client */
813 if ((daemon_local->sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
815 dlt_log(LOG_ERR, "socket() failed!\n");
819 if ( -1 == setsockopt(daemon_local->sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)))
821 sprintf(str,"Setsockopt error in dlt_daemon_local_connection_init: %s\n",strerror(errno));
822 dlt_log(LOG_ERR, str);
825 memset(&servAddr, 0, sizeof(servAddr));
826 servAddr.sin_family = AF_INET;
827 servAddr.sin_addr.s_addr = INADDR_ANY;
828 servAddr.sin_port = htons(servPort);
830 if (bind(daemon_local->sock, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0)
832 dlt_log(LOG_ERR, "bind() failed!\n");
836 if (daemon_local->flags.vflag)
838 dlt_log(LOG_INFO, "Bind succesfull\n");
841 if (listen(daemon_local->sock, 3) < 0)
843 dlt_log(LOG_ERR, "listen() failed!\n");
847 if (daemon_local->flags.vflag)
849 dlt_log(LOG_INFO, "Listen succesfull\n");
852 /* prepare usage of select(), add FIFO and receiving socket */
853 FD_ZERO(&(daemon_local->master));
854 FD_ZERO(&(daemon_local->read_fds));
855 FD_SET(daemon_local->sock, &(daemon_local->master));
857 daemon_local->fdmax = daemon_local->sock;
859 FD_SET(daemon_local->fp, &(daemon_local->master));
861 if (daemon_local->fp > daemon_local->fdmax)
863 daemon_local->fdmax = daemon_local->fp;
866 if (daemon_local->flags.yvalue[0])
868 /* create and open serial connection from/to client */
869 /* open serial connection */
870 daemon_local->fdserial=open(daemon_local->flags.yvalue,O_RDWR);
871 if (daemon_local->fdserial<0)
873 sprintf(str,"Failed to open serial device %s\n", daemon_local->flags.yvalue);
874 daemon_local->flags.yvalue[0] = 0;
875 dlt_log(LOG_ERR, str);
879 if (isatty(daemon_local->fdserial))
881 if (daemon_local->flags.bvalue[0])
883 daemon_local->baudrate = dlt_convert_serial_speed(atoi(daemon_local->flags.bvalue));
887 daemon_local->baudrate = dlt_convert_serial_speed(DLT_DAEMON_SERIAL_DEFAULT_BAUDRATE);
890 if (dlt_setup_serial(daemon_local->fdserial,daemon_local->baudrate)<0)
892 close(daemon_local->fdserial);
893 sprintf(str,"Failed to configure serial device %s (%s) \n", daemon_local->flags.yvalue, strerror(errno));
894 daemon_local->flags.yvalue[0] = 0;
895 dlt_log(LOG_ERR, str);
899 FD_SET(daemon_local->fdserial, &(daemon_local->master));
901 if (daemon_local->fdserial > daemon_local->fdmax)
903 daemon_local->fdmax = daemon_local->fdserial;
906 if (daemon_local->flags.vflag)
908 dlt_log(LOG_INFO, "Serial init done\n");
913 close(daemon_local->fdserial);
914 fprintf(stderr,"Device is not a serial device, device = %s (%s) \n", daemon_local->flags.yvalue, strerror(errno));
915 daemon_local->flags.yvalue[0] = 0;
923 int dlt_daemon_local_ecu_version_init(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
925 char *version = NULL;
928 PRINT_FUNCTION_VERBOSE(verbose);
930 /* By default, version string is null. */
931 daemon->ECUVersionString = NULL;
933 /* Open the file. Bail out if error occurs */
934 f = fopen(daemon_local->flags.pathToECUSoftwareVersion, "r");
937 /* Error level notice, because this might be deliberate choice */
938 dlt_log(LOG_NOTICE, "Failed to open ECU Software version file.\n");
942 /* Get the file size. Bail out if stat fails. */
945 if(fstat(fd, &s_buf) < 0)
947 dlt_log(LOG_ERR, "Failed to stat ECU Software version file.\n");
952 /* Bail out if file is too large. Use DLT_DAEMON_TEXTBUFSIZE max.
953 * Reserve one byte for trailing '\0' */
954 off_t size = s_buf.st_size;
955 if(size >= DLT_DAEMON_TEXTBUFSIZE)
957 dlt_log(LOG_ERR, "Too large file for ECU version.\n");
962 /* Allocate permanent buffer for version info */
963 version = malloc(size + 1);
967 offset += fread(version + offset, 1, size, f);
970 dlt_log(LOG_ERR, "Failed to read ECU Software version file.\n");
977 dlt_log(LOG_ERR, "Too long file for ECU Software version info.\n");
983 version[offset] = '\0';//append null termination at end of version string
984 daemon->ECUVersionString = version;
989 void dlt_daemon_local_cleanup(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
991 PRINT_FUNCTION_VERBOSE(verbose);
993 if ((daemon==0) || (daemon_local==0))
995 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_local_cleanup()\n");
1000 dlt_receiver_free(&(daemon_local->receiver));
1002 dlt_receiver_free(&(daemon_local->receiverSock));
1005 dlt_message_free(&(daemon_local->msg),daemon_local->flags.vflag);
1006 close(daemon_local->fp);
1008 /* free shared memory */
1009 if(daemon_local->flags.offlineTraceDirectory[0])
1010 dlt_offline_trace_free(&(daemon_local->offlineTrace));
1012 if (daemon_local->flags.ovalue[0])
1014 close(daemon_local->ohandle);
1019 dlt_file_free(&(daemon_local->file),daemon_local->flags.vflag);
1021 /* Try to delete existing pipe, ignore result of unlink() */
1022 unlink(DLT_USER_FIFO);
1024 #ifdef DLT_SHM_ENABLE
1025 /* free shared memory */
1026 dlt_shm_free_server(&(daemon_local->dlt_shm));
1029 /* Try to delete lock file, ignore result of unlink() */
1030 unlink(DLT_DAEMON_LOCK_FILE);
1033 void dlt_daemon_signal_handler(int sig)
1042 /* finalize the server */
1043 //dlt_log("terminate signal catched");
1044 dlt_log(LOG_NOTICE, "Exiting DLT daemon\n");
1046 /* Try to delete existing pipe, ignore result of unlink() */
1047 unlink(DLT_USER_FIFO);
1049 /* Try to delete lock file, ignore result of unlink() */
1050 unlink(DLT_DAEMON_LOCK_FILE);
1052 /* Terminate program */
1058 /* This case should never occur */
1062 } /* dlt_daemon_signal_handler() */
1064 void dlt_daemon_daemonize(int verbose)
1069 PRINT_FUNCTION_VERBOSE(verbose);
1071 dlt_log(LOG_NOTICE, "Daemon mode\n");
1077 dlt_log(LOG_CRIT, "Unable to fork(), exiting DLT daemon\n");
1078 exit(-1); /* fork error */
1083 exit(0); /* parent exits */
1085 /* child (daemon) continues */
1087 /* Process independency */
1089 /* obtain a new process group */
1092 dlt_log(LOG_CRIT, "setsid() failed, exiting DLT daemon\n");
1093 exit(-1); /* fork error */
1096 /* Close descriptors */
1097 for (i=getdtablesize();i>=0;--i)
1099 close(i); /* close all descriptors */
1102 /* Open standard descriptors stdin, stdout, stderr */
1103 i=open("/dev/null",O_RDWR); /* open stdin */
1107 dlt_log(LOG_ERR, "Failed to direct stdout to /dev/null.\n");/* stdout */
1109 dlt_log(LOG_ERR, "Failed to direct stderr to /dev/null.\n"); /* stderr */
1113 umask(DLT_DAEMON_UMASK);
1115 /* Change to known directory */
1116 if(chdir(DLT_USER_DIR) < 0)
1117 dlt_log(LOG_ERR, "Failed to chdir to DLT_USER_DIR.\n");;
1119 /* Ensure single copy of daemon;
1120 run only one instance at a time */
1121 lfp=open(DLT_DAEMON_LOCK_FILE,O_RDWR|O_CREAT,DLT_DAEMON_LOCK_FILE_PERM);
1124 dlt_log(LOG_CRIT, "can't open lock file, exiting DLT daemon\n");
1125 exit(-1); /* can not open */
1127 if (lockf(lfp,F_TLOCK,0)<0)
1129 dlt_log(LOG_CRIT, "can't lock lock file, exiting DLT daemon\n");
1130 exit(-1); /* can not lock */
1132 /* only first instance continues */
1134 sprintf(str,"%d\n",getpid());
1135 pid_len = strlen(str);
1136 if(write(lfp,str,pid_len) != pid_len) /* record pid to lockfile */
1137 dlt_log(LOG_ERR, "Could not write pid to file in dlt_daemon_daemonize.\n");
1140 signal(SIGCHLD,SIG_IGN); /* ignore child */
1141 signal(SIGTSTP,SIG_IGN); /* ignore tty signals */
1142 signal(SIGTTOU,SIG_IGN);
1143 signal(SIGTTIN,SIG_IGN);
1145 } /* dlt_daemon_daemonize() */
1147 int dlt_daemon_process_client_connect(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1150 struct sockaddr cli;
1154 PRINT_FUNCTION_VERBOSE(verbose);
1156 if ((daemon==0) || (daemon_local==0))
1158 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_client_connect()\n");
1162 /* event from TCP server socket, new connection */
1163 cli_size = sizeof(cli);
1164 if ((in_sock = accept(daemon_local->sock,&cli, &cli_size)) < 0)
1166 dlt_log(LOG_ERR, "accept() failed!\n");
1170 /* check if file file descriptor was already used, and make it invalid if it is reused */
1171 /* This prevents sending messages to wrong file descriptor */
1172 dlt_daemon_applications_invalidate_fd(daemon,in_sock,verbose);
1173 dlt_daemon_contexts_invalidate_fd(daemon,in_sock,verbose);
1175 /* Set socket timeout in reception */
1176 struct timeval timeout_send;
1177 timeout_send.tv_sec = daemon_local->timeoutOnSend;
1178 timeout_send.tv_usec = 0;
1179 if (setsockopt (in_sock, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout_send, sizeof(timeout_send)) < 0)
1180 dlt_log(LOG_ERR, "setsockopt failed\n");
1182 //sprintf("str,"Client Connection from %s\n", inet_ntoa(cli.sin_addr));
1184 FD_SET(in_sock, &(daemon_local->master)); /* add to master set */
1185 if (in_sock > daemon_local->fdmax)
1187 /* keep track of the maximum */
1188 daemon_local->fdmax = in_sock;
1191 daemon_local->client_connections++;
1192 if (daemon_local->flags.vflag)
1194 sprintf(str, "New connection to client established, #connections: %d\n",daemon_local->client_connections);
1195 dlt_log(LOG_INFO, str);
1198 // send connection info about connected
1199 dlt_daemon_control_message_connection_info(in_sock,daemon,DLT_CONNECTION_STATUS_CONNECTED,"",verbose);
1201 // send ecu version string
1202 if(daemon_local->flags.sendECUSoftwareVersion > 0)
1204 dlt_daemon_send_ecuversion(daemon,daemon_local);
1207 if (daemon_local->client_connections==1)
1209 if (daemon_local->flags.vflag)
1211 dlt_log(LOG_INFO, "Send ring-buffer to client\n");
1213 if (dlt_daemon_send_ringbuffer_to_client(daemon, daemon_local, verbose)==-1)
1215 dlt_log(LOG_ERR,"Can't send contents of ringbuffer to clients\n");
1219 /* send new log state to all applications */
1221 dlt_daemon_user_send_all_log_state(daemon,verbose);
1227 int dlt_daemon_process_client_messages(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1229 int bytes_to_be_removed=0;
1231 PRINT_FUNCTION_VERBOSE(verbose);
1233 if ((daemon==0) || (daemon_local==0))
1235 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_client_messages()\n");
1239 if (dlt_receiver_receive_socket(&(daemon_local->receiverSock))<=0)
1241 dlt_daemon_close_socket(daemon_local->receiverSock.fd, daemon, daemon_local, verbose);
1242 daemon_local->receiverSock.fd = -1;
1243 /* check: return 0; */
1246 /* Process all received messages */
1247 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)
1249 /* Check for control message */
1250 if ( 0 < daemon_local->receiverSock.fd && DLT_MSG_IS_CONTROL_REQUEST(&(daemon_local->msg)) )
1252 dlt_daemon_control_process_control(daemon_local->receiverSock.fd, daemon, &(daemon_local->msg), daemon_local->flags.vflag);
1255 bytes_to_be_removed = daemon_local->msg.headersize+daemon_local->msg.datasize-sizeof(DltStorageHeader);
1256 if (daemon_local->msg.found_serialheader)
1258 bytes_to_be_removed += sizeof(dltSerialHeader);
1260 if (daemon_local->msg.resync_offset)
1262 bytes_to_be_removed += daemon_local->msg.resync_offset;
1265 if (dlt_receiver_remove(&(daemon_local->receiverSock),bytes_to_be_removed)==-1)
1267 dlt_log(LOG_ERR,"Can't remove bytes from receiver for sockets\n");
1274 if (dlt_receiver_move_to_begin(&(daemon_local->receiverSock))==-1)
1276 dlt_log(LOG_ERR,"Can't move bytes to beginning of receiver buffer for sockets\n");
1283 int dlt_daemon_process_client_messages_serial(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1285 int bytes_to_be_removed=0;
1287 PRINT_FUNCTION_VERBOSE(verbose);
1289 if ((daemon==0) || (daemon_local==0))
1291 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_client_messages_serial()\n");
1295 if (dlt_receiver_receive_fd(&(daemon_local->receiverSerial))<=0)
1297 dlt_log(LOG_ERR, "dlt_receiver_receive_fd() for messages from serial interface failed!\n");
1301 /* Process all received messages */
1302 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)
1304 /* Check for control message */
1305 if (DLT_MSG_IS_CONTROL_REQUEST(&(daemon_local->msg)))
1307 if (dlt_daemon_control_process_control(daemon_local->receiverSerial.fd, daemon, &(daemon_local->msg), daemon_local->flags.vflag)==-1)
1309 dlt_log(LOG_ERR,"Can't process control messages\n");
1314 bytes_to_be_removed = daemon_local->msg.headersize+daemon_local->msg.datasize-sizeof(DltStorageHeader);
1315 if (daemon_local->msg.found_serialheader)
1317 bytes_to_be_removed += sizeof(dltSerialHeader);
1319 if (daemon_local->msg.resync_offset)
1321 bytes_to_be_removed += daemon_local->msg.resync_offset;
1324 if (dlt_receiver_remove(&(daemon_local->receiverSerial),bytes_to_be_removed)==-1)
1326 dlt_log(LOG_ERR,"Can't remove bytes from receiver for serial connection\n");
1333 if (dlt_receiver_move_to_begin(&(daemon_local->receiverSerial))==-1)
1335 dlt_log(LOG_ERR,"Can't move bytes to beginning of receiver buffer for serial connection\n");
1342 int dlt_daemon_process_user_messages(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1346 DltUserHeader *userheader;
1348 PRINT_FUNCTION_VERBOSE(verbose);
1350 if ((daemon==0) || (daemon_local==0))
1352 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_messages()\n");
1356 /* read data from FIFO */
1357 if (dlt_receiver_receive_fd(&(daemon_local->receiver))<0)
1359 dlt_log(LOG_ERR, "dlt_receiver_receive_fd() for user messages failed!\n");
1363 /* look through buffer as long as data is in there */
1366 if (daemon_local->receiver.bytesRcvd < (int32_t)sizeof(DltUserHeader))
1371 /* resync if necessary */
1375 userheader = (DltUserHeader*) (daemon_local->receiver.buf+offset);
1377 /* Check for user header pattern */
1378 if (dlt_user_check_userheader(userheader))
1386 while ((int32_t)(sizeof(DltUserHeader)+offset)<=daemon_local->receiver.bytesRcvd);
1388 /* Check for user header pattern */
1389 if (dlt_user_check_userheader(userheader)==0)
1394 /* Set new start offset */
1397 daemon_local->receiver.buf+=offset;
1398 daemon_local->receiver.bytesRcvd-=offset;
1401 switch (userheader->message)
1403 case DLT_USER_MESSAGE_OVERFLOW:
1405 if (dlt_daemon_process_user_message_overflow(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1411 case DLT_USER_MESSAGE_REGISTER_CONTEXT:
1413 if (dlt_daemon_process_user_message_register_context(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1419 case DLT_USER_MESSAGE_UNREGISTER_CONTEXT:
1421 if (dlt_daemon_process_user_message_unregister_context(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1427 case DLT_USER_MESSAGE_LOG:
1429 if (dlt_daemon_process_user_message_log(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1435 #ifdef DLT_SHM_ENABLE
1436 case DLT_USER_MESSAGE_LOG_SHM:
1438 if (dlt_daemon_process_user_message_log_shm(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1445 case DLT_USER_MESSAGE_REGISTER_APPLICATION:
1447 if (dlt_daemon_process_user_message_register_application(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1453 case DLT_USER_MESSAGE_UNREGISTER_APPLICATION:
1455 if (dlt_daemon_process_user_message_unregister_application(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1461 case DLT_USER_MESSAGE_APP_LL_TS:
1463 if (dlt_daemon_process_user_message_set_app_ll_ts(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1469 case DLT_USER_MESSAGE_LOG_MODE:
1471 if (dlt_daemon_process_user_message_log_mode(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1479 dlt_log(LOG_ERR,"(Internal) Invalid user message type received!\n");
1481 /* remove user header */
1482 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader))==-1)
1484 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user messages\n");
1488 /* In next invocation of do-while loop, a resync will be triggered if additional data was received */
1498 /* keep not read data in buffer */
1499 if (dlt_receiver_move_to_begin(&(daemon_local->receiver))==-1)
1501 dlt_log(LOG_ERR,"Can't move bytes to beginning of receiver buffer for user messages\n");
1508 int dlt_daemon_process_user_message_overflow(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1511 DltUserControlMsgBufferOverflow *userpayload;
1513 PRINT_FUNCTION_VERBOSE(verbose);
1515 if ((daemon==0) || (daemon_local==0))
1517 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_overflow()\n");
1521 if (daemon_local->receiver.bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgBufferOverflow)))
1523 /* Not enough bytes received */
1527 /* get the payload of the user message */
1528 userpayload = (DltUserControlMsgBufferOverflow*) (daemon_local->receiver.buf+sizeof(DltUserHeader));
1530 /* Store in daemon, that a message buffer overflow has occured */
1531 daemon->message_buffer_overflow = DLT_MESSAGE_BUFFER_OVERFLOW;
1533 /* look if TCP connection to client is available */
1536 for (j = 0; j <= daemon_local->fdmax; j++)
1538 /* send to everyone! */
1539 if (FD_ISSET(j, &(daemon_local->master)))
1541 /* except the listener and ourselves */
1542 if ((j != daemon_local->fp) && (j != daemon_local->sock)
1543 #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE
1544 && (j!=daemon_local->timer_wd)
1546 && (j!=daemon_local->timer_timingpacket) && (j!=daemon_local->timer_ecuversion))
1548 dlt_daemon_control_message_buffer_overflow(j, daemon, userpayload->overflow_counter,userpayload->apid,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 if(dlt_daemon_control_message_buffer_overflow(DLT_DAEMON_STORE_TO_BUFFER, daemon, userpayload->overflow_counter,
1560 userpayload->apid,verbose))
1562 /* there was an error when storing message */
1563 /* add the counter of lost messages to the daemon counter */
1564 daemon->overflow_counter+=userpayload->overflow_counter;
1568 /* keep not read data in buffer */
1569 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgBufferOverflow))==-1)
1571 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message overflow\n");
1578 int dlt_daemon_send_message_overflow(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1582 PRINT_FUNCTION_VERBOSE(verbose);
1584 if ((daemon==0) || (daemon_local==0))
1586 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_overflow()\n");
1590 /* Store in daemon, that a message buffer overflow has occured */
1591 daemon->message_buffer_overflow = DLT_MESSAGE_BUFFER_OVERFLOW;
1593 /* look if TCP connection to client is available */
1596 for (j = 0; j <= daemon_local->fdmax; j++)
1598 /* send to everyone! */
1599 if (FD_ISSET(j, &(daemon_local->master)))
1601 /* except the listener and ourselves */
1602 if ((j != daemon_local->fp) && (j != daemon_local->sock)
1603 #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE
1604 && (j!=daemon_local->timer_wd)
1606 && (j!=daemon_local->timer_timingpacket) && (j!=daemon_local->timer_ecuversion))
1608 dlt_daemon_control_message_buffer_overflow(j, daemon,daemon->overflow_counter,"", verbose);
1610 /* Reset overflow state */
1611 daemon->message_buffer_overflow = DLT_MESSAGE_BUFFER_NO_OVERFLOW;
1616 /* message was not sent, so report to caller that sending failed */
1625 int dlt_daemon_process_user_message_register_application(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1628 DltDaemonApplication *application;
1629 char description[DLT_DAEMON_DESCSIZE];
1630 DltUserControlMsgRegisterApplication *usercontext;
1632 PRINT_FUNCTION_VERBOSE(verbose);
1634 if ((daemon==0) || (daemon_local==0))
1636 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_register_application()\n");
1640 if (daemon_local->receiver.bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterApplication)))
1642 /* Not enough bytes received */
1646 usercontext = (DltUserControlMsgRegisterApplication*) (daemon_local->receiver.buf+sizeof(DltUserHeader));
1648 memset(description,0,sizeof(description));
1650 len=usercontext->description_length;
1651 if ((len>0) && (len<=DLT_DAEMON_DESCSIZE))
1653 /* Read and store application description */
1654 strncpy(description, (daemon_local->receiver.buf+sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterApplication)), len);
1657 application=dlt_daemon_application_add(daemon,usercontext->apid,usercontext->pid,description,verbose);
1659 /* send log state to new application */
1660 dlt_daemon_user_send_log_state(daemon,application,verbose);
1662 /* keep not read data in buffer */
1663 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterApplication)+len)==-1)
1665 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register application\n");
1671 dlt_log(LOG_CRIT,"Can't add application");
1678 int dlt_daemon_process_user_message_register_context(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1681 int8_t loglevel, tracestatus;
1682 DltUserControlMsgRegisterContext *usercontext;
1683 char description[DLT_DAEMON_DESCSIZE];
1684 DltDaemonApplication *application;
1685 DltDaemonContext *context;
1686 DltServiceGetLogInfoRequest *req;
1692 PRINT_FUNCTION_VERBOSE(verbose);
1694 if ((daemon==0) || (daemon_local==0))
1696 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_register_context()\n");
1700 if (daemon_local->receiver.bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)))
1702 /* Not enough bytes received */
1706 usercontext = (DltUserControlMsgRegisterContext*) (daemon_local->receiver.buf+sizeof(DltUserHeader));
1708 memset(description,0,sizeof(description));
1710 len=usercontext->description_length;
1711 if ((len>0) && (len<=DLT_DAEMON_DESCSIZE))
1713 /* Read and store context description */
1714 strncpy(description, (daemon_local->receiver.buf+sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)), len);
1717 application = dlt_daemon_application_find(daemon,usercontext->apid,verbose);
1721 dlt_log(LOG_ERR, "Application not found in dlt_daemon_process_user_message_register_context()\n");
1722 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)+len)==-1)
1724 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register context\n");
1730 /* Pre-set loglevel */
1731 if (usercontext->log_level == DLT_USER_LOG_LEVEL_NOT_SET)
1733 loglevel=DLT_LOG_DEFAULT;
1737 loglevel=usercontext->log_level;
1738 /* Plausibility check */
1739 if ((loglevel<DLT_LOG_DEFAULT) || (loglevel>DLT_LOG_VERBOSE))
1741 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)+len)==-1)
1743 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register context\n");
1749 /* Pre-set tracestatus */
1750 if (usercontext->trace_status == DLT_USER_TRACE_STATUS_NOT_SET)
1752 tracestatus=DLT_TRACE_STATUS_DEFAULT;
1756 tracestatus=usercontext->trace_status;
1758 /* Plausibility check */
1759 if ((tracestatus<DLT_TRACE_STATUS_DEFAULT) || (tracestatus>DLT_TRACE_STATUS_ON))
1761 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)+len)==-1)
1763 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register context\n");
1769 context = dlt_daemon_context_add(daemon,usercontext->apid,usercontext->ctid, loglevel, tracestatus, usercontext->log_level_pos,application->user_handle,description,verbose);
1773 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)+len)==-1)
1775 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register context\n");
1778 dlt_log(LOG_CRIT,"Can't add context");
1781 /* Create automatic get log info response for registered context */
1782 if (daemon_local->flags.rflag)
1784 /* Prepare request for get log info with one application and one context */
1785 if (dlt_message_init(&msg, verbose)==-1)
1787 dlt_log(LOG_ERR,"Can't initialize message");
1791 msg.datasize = sizeof(DltServiceGetLogInfoRequest);
1792 if (msg.databuffer && (msg.databuffersize < msg.datasize))
1794 free(msg.databuffer);
1797 if (msg.databuffer == 0){
1798 msg.databuffer = (uint8_t *) malloc(msg.datasize);
1799 msg.databuffersize = msg.datasize;
1801 if (msg.databuffer==0)
1803 dlt_log(LOG_ERR,"Can't allocate buffer for get log info message\n");
1807 req = (DltServiceGetLogInfoRequest*) msg.databuffer;
1809 req->service_id = DLT_SERVICE_ID_GET_LOG_INFO;
1811 dlt_set_id(req->apid, usercontext->apid);
1812 dlt_set_id(req->ctid, usercontext->ctid);
1813 dlt_set_id(req->com,"remo");
1817 /* Send response to get log info request to DLT clients */
1818 for (j = 0; j <= daemon_local->fdmax; j++)
1820 /* send to everyone! */
1821 if (FD_ISSET(j, &(daemon_local->master)))
1823 /* except the listener and ourselves */
1824 if ((j != daemon_local->fp) && (j != daemon_local->sock)
1825 #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE
1826 && (j!=daemon_local->timer_wd)
1828 && (j!=daemon_local->timer_timingpacket) && (j!=daemon_local->timer_ecuversion))
1830 dlt_daemon_control_get_log_info(j , daemon, &msg, verbose);
1838 /* Store to buffer */
1839 dlt_daemon_control_get_log_info(DLT_DAEMON_STORE_TO_BUFFER , daemon, &msg, verbose);
1842 dlt_message_free(&msg, verbose);
1845 if (context->user_handle >= DLT_FD_MINIMUM)
1847 /* This call also replaces the default values with the values defined for default */
1848 if (dlt_daemon_user_send_log_level(daemon, context, verbose)==-1)
1850 dlt_log(LOG_ERR,"Can't send current log level as response to user message register context\n");
1855 /* keep not read data in buffer */
1856 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)+len)==-1)
1858 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register context\n");
1865 int dlt_daemon_process_user_message_unregister_application(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1867 DltUserControlMsgUnregisterApplication *usercontext;
1868 DltDaemonApplication *application;
1869 DltDaemonContext *context;
1872 PRINT_FUNCTION_VERBOSE(verbose);
1874 if ((daemon==0) || (daemon_local==0))
1876 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_unregister_application()\n");
1880 if (daemon_local->receiver.bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgUnregisterApplication)))
1882 /* Not enough bytes received */
1886 if (daemon->num_applications>0)
1888 usercontext = (DltUserControlMsgUnregisterApplication*) (daemon_local->receiver.buf+sizeof(DltUserHeader));
1890 /* Delete this application and all corresponding contexts for this application from internal table */
1891 application = dlt_daemon_application_find(daemon,usercontext->apid, verbose);
1895 /* Calculate start offset within contexts[] */
1897 for (i=0; i<(application-(daemon->applications)); i++)
1899 offset_base+=daemon->applications[i].num_contexts;
1902 for (i=application->num_contexts-1; i>=0; i--)
1904 context = &(daemon->contexts[offset_base+i]);
1907 /* Delete context */
1908 if (dlt_daemon_context_del(daemon, context, verbose)==-1)
1910 dlt_log(LOG_ERR,"Can't delete context for user message unregister application\n");
1916 /* Delete this application entry from internal table*/
1917 if (dlt_daemon_application_del(daemon, application, verbose)==-1)
1919 dlt_log(LOG_ERR,"Can't delete application for user message unregister application\n");
1925 /* keep not read data in buffer */
1926 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgUnregisterApplication))==-1)
1928 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message unregister application\n");
1935 int dlt_daemon_process_user_message_unregister_context(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1937 DltUserControlMsgUnregisterContext *usercontext;
1938 DltDaemonContext *context;
1940 PRINT_FUNCTION_VERBOSE(verbose);
1942 if ((daemon==0) || (daemon_local==0))
1944 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_unregister_context()\n");
1948 if (daemon_local->receiver.bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgUnregisterContext)))
1950 /* Not enough bytes received */
1954 usercontext = (DltUserControlMsgUnregisterContext*) (daemon_local->receiver.buf+sizeof(DltUserHeader));
1955 context = dlt_daemon_context_find(daemon,usercontext->apid, usercontext->ctid, verbose);
1959 /* Delete this connection entry from internal table*/
1960 if (dlt_daemon_context_del(daemon, context, verbose)==-1)
1962 dlt_log(LOG_ERR,"Can't delete context for user message unregister context\n");
1967 /* Create automatic unregister context response for unregistered context */
1968 if (daemon_local->flags.rflag)
1973 /* Send response to get log info request to DLT clients */
1974 for (j = 0; j <= daemon_local->fdmax; j++)
1976 /* send to everyone! */
1977 if (FD_ISSET(j, &(daemon_local->master)))
1979 /* except the listener and ourselves */
1980 if ((j != daemon_local->fp) && (j != daemon_local->sock)
1981 #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE
1982 && (j!=daemon_local->timer_wd)
1984 && (j!=daemon_local->timer_timingpacket) && (j!=daemon_local->timer_ecuversion))
1986 dlt_daemon_control_message_unregister_context(j,daemon,usercontext->apid, usercontext->ctid, "remo",verbose);
1994 /* Store to buffer */
1995 dlt_daemon_control_message_unregister_context(DLT_DAEMON_STORE_TO_BUFFER,daemon,usercontext->apid, usercontext->ctid, "remo",verbose);
1999 /* keep not read data in buffer */
2000 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgUnregisterContext))==-1)
2002 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message unregister context\n");
2009 int dlt_daemon_process_user_message_log(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
2011 int bytes_to_be_removed;
2012 int j,sent,third_value;
2015 static char text[DLT_DAEMON_TEXTSIZE];
2017 PRINT_FUNCTION_VERBOSE(verbose);
2019 if ((daemon==0) || (daemon_local==0))
2021 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_log()\n");
2025 if (dlt_message_read(&(daemon_local->msg),(unsigned char*)daemon_local->receiver.buf+sizeof(DltUserHeader),daemon_local->receiver.bytesRcvd-sizeof(DltUserHeader),0,verbose)==0)
2027 /* set overwrite ecu id */
2028 if (daemon_local->flags.evalue!=0)
2030 /* Set header extra parameters */
2031 dlt_set_id(daemon_local->msg.headerextra.ecu, daemon->ecuid );
2032 //msg.headerextra.seid = 0;
2033 if (dlt_message_set_extraparameters(&(daemon_local->msg),0)==-1)
2035 dlt_log(LOG_ERR,"Can't set message extra parameters in process user message log\n");
2039 /* Correct value of timestamp, this was changed by dlt_message_set_extraparameters() */
2040 daemon_local->msg.headerextra.tmsp = DLT_BETOH_32(daemon_local->msg.headerextra.tmsp);
2043 /* prepare storage header */
2044 if (DLT_IS_HTYP_WEID(daemon_local->msg.standardheader->htyp))
2046 if (dlt_set_storageheader(daemon_local->msg.storageheader,daemon_local->msg.headerextra.ecu)==-1)
2048 dlt_log(LOG_ERR,"Can't set storage header in process user message log\n");
2054 if (dlt_set_storageheader(daemon_local->msg.storageheader,daemon->ecuid)==-1)
2056 dlt_log(LOG_ERR,"Can't set storage header in process user message log\n");
2062 /* if no filter set or filter is matching display message */
2063 if (daemon_local->flags.xflag)
2065 if (dlt_message_print_hex(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1)
2067 dlt_log(LOG_ERR,"dlt_message_print_hex() failed!\n");
2070 else if (daemon_local->flags.aflag)
2072 if (dlt_message_print_ascii(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1)
2074 dlt_log(LOG_ERR,"dlt_message_print_ascii() failed!\n");
2077 else if (daemon_local->flags.sflag)
2079 if (dlt_message_print_header(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1)
2081 dlt_log(LOG_ERR,"dlt_message_print_header() failed!\n");
2083 /* print message header only */
2088 /* write message to offline trace */
2089 if(((daemon->mode == DLT_USER_MODE_INTERNAL) || (daemon->mode == DLT_USER_MODE_BOTH)) && daemon_local->flags.offlineTraceDirectory[0])
2091 dlt_offline_trace_write(&(daemon_local->offlineTrace),daemon_local->msg.headerbuffer,daemon_local->msg.headersize,
2092 daemon_local->msg.databuffer,daemon_local->msg.datasize,0,0);
2096 /* check if overflow occurred */
2097 if(daemon->overflow_counter)
2099 if(dlt_daemon_send_message_overflow(daemon,daemon_local,verbose)==0)
2101 sprintf(str,"%u messages discarded!\n",daemon->overflow_counter);
2102 dlt_log(LOG_ERR, str);
2103 daemon->overflow_counter=0;
2107 /* look if TCP connection to client is available */
2108 for (j = 0;((daemon->mode == DLT_USER_MODE_EXTERNAL) || (daemon->mode == DLT_USER_MODE_BOTH)) && (j <= daemon_local->fdmax); j++)
2110 /* send to everyone! */
2111 if (FD_ISSET(j, &(daemon_local->master)))
2113 /* except the listener and ourselves */
2114 if (daemon_local->flags.yvalue[0])
2116 third_value = daemon_local->fdserial;
2120 third_value = daemon_local->sock;
2123 if ((j != daemon_local->fp) && (j != daemon_local->sock) && (j != third_value)
2124 #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE
2125 && (j!=daemon_local->timer_wd)
2127 && (j!=daemon_local->timer_timingpacket) && (j!=daemon_local->timer_ecuversion))
2131 DLT_DAEMON_SEM_LOCK();
2133 if (daemon_local->flags.lflag)
2135 if(0 > send(j,dltSerialHeader,sizeof(dltSerialHeader),0))
2137 dlt_daemon_close_socket(j, daemon, daemon_local, verbose);
2142 if(!failed && 0 > send(j,daemon_local->msg.headerbuffer+sizeof(DltStorageHeader),daemon_local->msg.headersize-sizeof(DltStorageHeader),0))
2144 dlt_daemon_close_socket(j, daemon, daemon_local, verbose);
2148 if(!failed && 0 > send(j,daemon_local->msg.databuffer,daemon_local->msg.datasize,0))
2150 dlt_daemon_close_socket(j, daemon, daemon_local, verbose);
2154 DLT_DAEMON_SEM_FREE();
2158 else if ((j == daemon_local->fdserial) && (daemon_local->flags.yvalue!=0))
2160 DLT_DAEMON_SEM_LOCK();
2162 if (daemon_local->flags.lflag)
2164 ret=write(j,dltSerialHeader,sizeof(dltSerialHeader));
2167 dlt_log(LOG_ERR,"write(j,dltSerialHeader failed\n");
2170 int32_t diff = daemon_local->msg.headersize-sizeof(DltStorageHeader);
2171 //extra calculation for coverity
2173 ret=write(j,daemon_local->msg.headerbuffer+sizeof(DltStorageHeader),diff);
2176 dlt_log(LOG_ERR,"write(j,daemon_local->msg.headerbuffer failed\n");
2178 ret=write(j,daemon_local->msg.databuffer,daemon_local->msg.datasize);
2181 dlt_log(LOG_ERR,"write(j,daemon_local->msg.databuffer failed\n");
2185 DLT_DAEMON_SEM_FREE();
2192 /* Message was not sent to client, so store it in client ringbuffer */
2195 DLT_DAEMON_SEM_LOCK();
2196 if (dlt_buffer_push3(&(daemon->client_ringbuffer),
2197 daemon_local->msg.headerbuffer+sizeof(DltStorageHeader),daemon_local->msg.headersize-sizeof(DltStorageHeader),
2198 daemon_local->msg.databuffer,daemon_local->msg.datasize,
2202 if(daemon->overflow_counter==0)
2203 dlt_log(LOG_ERR,"Buffer full! Messages will be discarded.\n");
2204 daemon->overflow_counter+=1;
2206 DLT_DAEMON_SEM_FREE();
2210 /* keep not read data in buffer */
2211 bytes_to_be_removed = daemon_local->msg.headersize+daemon_local->msg.datasize-sizeof(DltStorageHeader)+sizeof(DltUserHeader);
2212 if (daemon_local->msg.found_serialheader)
2214 bytes_to_be_removed += sizeof(dltSerialHeader);
2217 if (dlt_receiver_remove(&(daemon_local->receiver),bytes_to_be_removed)==-1)
2219 dlt_log(LOG_ERR,"Can't remove bytes from receiver\n");
2225 dlt_log(LOG_ERR,"Can't read messages from receiver\n");
2232 #ifdef DLT_SHM_ENABLE
2233 int dlt_daemon_process_user_message_log_shm(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
2235 int bytes_to_be_removed=0;
2236 int j,sent,third_value;
2238 uint8_t rcv_buffer[10000];
2240 DltUserHeader *userheader;
2242 static char text[DLT_DAEMON_TEXTSIZE];
2244 PRINT_FUNCTION_VERBOSE(verbose);
2246 if ((daemon==0) || (daemon_local==0))
2248 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_log()\n");
2252 userheader = (DltUserHeader*) (daemon_local->receiver.buf);
2254 //dlt_shm_status(&(daemon_local->dlt_shm));
2257 /* log message in SHM */
2258 if((size = dlt_shm_copy(&(daemon_local->dlt_shm),rcv_buffer,10000)) <= 0)
2260 if (dlt_message_read(&(daemon_local->msg),rcv_buffer,size,0,verbose)!=0) {
2262 dlt_log(LOG_ERR,"Can't read messages from shm\n");
2265 bytes_to_be_removed = daemon_local->msg.headersize+daemon_local->msg.datasize-sizeof(DltStorageHeader)+sizeof(DltUserHeader);
2266 if (daemon_local->msg.found_serialheader)
2268 bytes_to_be_removed += sizeof(dltSerialHeader);
2271 /* set overwrite ecu id */
2272 if (daemon_local->flags.evalue[0])
2274 /* Set header extra parameters */
2275 dlt_set_id(daemon_local->msg.headerextra.ecu, daemon->ecuid );
2276 //msg.headerextra.seid = 0;
2277 if (dlt_message_set_extraparameters(&(daemon_local->msg),0)==-1)
2279 dlt_log(LOG_ERR,"Can't set message extra parameters in process user message log\n");
2280 dlt_shm_remove(&(daemon_local->dlt_shm));
2284 /* Correct value of timestamp, this was changed by dlt_message_set_extraparameters() */
2285 daemon_local->msg.headerextra.tmsp = DLT_BETOH_32(daemon_local->msg.headerextra.tmsp);
2288 /* prepare storage header */
2289 if (DLT_IS_HTYP_WEID(daemon_local->msg.standardheader->htyp))
2291 if (dlt_set_storageheader(daemon_local->msg.storageheader,daemon_local->msg.headerextra.ecu)==-1)
2293 dlt_log(LOG_ERR,"Can't set storage header in process user message log\n");
2294 dlt_shm_remove(&(daemon_local->dlt_shm));
2300 if (dlt_set_storageheader(daemon_local->msg.storageheader,daemon->ecuid)==-1)
2302 dlt_log(LOG_ERR,"Can't set storage header in process user message log\n");
2303 dlt_shm_remove(&(daemon_local->dlt_shm));
2308 /* display message */
2309 if (daemon_local->flags.xflag)
2311 if (dlt_message_print_hex(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1)
2313 dlt_log(LOG_ERR,"dlt_message_print_hex() failed!\n");
2316 else if (daemon_local->flags.aflag)
2318 if (dlt_message_print_ascii(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1)
2320 dlt_log(LOG_ERR,"dlt_message_print_ascii() failed!\n");
2323 else if (daemon_local->flags.sflag)
2325 if (dlt_message_print_header(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1)
2327 dlt_log(LOG_ERR,"dlt_message_print_header() failed!\n");
2329 /* print message header only */
2334 /* write message to offline trace */
2335 if(((daemon->mode == DLT_USER_MODE_INTERNAL) || (daemon->mode == DLT_USER_MODE_BOTH)) && daemon_local->flags.offlineTraceDirectory[0])
2337 dlt_offline_trace_write(&(daemon_local->offlineTrace),daemon_local->msg.headerbuffer,daemon_local->msg.headersize,
2338 daemon_local->msg.databuffer,daemon_local->msg.datasize,0,0);
2342 /* look if TCP connection to client is available */
2343 for (j = 0;((daemon->mode == DLT_USER_MODE_EXTERNAL) || (daemon->mode == DLT_USER_MODE_BOTH)) && (j <= daemon_local->fdmax); j++)
2345 /* send to everyone! */
2346 if (FD_ISSET(j, &(daemon_local->master)))
2348 /* except the listener and ourselves */
2349 if (daemon_local->flags.yvalue[0])
2351 third_value = daemon_local->fdserial;
2355 third_value = daemon_local->sock;
2358 if ((j != daemon_local->fp) && (j != daemon_local->sock) && (j != third_value))
2360 DLT_DAEMON_SEM_LOCK();
2362 if (daemon_local->flags.lflag)
2364 send(j,dltSerialHeader,sizeof(dltSerialHeader),0);
2367 send(j,daemon_local->msg.headerbuffer+sizeof(DltStorageHeader),daemon_local->msg.headersize-sizeof(DltStorageHeader),0);
2368 send(j,daemon_local->msg.databuffer,daemon_local->msg.datasize,0);
2370 DLT_DAEMON_SEM_FREE();
2374 else if ((j == daemon_local->fdserial) && (daemon_local->flags.yvalue[0]))
2376 DLT_DAEMON_SEM_LOCK();
2378 if (daemon_local->flags.lflag)
2380 ret=write(j,dltSerialHeader,sizeof(dltSerialHeader));
2383 ret=write(j,daemon_local->msg.headerbuffer+sizeof(DltStorageHeader),daemon_local->msg.headersize-sizeof(DltStorageHeader));
2384 ret=write(j,daemon_local->msg.databuffer,daemon_local->msg.datasize);
2386 DLT_DAEMON_SEM_FREE();
2393 /* Message was not sent to client, so store it in client ringbuffer */
2394 if (sent==1 || (daemon->mode == DLT_USER_MODE_OFF))
2396 if(userheader->message == DLT_USER_MESSAGE_LOG_SHM) {
2397 /* dlt message was sent, remove from buffer if log message from shm */
2398 dlt_shm_remove(&(daemon_local->dlt_shm));
2403 /* dlt message was not sent, keep in buffer */
2409 /* keep not read data in buffer */
2410 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader))==-1)
2412 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message overflow\n");
2420 int dlt_daemon_process_user_message_set_app_ll_ts(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
2422 DltUserControlMsgAppLogLevelTraceStatus *usercontext;
2423 DltDaemonApplication *application;
2424 DltDaemonContext *context;
2426 int8_t old_log_level, old_trace_status;
2428 PRINT_FUNCTION_VERBOSE(verbose);
2430 if ((daemon==0) || (daemon_local==0))
2432 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_set_app_ll_ts()\n");
2436 if (daemon_local->receiver.bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgAppLogLevelTraceStatus )))
2438 /* Not enough bytes receeived */
2442 if (daemon->num_applications>0)
2444 usercontext = (DltUserControlMsgAppLogLevelTraceStatus*) (daemon_local->receiver.buf+sizeof(DltUserHeader));
2446 /* Get all contexts with application id matching the received application id */
2447 application = dlt_daemon_application_find(daemon, usercontext->apid, verbose);
2450 /* Calculate start offset within contexts[] */
2452 for (i=0; i<(application-(daemon->applications)); i++)
2454 offset_base+=daemon->applications[i].num_contexts;
2457 for (i=0; i < application->num_contexts; i++)
2459 context = &(daemon->contexts[offset_base+i]);
2462 old_log_level = context->log_level;
2463 context->log_level = usercontext->log_level; /* No endianess conversion necessary*/
2465 old_trace_status = context->trace_status;
2466 context->trace_status = usercontext->trace_status; /* No endianess conversion necessary */
2468 /* The folowing function sends also the trace status */
2469 if (context->user_handle >= DLT_FD_MINIMUM && dlt_daemon_user_send_log_level(daemon, context, verbose)!=0)
2471 context->log_level = old_log_level;
2472 context->trace_status = old_trace_status;
2479 /* keep not read data in buffer */
2480 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgAppLogLevelTraceStatus))==-1)
2482 dlt_log(LOG_ERR,"Can't remove bytes from receiver\n");
2489 int dlt_daemon_process_user_message_log_mode(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
2491 DltUserControlMsgLogMode *logmode;
2493 PRINT_FUNCTION_VERBOSE(verbose);
2495 if ((daemon==0) || (daemon_local==0))
2497 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_log_mode()\n");
2501 if (daemon_local->receiver.bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgUnregisterContext)))
2503 /* Not enough bytes received */
2507 logmode = (DltUserControlMsgLogMode*) (daemon_local->receiver.buf+sizeof(DltUserHeader));
2509 /* set the new log mode */
2510 daemon->mode = logmode->log_mode;
2512 /* write configuration persistantly */
2513 dlt_daemon_configuration_save(daemon, daemon->runtime_configuration, verbose);
2515 /* keep not read data in buffer */
2516 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogMode))==-1)
2518 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message log mode\n");
2525 int dlt_daemon_send_ringbuffer_to_client(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
2527 static uint8_t data[DLT_DAEMON_RCVBUFSIZE];
2532 PRINT_FUNCTION_VERBOSE(verbose);
2534 if ((daemon==0) || (daemon_local==0))
2536 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_send_ringbuffer_to_client()\n");
2540 /* Attention: If the message can't be send at this time, it will be silently discarded. */
2541 while ((length = dlt_buffer_pull(&(daemon->client_ringbuffer), data, sizeof(data) )) > 0)
2543 /* look if TCP connection to client is available */
2544 for (j = 0; j <= daemon_local->fdmax; j++)
2546 /* send to everyone! */
2547 if (FD_ISSET(j, &(daemon_local->master)))
2549 /* except the listener and ourselves */
2550 if (daemon_local->flags.yvalue[0])
2552 third_value = daemon_local->fdserial;
2556 third_value = daemon_local->sock;
2559 if ((j != daemon_local->fp) && (j != daemon_local->sock) && (j != third_value)
2560 #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE
2561 && (j!=daemon_local->timer_wd)
2563 && (j!=daemon_local->timer_timingpacket) && (j!=daemon_local->timer_ecuversion))
2566 DLT_DAEMON_SEM_LOCK();
2568 if (daemon_local->flags.lflag)
2570 if(!failed && 0 > send(j,dltSerialHeader,sizeof(dltSerialHeader),0))
2572 dlt_daemon_close_socket(j, daemon, daemon_local, verbose);
2576 if(!failed && 0 > send(j,data,length,0))
2578 dlt_daemon_close_socket(j, daemon, daemon_local, verbose);
2582 DLT_DAEMON_SEM_FREE();
2585 else if ((j == daemon_local->fdserial) && (daemon_local->flags.yvalue[0]))
2587 DLT_DAEMON_SEM_LOCK();
2589 if (daemon_local->flags.lflag)
2591 ret=write(j,dltSerialHeader,sizeof(dltSerialHeader));
2594 dlt_log(LOG_ERR, "dlt_daemon_send_ringbuffer_to_client: write(j,dltSerialHeader,sizeof(dltSerialHeader)) failed!\n");
2595 DLT_DAEMON_SEM_FREE();
2599 ret=write(j,data,length);
2602 dlt_log(LOG_ERR, "dlt_daemon_send_ringbuffer_to_client: write(j,data,length) failed!\n");
2603 DLT_DAEMON_SEM_FREE();
2606 DLT_DAEMON_SEM_FREE();
2611 length = sizeof(data);
2617 int dlt_daemon_make_periodic (unsigned int period, DltDaemonPeriodicData *info, int verbose)
2623 struct itimerspec itval;
2625 PRINT_FUNCTION_VERBOSE(verbose);
2629 dlt_log(LOG_ERR,"No data pointer passed!\n");
2633 /* Create the timer */
2634 fd = timerfd_create (CLOCK_MONOTONIC, 0);
2636 info->wakeups_missed = 0;
2637 info->timer_fd = fd;
2641 dlt_log(LOG_ERR,"Can't create timer filedescriptor");
2645 /* Make the timer periodic */
2646 sec = period/1000000;
2647 ns = (period - (sec * 1000000)) * 1000;
2648 itval.it_interval.tv_sec = sec;
2649 itval.it_interval.tv_nsec = ns;
2650 itval.it_value.tv_sec = sec;
2651 itval.it_value.tv_nsec = ns;
2653 ret = timerfd_settime (fd, 0, &itval, NULL);
2658 void dlt_daemon_wait_period (DltDaemonPeriodicData *info, int verbose)
2660 unsigned long long missed;
2663 PRINT_FUNCTION_VERBOSE(verbose);
2665 ret = read (info->timer_fd, &missed, sizeof (missed));
2667 dlt_log(LOG_ERR,"dlt_daemon_wait_period: Read failed");
2672 info->wakeups_missed += (missed - 1);
2676 int create_timer_fd(DltDaemonLocal *daemon_local, int period_sec, int starts_in, int* fd, const char* timer_name)
2679 struct itimerspec l_timer_spec;
2681 if(timer_name == NULL)
2683 timer_name = "timer_not_named";
2688 snprintf(str, sizeof(str), "<%s> fd is NULL pointer\n", timer_name );
2689 dlt_log(DLT_LOG_ERROR, str);
2693 if( period_sec > 0 ) {
2694 local_fd = timerfd_create(CLOCK_MONOTONIC, 0);
2697 snprintf(str, sizeof(str), "<%s> timerfd_create failed: %s\n", timer_name, strerror(errno));
2698 dlt_log(DLT_LOG_ERROR, str);
2701 l_timer_spec.it_interval.tv_sec = period_sec;
2702 l_timer_spec.it_interval.tv_nsec = 0;
2703 l_timer_spec.it_value.tv_sec = starts_in;
2704 l_timer_spec.it_value.tv_nsec = 0;
2706 if( timerfd_settime( local_fd, 0, &l_timer_spec, NULL) < 0)
2708 snprintf(str, sizeof(str), "<%s> timerfd_settime failed: %s\n", timer_name, strerror(errno));
2709 dlt_log(DLT_LOG_ERROR, str);
2714 // timer not activated via the service file
2715 snprintf(str, sizeof(str), "<%s> not set: period=0\n", timer_name);
2716 dlt_log(DLT_LOG_INFO, str);
2720 // If fd is fully initialized, let's add it to the fd sets
2723 snprintf(str, sizeof(str), "<%s> initialized with %ds timer\n", timer_name, period_sec);
2724 dlt_log(DLT_LOG_INFO, str);
2726 FD_SET(local_fd, &(daemon_local->master));
2727 //FD_SET(local_fd, &(daemon_local->timer_fds));
2728 if (local_fd > daemon_local->fdmax)
2730 daemon_local->fdmax = local_fd;
2739 void dlt_daemon_send_timingpacket(DltDaemon *daemon, DltDaemonLocal *daemon_local)
2743 if (daemon->timingpackets)
2745 for (j = 0; j <= daemon_local->fdmax; j++)
2747 /* send to everyone! */
2748 if (FD_ISSET(j, &(daemon_local->master)))
2750 /* except the listener and ourselves */
2751 if ((j != daemon_local->fp) && (j != daemon_local->sock)
2752 #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE
2753 && (j!=daemon_local->timer_wd)
2755 && (j!=daemon_local->timer_timingpacket) && (j!=daemon_local->timer_ecuversion) )
2757 dlt_log(LOG_DEBUG, "timingpacket\n");
2758 dlt_daemon_control_message_time(j, daemon, daemon_local->flags.vflag);
2766 void dlt_daemon_send_ecuversion(DltDaemon *daemon, DltDaemonLocal *daemon_local)
2770 for (j = 0; j <= daemon_local->fdmax; j++)
2772 /* send to everyone! */
2773 if (FD_ISSET(j, &(daemon_local->master)))
2775 /* except the listener and ourselves */
2776 if ((j != daemon_local->fp) && (j != daemon_local->sock)
2777 #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE
2778 && (j!=daemon_local->timer_wd)
2780 && (j!=daemon_local->timer_timingpacket) && (j!=daemon_local->timer_ecuversion))
2782 dlt_log(LOG_DEBUG, "ecu_version\n");
2783 if(daemon_local->flags.sendECUSoftwareVersion > 0)
2784 dlt_daemon_control_get_software_version(j, daemon, daemon_local->flags.vflag);
2786 if(daemon_local->flags.sendTimezone > 0)
2788 // send timezone information
2789 time_t t = time(NULL);
2791 localtime_r(&t, <);
2792 dlt_daemon_control_message_timezone(j,daemon,(int32_t) lt.tm_gmtoff,(uint8_t) lt.tm_isdst,daemon_local->flags.vflag);
2799 /* Close connection function */
2800 int dlt_daemon_close_socket(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
2803 FD_CLR(sock, &(daemon_local->master));
2805 if (daemon_local->client_connections)
2807 daemon_local->client_connections--;
2810 if(daemon_local->client_connections==0)
2812 /* send new log state to all applications */
2814 dlt_daemon_user_send_all_log_state(daemon,verbose);
2817 if (daemon_local->flags.vflag)
2819 sprintf(str, "Connection to client lost, #connections: %d\n",daemon_local->client_connections);
2820 dlt_log(LOG_INFO, str);
2823 dlt_daemon_control_message_connection_info(DLT_DAEMON_STORE_TO_BUFFER,daemon,DLT_CONNECTION_STATUS_DISCONNECTED,"",verbose);