3 * Copyright (C) 2012 BMW AG
5 * This file is part of GENIVI Project Dlt - Diagnostic Log and Trace console apps.
7 * Contributions are licensed to the GENIVI Alliance under one or more
8 * Contribution License Agreements.
11 * This Source Code Form is subject to the terms of the
12 * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with
13 * this file, You can obtain one at http://mozilla.org/MPL/2.0/.
16 * \author Alexander Wenzel <alexander.aw.wenzel@bmw.de> BMW 2011-2012
19 * For further information see http://www.genivi.org/.
23 /*******************************************************************************
25 ** SRC-MODULE: dlt-daemon.c **
31 ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de **
38 ** PLATFORM DEPENDANT [yes/no]: yes **
40 ** TO BE CHANGED BY USER [yes/no]: no **
42 *******************************************************************************/
44 /*******************************************************************************
46 ********************************************************************************
48 ** Initials Name Company **
49 ** -------- ------------------------- ---------------------------------- **
50 ** aw Alexander Wenzel BMW **
51 ** mk Markus Klein Fraunhofer ESK **
52 *******************************************************************************/
54 /*******************************************************************************
55 ** Revision Control History **
56 *******************************************************************************/
59 * $LastChangedRevision: 1670 $
60 * $LastChangedDate: 2011-04-08 15:12:06 +0200 (Fr, 08. Apr 2011) $
68 #include <stdio.h> /* for printf() and fprintf() */
69 #include <sys/socket.h> /* for socket(), connect(), (), and recv() */
70 #include <arpa/inet.h> /* for sockaddr_in and inet_addr() */
71 #include <stdlib.h> /* for atoi() and exit() */
72 #include <string.h> /* for memset() */
73 #include <unistd.h> /* for close() */
80 #include <sys/timerfd.h>
83 #include <linux/stat.h>
85 #include "dlt_types.h"
86 #include "dlt-daemon.h"
87 #include "dlt-daemon_cfg.h"
89 #if defined(DLT_SYSTEMD_WATCHDOG_ENABLE) || defined(DLT_SYSTEMD_ENABLE)
90 #include "sd-daemon.h"
94 \defgroup daemon DLT Daemon
99 /** Global text output buffer, mainly used for creation of error/warning strings */
100 static char str[DLT_DAEMON_TEXTBUFSIZE];
102 static DltDaemonTimingPacketThreadData dlt_daemon_timingpacket_thread_data;
104 static pthread_t dlt_daemon_timingpacket_thread_handle;
105 static pthread_attr_t dlt_daemon_timingpacket_thread_attr;
107 static DltDaemonECUVersionThreadData dlt_daemon_ecu_version_thread_data;
108 static pthread_t dlt_daemon_ecu_version_thread_handle;
110 #if defined(DLT_SYSTEMD_WATCHDOG_ENABLE)
111 // Allow main loop to execute every 100ms
112 #define DLT_SELECT_TIMEOUT_USEC (1000 * 100)
113 static DltDaemonTimingPacketThreadData dlt_daemon_systemd_watchdog_thread_data;
114 static pthread_t dlt_daemon_systemd_watchdog_thread_handle;
118 * Print usage information of tool.
122 char version[DLT_DAEMON_TEXTBUFSIZE];
123 dlt_get_version(version);
125 //printf("DLT logging daemon %s %s\n", _DLT_PACKAGE_VERSION, _DLT_PACKAGE_VERSION_STATE);
126 //printf("Compile options: %s %s %s %s",_DLT_SYSTEMD_ENABLE, _DLT_SYSTEMD_WATCHDOG_ENABLE, _DLT_TEST_ENABLE, _DLT_SHM_ENABLE);
127 printf("%s", version);
128 printf("Usage: dlt-daemon [options]\n");
129 printf("Options:\n");
130 printf(" -d Daemonize\n");
131 printf(" -h Usage\n");
132 printf(" -c filename DLT daemon configuration file (Default: /etc/dlt.conf)\n");
138 int option_handling(DltDaemonLocal *daemon_local,int argc, char* argv[])
144 fprintf (stderr, "Invalid parameter passed to option_handling()\n");
148 /* Initialize flags */
149 memset(daemon_local,0,sizeof(DltDaemonLocal));
153 while ((c = getopt (argc, argv, "hdc:")) != -1)
159 daemon_local->flags.dflag = 1;
164 strncpy(daemon_local->flags.cvalue,optarg,NAME_MAX);
170 return -2; /* return no error */
176 fprintf (stderr, "Option -%c requires an argument.\n", optopt);
178 else if (isprint (optopt))
180 fprintf (stderr, "Unknown option `-%c'.\n", optopt);
184 fprintf (stderr, "Unknown option character `\\x%x'.\n",optopt);
186 /* unknown or wrong option used, show usage information and terminate */
192 fprintf (stderr, "Invalid option, this should never occur!\n");
200 } /* option_handling() */
205 int option_file_parser(DltDaemonLocal *daemon_local)
208 int value_length = 1024;
209 char line[value_length-1];
210 char token[value_length];
211 char value[value_length];
213 const char *filename;
215 /* set default values for configuration */
216 daemon_local->flags.sharedMemorySize = DLT_SHM_SIZE;
217 daemon_local->flags.sendMessageTime = 0;
218 daemon_local->flags.offlineTraceDirectory[0] = 0;
219 daemon_local->flags.offlineTraceFileSize = 1000000;
220 daemon_local->flags.offlineTraceMaxSize = 0;
221 daemon_local->flags.loggingMode = 0;
222 daemon_local->flags.loggingLevel = 6;
223 strncpy(daemon_local->flags.loggingFilename, DLT_USER_DIR "/dlt.log",sizeof(daemon_local->flags.loggingFilename));
224 daemon_local->flags.sendECUSoftwareVersion = 0;
225 memset(daemon_local->flags.pathToECUSoftwareVersion, 0, sizeof(daemon_local->flags.pathToECUSoftwareVersion));
227 /* open configuration file */
228 if(daemon_local->flags.cvalue[0])
229 filename = daemon_local->flags.cvalue;
231 filename = "/etc/dlt.conf";
232 //printf("Load configuration from file: %s\n",filename);
233 pFile = fopen (filename,"r");
239 /* fetch line from configuration file */
240 if ( fgets (line , value_length - 1 , pFile) != NULL )
242 pch = strtok (line," =\r\n");
248 if(strcmp(pch,"#")==0)
253 strncpy(token,pch,sizeof(token) - 1);
257 strncpy(value,pch,sizeof(value) - 1);
261 pch = strtok (NULL, " =\r\n");
264 if(token[0] && value[0])
266 /* parse arguments here */
267 if(strcmp(token,"Verbose")==0)
269 daemon_local->flags.vflag = atoi(value);
270 //printf("Option: %s=%s\n",token,value);
272 else if(strcmp(token,"PrintASCII")==0)
274 daemon_local->flags.aflag = atoi(value);
275 //printf("Option: %s=%s\n",token,value);
277 else if(strcmp(token,"PrintHex")==0)
279 daemon_local->flags.xflag = atoi(value);
280 //printf("Option: %s=%s\n",token,value);
282 else if(strcmp(token,"PrintHeadersOnly")==0)
284 daemon_local->flags.sflag = atoi(value);
285 //printf("Option: %s=%s\n",token,value);
287 else if(strcmp(token,"SendSerialHeader")==0)
289 daemon_local->flags.lflag = atoi(value);
290 //printf("Option: %s=%s\n",token,value);
292 else if(strcmp(token,"SendContextRegistration")==0)
294 daemon_local->flags.rflag = atoi(value);
295 //printf("Option: %s=%s\n",token,value);
297 else if(strcmp(token,"SendMessageTime")==0)
299 daemon_local->flags.sendMessageTime = atoi(value);
300 //printf("Option: %s=%s\n",token,value);
302 else if(strcmp(token,"RS232SyncSerialHeader")==0)
304 daemon_local->flags.mflag = atoi(value);
305 //printf("Option: %s=%s\n",token,value);
307 else if(strcmp(token,"TCPSyncSerialHeader")==0)
309 daemon_local->flags.nflag = atoi(value);
310 //printf("Option: %s=%s\n",token,value);
312 else if(strcmp(token,"RS232DeviceName")==0)
314 strncpy(daemon_local->flags.yvalue,value,NAME_MAX);
315 //printf("Option: %s=%s\n",token,value);
317 else if(strcmp(token,"RS232Baudrate")==0)
319 strncpy(daemon_local->flags.bvalue,value,NAME_MAX);
320 //printf("Option: %s=%s\n",token,value);
322 else if(strcmp(token,"ECUId")==0)
324 strncpy(daemon_local->flags.evalue,value,NAME_MAX);
325 //printf("Option: %s=%s\n",token,value);
327 else if(strcmp(token,"PersistanceStoragePath")==0)
329 strncpy(daemon_local->flags.ivalue,value,NAME_MAX);
330 //printf("Option: %s=%s\n",token,value);
332 else if(strcmp(token,"LoggingMode")==0)
334 daemon_local->flags.loggingMode = atoi(value);
335 //printf("Option: %s=%s\n",token,value);
337 else if(strcmp(token,"LoggingLevel")==0)
339 daemon_local->flags.loggingLevel = atoi(value);
340 //printf("Option: %s=%s\n",token,value);
342 else if(strcmp(token,"LoggingFilename")==0)
344 strncpy(daemon_local->flags.loggingFilename,value,sizeof(daemon_local->flags.loggingFilename) - 1);
345 //printf("Option: %s=%s\n",token,value);
347 else if(strcmp(token,"SharedMemorySize")==0)
349 daemon_local->flags.sharedMemorySize = atoi(value);
350 //printf("Option: %s=%s\n",token,value);
352 else if(strcmp(token,"OfflineTraceDirectory")==0)
354 strncpy(daemon_local->flags.offlineTraceDirectory,value,sizeof(daemon_local->flags.offlineTraceDirectory) - 1);
355 //printf("Option: %s=%s\n",token,value);
357 else if(strcmp(token,"OfflineTraceFileSize")==0)
359 daemon_local->flags.offlineTraceFileSize = atoi(value);
360 //printf("Option: %s=%s\n",token,value);
362 else if(strcmp(token,"OfflineTraceMaxSize")==0)
364 daemon_local->flags.offlineTraceMaxSize = atoi(value);
365 //printf("Option: %s=%s\n",token,value);
367 else if(strcmp(token,"SendECUSoftwareVersion")==0)
369 daemon_local->flags.sendECUSoftwareVersion = atoi(value);
370 //printf("Option: %s=%s\n",token,value);
372 else if(strcmp(token,"PathToECUSoftwareVersion")==0)
374 strncpy(daemon_local->flags.pathToECUSoftwareVersion,value,sizeof(daemon_local->flags.pathToECUSoftwareVersion) - 1);
375 //printf("Option: %s=%s\n",token,value);
380 fprintf(stderr, "Unknown option: %s=%s\n",token,value);
393 fprintf(stderr, "Cannot open configuration file: %s\n",filename);
400 * Main function of tool.
402 int main(int argc, char* argv[])
404 char version[DLT_DAEMON_TEXTBUFSIZE];
405 DltDaemonLocal daemon_local;
409 #if defined(DLT_SYSTEMD_WATCHDOG_ENABLE)
410 /* Timeout for select */
411 struct timeval tvTimeout;
412 tvTimeout.tv_sec = 0;
413 tvTimeout.tv_usec = DLT_SELECT_TIMEOUT_USEC;
415 /* Set watchdog flag immediately, not to timeout while init */
416 if(sd_notify(0, "WATCHDOG=1") < 0)
418 fprintf (stderr, "Could not initialize systemd watchdog\n");
422 /* Command line option handling */
423 if ((back = option_handling(&daemon_local,argc,argv))<0)
426 fprintf (stderr, "option_handling() failed!\n");
431 /* Configuration file option handling */
432 if ((back = option_file_parser(&daemon_local))<0)
435 fprintf (stderr, "option_file_parser() failed!\n");
440 /* Initialize internal logging facility */
441 dlt_log_set_filename(daemon_local.flags.loggingFilename);
442 dlt_log_set_level(daemon_local.flags.loggingLevel);
443 dlt_log_init(daemon_local.flags.loggingMode);
445 /* Print version information */
446 dlt_get_version(version);
448 sprintf(str,"Starting DLT Daemon; %s\n", version );
449 dlt_log(LOG_NOTICE, str);
451 PRINT_FUNCTION_VERBOSE(daemon_local.flags.vflag);
453 /* --- Daemon init phase 1 begin --- */
454 if (dlt_daemon_local_init_p1(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
456 dlt_log(LOG_CRIT,"Initialization of phase 1 failed!\n");
459 /* --- Daemon init phase 1 end --- */
461 /* --- Daemon connection init begin */
462 if (dlt_daemon_local_connection_init(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
464 dlt_log(LOG_CRIT,"Initialization of local connections failed!\n");
467 /* --- Daemon connection init end */
469 /* --- Daemon init phase 2 begin --- */
470 if (dlt_daemon_local_init_p2(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
472 dlt_log(LOG_CRIT,"Initialization of phase 2 failed!\n");
475 /* --- Daemon init phase 2 end --- */
479 #if defined(DLT_SYSTEMD_WATCHDOG_ENABLE)
480 /* Set timeout to defined usecs
481 * select might modify this value: POSIX.1-2001 */
482 tvTimeout.tv_sec = 0;
483 tvTimeout.tv_usec = DLT_SELECT_TIMEOUT_USEC;
485 /* update the watchdog time structure */
486 daemon_local.lastOperationTime = dlt_uptime();
488 /* wait for events from all FIFO and sockets, with timeout */
489 daemon_local.read_fds = daemon_local.master;
490 int selectRet = select(daemon_local.fdmax+1, &(daemon_local.read_fds), NULL, NULL, &tvTimeout);
493 dlt_log(LOG_CRIT, "select() failed!\n");
496 else if(selectRet == 0)
498 /* No pending reads, continue while(1)*/
503 /* wait for events from all FIFO and sockets */
504 daemon_local.read_fds = daemon_local.master;
505 if (select(daemon_local.fdmax+1, &(daemon_local.read_fds), NULL, NULL, NULL) == -1)
507 dlt_log(LOG_CRIT, "select() failed!\n");
511 /* run through the existing FIFO and sockets to check for events */
512 for (i = 0; i <= daemon_local.fdmax; i++)
514 if (FD_ISSET(i, &(daemon_local.read_fds)))
516 if (i == daemon_local.sock && ((daemon.mode == DLT_USER_MODE_EXTERNAL) || (daemon.mode == DLT_USER_MODE_BOTH)))
518 /* event from TCP server socket, new connection */
519 if (dlt_daemon_process_client_connect(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
521 dlt_log(LOG_CRIT,"Connect to dlt client failed!\n");
525 else if (i == daemon_local.fp)
527 /* event from the FIFO happened */
528 if (dlt_daemon_process_user_messages(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
530 dlt_log(LOG_CRIT,"Processing of messages from user connection failed!\n");
534 else if ((i == daemon_local.fdserial) && (daemon_local.flags.yvalue[0]))
536 /* event from serial connection to client received */
537 if (dlt_daemon_process_client_messages_serial(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
539 dlt_log(LOG_CRIT,"Processing of messages from serial connection failed!\n");
545 /* event from tcp connection to client received */
546 daemon_local.receiverSock.fd = i;
547 if (dlt_daemon_process_client_messages(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
549 dlt_log(LOG_CRIT,"Processing of messages from client connection failed!\n");
557 dlt_daemon_local_cleanup(&daemon, &daemon_local, daemon_local.flags.vflag);
559 dlt_log(LOG_NOTICE, "Leaving DLT daemon\n");
565 int dlt_daemon_local_init_p1(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
567 #if defined(DLT_SYSTEMD_WATCHDOG_ENABLE) || defined(DLT_SYSTEMD_ENABLE)
572 PRINT_FUNCTION_VERBOSE(verbose);
574 if ((daemon==0) || (daemon_local==0))
576 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_local_init_p1()\n");
580 #if defined(DLT_SYSTEMD_WATCHDOG_ENABLE) || defined(DLT_SYSTEMD_ENABLE)
584 dlt_log(LOG_CRIT, "system not booted with systemd!\n");
589 dlt_log(LOG_CRIT, "sd_booted failed!\n");
594 dlt_log(LOG_INFO, "system booted with systemd\n");
600 /* Check for daemon mode */
601 if (daemon_local->flags.dflag)
603 dlt_daemon_daemonize(daemon_local->flags.vflag);
606 /* initialise structure to use DLT file */
607 if (dlt_file_init(&(daemon_local->file),daemon_local->flags.vflag)==-1)
609 dlt_log(LOG_ERR,"Could not initialize file structure\n");
610 /* Return value ignored, dlt daemon will exit */
611 dlt_file_free(&(daemon_local->file),daemon_local->flags.vflag);
615 signal(SIGPIPE,SIG_IGN);
617 signal(SIGTERM, dlt_daemon_signal_handler); /* software termination signal from kill */
618 signal(SIGHUP, dlt_daemon_signal_handler); /* hangup signal */
619 signal(SIGQUIT, dlt_daemon_signal_handler);
620 signal(SIGINT, dlt_daemon_signal_handler);
625 int dlt_daemon_local_init_p2(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
627 PRINT_FUNCTION_VERBOSE(verbose);
629 if ((daemon==0) || (daemon_local==0))
631 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_local_init_p2()\n");
636 if (dlt_daemon_init(daemon,daemon_local->flags.ivalue,daemon_local->flags.vflag)==-1)
638 dlt_log(LOG_ERR,"Could not initialize daemon data\n");
642 /* init offline trace */
643 if(((daemon->mode == DLT_USER_MODE_INTERNAL) || (daemon->mode == DLT_USER_MODE_BOTH)) && daemon_local->flags.offlineTraceDirectory[0])
645 if (dlt_offline_trace_init(&(daemon_local->offlineTrace),daemon_local->flags.offlineTraceDirectory,daemon_local->flags.offlineTraceFileSize,daemon_local->flags.offlineTraceMaxSize)==-1)
647 dlt_log(LOG_ERR,"Could not initialize offline trace\n");
652 /* Set ECU id of daemon */
653 if (daemon_local->flags.evalue[0])
655 dlt_set_id(daemon->ecuid,daemon_local->flags.evalue);
659 dlt_set_id(daemon->ecuid,DLT_DAEMON_ECU_ID);
662 /* Set flag for optional sending of serial header */
663 daemon->sendserialheader = daemon_local->flags.lflag;
665 #ifdef DLT_SHM_ENABLE
666 /* init shared memory */
667 if (dlt_shm_init_server(&(daemon_local->dlt_shm),DLT_SHM_KEY,daemon_local->flags.sharedMemorySize)==-1)
669 dlt_log(LOG_ERR,"Could not initialize shared memory\n");
674 /* prepare main loop */
675 if (dlt_message_init(&(daemon_local->msg),daemon_local->flags.vflag)==-1)
677 dlt_log(LOG_ERR,"Could not initialize message\n");
681 if (dlt_receiver_init(&(daemon_local->receiver),daemon_local->fp,DLT_DAEMON_RCVBUFSIZE)==-1)
683 dlt_log(LOG_ERR,"Could not initialize receiver\n");
686 if (dlt_receiver_init(&(daemon_local->receiverSock),daemon_local->sock,DLT_DAEMON_RCVBUFSIZESOCK)==-1)
688 dlt_log(LOG_ERR,"Could not initialize receiver for socket\n");
691 if (daemon_local->flags.yvalue[0])
693 if (dlt_receiver_init(&(daemon_local->receiverSerial),daemon_local->fdserial,DLT_DAEMON_RCVBUFSIZESERIAL)==-1)
695 dlt_log(LOG_ERR,"Could not initialize receiver for serial connection\n");
700 /* setup period thread for timing packets */
701 if (pthread_attr_init(&dlt_daemon_timingpacket_thread_attr)<0)
703 dlt_log(LOG_WARNING, "Initialization of default thread stack size failed!\n");
707 if (pthread_attr_setstacksize(&dlt_daemon_timingpacket_thread_attr,DLT_DAEMON_TIMINGPACKET_THREAD_STACKSIZE)<0)
709 dlt_log(LOG_WARNING, "Setting of default thread stack size failed!\n");
713 /* configure sending timing packets */
714 if (daemon_local->flags.sendMessageTime)
716 daemon->timingpackets = 1;
719 /* Binary semaphore for thread */
720 if (sem_init(&dlt_daemon_mutex, 0, 1)==-1)
722 dlt_log(LOG_ERR,"Could not initialize binary semaphore\n");
727 dlt_daemon_timingpacket_thread_data.daemon = daemon;
728 dlt_daemon_timingpacket_thread_data.daemon_local = daemon_local;
730 if (pthread_create(&(dlt_daemon_timingpacket_thread_handle),
731 &dlt_daemon_timingpacket_thread_attr,
732 (void *) &dlt_daemon_timingpacket_thread,
733 (void *)&dlt_daemon_timingpacket_thread_data)!=0)
735 dlt_log(LOG_ERR,"Could not initialize timing packet thread\n");
736 pthread_attr_destroy(&dlt_daemon_timingpacket_thread_attr);
740 pthread_attr_destroy(&dlt_daemon_timingpacket_thread_attr);
742 /* Get ECU version info from a file. If it fails, use dlt_version as fallback. */
743 if(dlt_daemon_local_ecu_version_init(daemon, daemon_local, daemon_local->flags.vflag) < 0)
745 daemon->ECUVersionString = malloc(DLT_DAEMON_TEXTBUFSIZE);
746 dlt_get_version(daemon->ECUVersionString);
749 /* start thread for ECU version, if enabled */
750 if(daemon_local->flags.sendECUSoftwareVersion > 0)
752 dlt_daemon_ecu_version_thread_data.daemon = daemon;
753 dlt_daemon_ecu_version_thread_data.daemon_local = daemon_local;
755 if (pthread_create(&(dlt_daemon_ecu_version_thread_handle),
757 (void *) &dlt_daemon_ecu_version_thread,
758 (void *)&dlt_daemon_ecu_version_thread_data)!=0)
760 dlt_log(LOG_ERR,"Could not initialize ECU version thread\n");
765 #if defined(DLT_SYSTEMD_WATCHDOG_ENABLE)
767 dlt_daemon_systemd_watchdog_thread_data.daemon = daemon;
768 dlt_daemon_systemd_watchdog_thread_data.daemon_local = daemon_local;
770 if (pthread_create(&(dlt_daemon_systemd_watchdog_thread_handle),
772 (void *) &dlt_daemon_systemd_watchdog_thread,
773 (void *) &dlt_daemon_systemd_watchdog_thread_data)!=0)
775 dlt_log(LOG_ERR,"Could not initialize systemd watchdog thread\n");
784 int dlt_daemon_local_connection_init(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
789 struct sockaddr_in servAddr;
790 unsigned int servPort = DLT_DAEMON_TCP_PORT;
792 PRINT_FUNCTION_VERBOSE(verbose);
794 if ((daemon==0) || (daemon_local==0))
796 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_local_connection_init()\n");
800 /* open named pipe(FIFO) to receive DLT messages from users */
803 /* Try to delete existing pipe, ignore result of unlink */
804 unlink(DLT_USER_FIFO);
806 ret=mkfifo(DLT_USER_FIFO, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH );
809 sprintf(str,"FIFO user %s cannot be created!\n",DLT_USER_FIFO);
810 dlt_log(LOG_ERR, str);
814 daemon_local->fp = open(DLT_USER_FIFO, O_RDWR);
815 if (daemon_local->fp==-1)
817 sprintf(str,"FIFO user %s cannot be opened!\n",DLT_USER_FIFO);
818 dlt_log(LOG_ERR, str);
822 /* create and open socket to receive incoming connections from client */
823 if ((daemon_local->sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
825 dlt_log(LOG_ERR, "socket() failed!\n");
829 if ( -1 == setsockopt(daemon_local->sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)))
831 sprintf(str,"Setsockopt error in dlt_daemon_local_connection_init: %s\n",strerror(errno));
832 dlt_log(LOG_ERR, str);
835 memset(&servAddr, 0, sizeof(servAddr));
836 servAddr.sin_family = AF_INET;
837 servAddr.sin_addr.s_addr = INADDR_ANY;
838 servAddr.sin_port = htons(servPort);
840 if (bind(daemon_local->sock, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0)
842 dlt_log(LOG_ERR, "bind() failed!\n");
846 if (daemon_local->flags.vflag)
848 dlt_log(LOG_INFO, "Bind succesfull\n");
851 if (listen(daemon_local->sock, 3) < 0)
853 dlt_log(LOG_ERR, "listen() failed!\n");
857 if (daemon_local->flags.vflag)
859 dlt_log(LOG_INFO, "Listen succesfull\n");
862 /* prepare usage of select(), add FIFO and receiving socket */
863 FD_ZERO(&(daemon_local->master));
864 FD_ZERO(&(daemon_local->read_fds));
865 FD_SET(daemon_local->sock, &(daemon_local->master));
867 daemon_local->fdmax = daemon_local->sock;
869 FD_SET(daemon_local->fp, &(daemon_local->master));
871 if (daemon_local->fp > daemon_local->fdmax)
873 daemon_local->fdmax = daemon_local->fp;
876 if (daemon_local->flags.yvalue[0])
878 /* create and open serial connection from/to client */
879 /* open serial connection */
880 daemon_local->fdserial=open(daemon_local->flags.yvalue,O_RDWR);
881 if (daemon_local->fdserial<0)
883 sprintf(str,"Failed to open serial device %s\n", daemon_local->flags.yvalue);
884 daemon_local->flags.yvalue[0] = 0;
885 dlt_log(LOG_ERR, str);
889 if (isatty(daemon_local->fdserial))
891 if (daemon_local->flags.bvalue[0])
893 daemon_local->baudrate = dlt_convert_serial_speed(atoi(daemon_local->flags.bvalue));
897 daemon_local->baudrate = dlt_convert_serial_speed(DLT_DAEMON_SERIAL_DEFAULT_BAUDRATE);
900 if (dlt_setup_serial(daemon_local->fdserial,daemon_local->baudrate)<0)
902 close(daemon_local->fdserial);
903 sprintf(str,"Failed to configure serial device %s (%s) \n", daemon_local->flags.yvalue, strerror(errno));
904 daemon_local->flags.yvalue[0] = 0;
905 dlt_log(LOG_ERR, str);
909 FD_SET(daemon_local->fdserial, &(daemon_local->master));
911 if (daemon_local->fdserial > daemon_local->fdmax)
913 daemon_local->fdmax = daemon_local->fdserial;
916 if (daemon_local->flags.vflag)
918 dlt_log(LOG_INFO, "Serial init done\n");
923 close(daemon_local->fdserial);
924 fprintf(stderr,"Device is not a serial device, device = %s (%s) \n", daemon_local->flags.yvalue, strerror(errno));
925 daemon_local->flags.yvalue[0] = 0;
933 int dlt_daemon_local_ecu_version_init(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
935 char *version = NULL;
938 PRINT_FUNCTION_VERBOSE(verbose);
940 /* By default, version string is null. */
941 daemon->ECUVersionString = NULL;
943 /* Open the file. Bail out if error occurs */
944 f = fopen(daemon_local->flags.pathToECUSoftwareVersion, "r");
947 /* Error level notice, because this might be deliberate choice */
948 dlt_log(LOG_NOTICE, "Failed to open ECU Software version file.\n");
952 /* Get the file size. Bail out if stat fails. */
955 if(fstat(fd, &s_buf) < 0)
957 dlt_log(LOG_ERR, "Failed to stat ECU Software version file.\n");
962 /* Bail out if file is too large. Use DLT_DAEMON_TEXTBUFSIZE max.
963 * Reserve one byte for trailing '\0' */
964 off_t size = s_buf.st_size;
965 if(size >= DLT_DAEMON_TEXTBUFSIZE)
967 dlt_log(LOG_ERR, "Too large file for ECU version.\n");
972 /* Allocate permanent buffer for version info */
973 version = malloc(size + 1);
977 offset += fread(version + offset, 1, size, f);
980 dlt_log(LOG_ERR, "Failed to read ECU Software version file.\n");
987 dlt_log(LOG_ERR, "Too long file for ECU Software version info.\n");
993 version[offset] = '\0';//append null termination at end of version string
994 daemon->ECUVersionString = version;
999 void dlt_daemon_local_cleanup(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1001 PRINT_FUNCTION_VERBOSE(verbose);
1003 if ((daemon==0) || (daemon_local==0))
1005 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_local_cleanup()\n");
1010 dlt_receiver_free(&(daemon_local->receiver));
1012 dlt_receiver_free(&(daemon_local->receiverSock));
1015 dlt_message_free(&(daemon_local->msg),daemon_local->flags.vflag);
1016 close(daemon_local->fp);
1018 /* free shared memory */
1019 if(daemon_local->flags.offlineTraceDirectory[0])
1020 dlt_offline_trace_free(&(daemon_local->offlineTrace));
1022 if (daemon_local->flags.ovalue[0])
1024 close(daemon_local->ohandle);
1029 dlt_file_free(&(daemon_local->file),daemon_local->flags.vflag);
1031 /* Try to delete existing pipe, ignore result of unlink() */
1032 unlink(DLT_USER_FIFO);
1034 #ifdef DLT_SHM_ENABLE
1035 /* free shared memory */
1036 dlt_shm_free_server(&(daemon_local->dlt_shm));
1039 /* Try to delete lock file, ignore result of unlink() */
1040 unlink(DLT_DAEMON_LOCK_FILE);
1043 void dlt_daemon_signal_handler(int sig)
1052 /* finalize the server */
1053 //dlt_log("terminate signal catched");
1054 dlt_log(LOG_NOTICE, "Exiting DLT daemon\n");
1056 /* Try to delete existing pipe, ignore result of unlink() */
1057 unlink(DLT_USER_FIFO);
1059 /* Try to delete lock file, ignore result of unlink() */
1060 unlink(DLT_DAEMON_LOCK_FILE);
1062 /* Terminate program */
1068 /* This case should never occur */
1072 } /* dlt_daemon_signal_handler() */
1074 void dlt_daemon_daemonize(int verbose)
1079 PRINT_FUNCTION_VERBOSE(verbose);
1081 dlt_log(LOG_NOTICE, "Daemon mode\n");
1087 dlt_log(LOG_CRIT, "Unable to fork(), exiting DLT daemon\n");
1088 exit(-1); /* fork error */
1093 exit(0); /* parent exits */
1095 /* child (daemon) continues */
1097 /* Process independency */
1099 /* obtain a new process group */
1102 dlt_log(LOG_CRIT, "setsid() failed, exiting DLT daemon\n");
1103 exit(-1); /* fork error */
1106 /* Close descriptors */
1107 for (i=getdtablesize();i>=0;--i)
1109 close(i); /* close all descriptors */
1112 /* Open standard descriptors stdin, stdout, stderr */
1113 i=open("/dev/null",O_RDWR); /* open stdin */
1117 dlt_log(LOG_ERR, "Failed to direct stdout to /dev/null.\n");/* stdout */
1119 dlt_log(LOG_ERR, "Failed to direct stderr to /dev/null.\n"); /* stderr */
1123 umask(DLT_DAEMON_UMASK);
1125 /* Change to known directory */
1126 if(chdir(DLT_USER_DIR) < 0)
1127 dlt_log(LOG_ERR, "Failed to chdir to DLT_USER_DIR.\n");;
1129 /* Ensure single copy of daemon;
1130 run only one instance at a time */
1131 lfp=open(DLT_DAEMON_LOCK_FILE,O_RDWR|O_CREAT,DLT_DAEMON_LOCK_FILE_PERM);
1134 dlt_log(LOG_CRIT, "can't open lock file, exiting DLT daemon\n");
1135 exit(-1); /* can not open */
1137 if (lockf(lfp,F_TLOCK,0)<0)
1139 dlt_log(LOG_CRIT, "can't lock lock file, exiting DLT daemon\n");
1140 exit(-1); /* can not lock */
1142 /* only first instance continues */
1144 sprintf(str,"%d\n",getpid());
1145 pid_len = strlen(str);
1146 if(write(lfp,str,pid_len) != pid_len) /* record pid to lockfile */
1147 dlt_log(LOG_ERR, "Could not write pid to file in dlt_daemon_daemonize.\n");
1150 signal(SIGCHLD,SIG_IGN); /* ignore child */
1151 signal(SIGTSTP,SIG_IGN); /* ignore tty signals */
1152 signal(SIGTTOU,SIG_IGN);
1153 signal(SIGTTIN,SIG_IGN);
1155 } /* dlt_daemon_daemonize() */
1157 int dlt_daemon_process_client_connect(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1160 struct sockaddr cli;
1164 PRINT_FUNCTION_VERBOSE(verbose);
1166 if ((daemon==0) || (daemon_local==0))
1168 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_client_connect()\n");
1172 /* event from TCP server socket, new connection */
1173 cli_size = sizeof(cli);
1174 if ((in_sock = accept(daemon_local->sock,&cli, &cli_size)) < 0)
1176 dlt_log(LOG_ERR, "accept() failed!\n");
1180 /* check if file file descriptor was already used, and make it invalid if it is reused */
1181 /* This prevents sending messages to wrong file descriptor */
1182 dlt_daemon_applications_invalidate_fd(daemon,in_sock,verbose);
1183 dlt_daemon_contexts_invalidate_fd(daemon,in_sock,verbose);
1185 //sprintf("str,"Client Connection from %s\n", inet_ntoa(cli.sin_addr));
1187 FD_SET(in_sock, &(daemon_local->master)); /* add to master set */
1188 if (in_sock > daemon_local->fdmax)
1190 /* keep track of the maximum */
1191 daemon_local->fdmax = in_sock;
1194 daemon_local->client_connections++;
1195 if (daemon_local->flags.vflag)
1197 sprintf(str, "New connection to client established, #connections: %d\n",daemon_local->client_connections);
1198 dlt_log(LOG_INFO, str);
1201 if (daemon_local->client_connections==1)
1203 if (daemon_local->flags.vflag)
1205 dlt_log(LOG_INFO, "Send ring-buffer to client\n");
1207 if (dlt_daemon_send_ringbuffer_to_client(daemon, daemon_local, verbose)==-1)
1209 dlt_log(LOG_ERR,"Can't send contents of ringbuffer to clients\n");
1213 /* send new log state to all applications */
1215 dlt_daemon_user_send_all_log_state(daemon,verbose);
1221 int dlt_daemon_process_client_messages(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1223 int bytes_to_be_removed=0;
1225 PRINT_FUNCTION_VERBOSE(verbose);
1227 if ((daemon==0) || (daemon_local==0))
1229 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_client_messages()\n");
1233 if (dlt_receiver_receive_socket(&(daemon_local->receiverSock))<=0)
1235 close(daemon_local->receiverSock.fd);
1236 FD_CLR(daemon_local->receiverSock.fd, &(daemon_local->master));
1237 daemon_local->receiverSock.fd = -1;
1239 if (daemon_local->client_connections)
1241 daemon_local->client_connections--;
1244 if(daemon_local->client_connections==0)
1246 /* send new log state to all applications */
1248 dlt_daemon_user_send_all_log_state(daemon,verbose);
1251 if (daemon_local->flags.vflag)
1253 sprintf(str, "Connection to client lost, #connections: %d\n",daemon_local->client_connections);
1254 dlt_log(LOG_INFO, str);
1257 /* check: return 0; */
1260 /* Process all received messages */
1261 while (dlt_message_read(&(daemon_local->msg),(uint8_t*)daemon_local->receiverSock.buf,daemon_local->receiverSock.bytesRcvd,daemon_local->flags.nflag,daemon_local->flags.vflag)==0)
1263 /* Check for control message */
1264 if ( 0 < daemon_local->receiverSock.fd && DLT_MSG_IS_CONTROL_REQUEST(&(daemon_local->msg)) )
1266 dlt_daemon_control_process_control(daemon_local->receiverSock.fd, daemon, &(daemon_local->msg), daemon_local->flags.vflag);
1269 bytes_to_be_removed = daemon_local->msg.headersize+daemon_local->msg.datasize-sizeof(DltStorageHeader);
1270 if (daemon_local->msg.found_serialheader)
1272 bytes_to_be_removed += sizeof(dltSerialHeader);
1274 if (daemon_local->msg.resync_offset)
1276 bytes_to_be_removed += daemon_local->msg.resync_offset;
1279 if (dlt_receiver_remove(&(daemon_local->receiverSock),bytes_to_be_removed)==-1)
1281 dlt_log(LOG_ERR,"Can't remove bytes from receiver for sockets\n");
1288 if (dlt_receiver_move_to_begin(&(daemon_local->receiverSock))==-1)
1290 dlt_log(LOG_ERR,"Can't move bytes to beginning of receiver buffer for sockets\n");
1297 int dlt_daemon_process_client_messages_serial(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1299 int bytes_to_be_removed=0;
1301 PRINT_FUNCTION_VERBOSE(verbose);
1303 if ((daemon==0) || (daemon_local==0))
1305 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_client_messages_serial()\n");
1309 if (dlt_receiver_receive_fd(&(daemon_local->receiverSerial))<=0)
1311 dlt_log(LOG_ERR, "dlt_receiver_receive_fd() for messages from serial interface failed!\n");
1315 /* Process all received messages */
1316 while (dlt_message_read(&(daemon_local->msg),(uint8_t*)daemon_local->receiverSerial.buf,daemon_local->receiverSerial.bytesRcvd,daemon_local->flags.mflag,daemon_local->flags.vflag)==0)
1318 /* Check for control message */
1319 if (DLT_MSG_IS_CONTROL_REQUEST(&(daemon_local->msg)))
1321 if (dlt_daemon_control_process_control(daemon_local->receiverSerial.fd, daemon, &(daemon_local->msg), daemon_local->flags.vflag)==-1)
1323 dlt_log(LOG_ERR,"Can't process control messages\n");
1328 bytes_to_be_removed = daemon_local->msg.headersize+daemon_local->msg.datasize-sizeof(DltStorageHeader);
1329 if (daemon_local->msg.found_serialheader)
1331 bytes_to_be_removed += sizeof(dltSerialHeader);
1333 if (daemon_local->msg.resync_offset)
1335 bytes_to_be_removed += daemon_local->msg.resync_offset;
1338 if (dlt_receiver_remove(&(daemon_local->receiverSerial),bytes_to_be_removed)==-1)
1340 dlt_log(LOG_ERR,"Can't remove bytes from receiver for serial connection\n");
1347 if (dlt_receiver_move_to_begin(&(daemon_local->receiverSerial))==-1)
1349 dlt_log(LOG_ERR,"Can't move bytes to beginning of receiver buffer for serial connection\n");
1356 int dlt_daemon_process_user_messages(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1360 DltUserHeader *userheader;
1362 PRINT_FUNCTION_VERBOSE(verbose);
1364 if ((daemon==0) || (daemon_local==0))
1366 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_messages()\n");
1370 /* read data from FIFO */
1371 if (dlt_receiver_receive_fd(&(daemon_local->receiver))<0)
1373 dlt_log(LOG_ERR, "dlt_receiver_receive_fd() for user messages failed!\n");
1377 /* look through buffer as long as data is in there */
1380 if (daemon_local->receiver.bytesRcvd < (int32_t)sizeof(DltUserHeader))
1385 /* resync if necessary */
1389 userheader = (DltUserHeader*) (daemon_local->receiver.buf+offset);
1391 /* Check for user header pattern */
1392 if (dlt_user_check_userheader(userheader))
1400 while ((int32_t)(sizeof(DltUserHeader)+offset)<=daemon_local->receiver.bytesRcvd);
1402 /* Check for user header pattern */
1403 if (dlt_user_check_userheader(userheader)==0)
1408 /* Set new start offset */
1411 daemon_local->receiver.buf+=offset;
1412 daemon_local->receiver.bytesRcvd-=offset;
1415 switch (userheader->message)
1417 case DLT_USER_MESSAGE_OVERFLOW:
1419 if (dlt_daemon_process_user_message_overflow(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1425 case DLT_USER_MESSAGE_REGISTER_CONTEXT:
1427 if (dlt_daemon_process_user_message_register_context(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1433 case DLT_USER_MESSAGE_UNREGISTER_CONTEXT:
1435 if (dlt_daemon_process_user_message_unregister_context(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1441 case DLT_USER_MESSAGE_LOG:
1443 if (dlt_daemon_process_user_message_log(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1449 #ifdef DLT_SHM_ENABLE
1450 case DLT_USER_MESSAGE_LOG_SHM:
1452 if (dlt_daemon_process_user_message_log_shm(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1459 case DLT_USER_MESSAGE_REGISTER_APPLICATION:
1461 if (dlt_daemon_process_user_message_register_application(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1467 case DLT_USER_MESSAGE_UNREGISTER_APPLICATION:
1469 if (dlt_daemon_process_user_message_unregister_application(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1475 case DLT_USER_MESSAGE_APP_LL_TS:
1477 if (dlt_daemon_process_user_message_set_app_ll_ts(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1483 case DLT_USER_MESSAGE_LOG_MODE:
1485 if (dlt_daemon_process_user_message_log_mode(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1493 dlt_log(LOG_ERR,"(Internal) Invalid user message type received!\n");
1495 /* remove user header */
1496 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader))==-1)
1498 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user messages\n");
1502 /* In next invocation of do-while loop, a resync will be triggered if additional data was received */
1512 /* keep not read data in buffer */
1513 if (dlt_receiver_move_to_begin(&(daemon_local->receiver))==-1)
1515 dlt_log(LOG_ERR,"Can't move bytes to beginning of receiver buffer for user messages\n");
1522 int dlt_daemon_process_user_message_overflow(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1525 DltUserControlMsgBufferOverflow *userpayload;
1527 PRINT_FUNCTION_VERBOSE(verbose);
1529 if ((daemon==0) || (daemon_local==0))
1531 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_overflow()\n");
1535 if (daemon_local->receiver.bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgBufferOverflow)))
1537 /* Not enough bytes received */
1541 /* get the payload of the user message */
1542 userpayload = (DltUserControlMsgBufferOverflow*) (daemon_local->receiver.buf+sizeof(DltUserHeader));
1544 /* Store in daemon, that a message buffer overflow has occured */
1545 daemon->message_buffer_overflow = DLT_MESSAGE_BUFFER_OVERFLOW;
1547 /* look if TCP connection to client is available */
1550 for (j = 0; j <= daemon_local->fdmax; j++)
1552 /* send to everyone! */
1553 if (FD_ISSET(j, &(daemon_local->master)))
1555 /* except the listener and ourselves */
1556 if ((j != daemon_local->fp) && (j != daemon_local->sock))
1558 dlt_daemon_control_message_buffer_overflow(j, daemon, userpayload->overflow_counter,userpayload->apid,verbose);
1560 /* Reset overflow state */
1561 daemon->message_buffer_overflow = DLT_MESSAGE_BUFFER_NO_OVERFLOW;
1566 /* message was not sent, so store it in ringbuffer */
1569 if(dlt_daemon_control_message_buffer_overflow(DLT_DAEMON_STORE_TO_BUFFER, daemon, userpayload->overflow_counter,
1570 userpayload->apid,verbose))
1572 /* there was an error when storing message */
1573 /* add the counter of lost messages to the daemon counter */
1574 daemon->overflow_counter+=userpayload->overflow_counter;
1578 /* keep not read data in buffer */
1579 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgBufferOverflow))==-1)
1581 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message overflow\n");
1588 int dlt_daemon_send_message_overflow(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1592 PRINT_FUNCTION_VERBOSE(verbose);
1594 if ((daemon==0) || (daemon_local==0))
1596 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_overflow()\n");
1600 /* Store in daemon, that a message buffer overflow has occured */
1601 daemon->message_buffer_overflow = DLT_MESSAGE_BUFFER_OVERFLOW;
1603 /* look if TCP connection to client is available */
1606 for (j = 0; j <= daemon_local->fdmax; j++)
1608 /* send to everyone! */
1609 if (FD_ISSET(j, &(daemon_local->master)))
1611 /* except the listener and ourselves */
1612 if ((j != daemon_local->fp) && (j != daemon_local->sock))
1614 dlt_daemon_control_message_buffer_overflow(j, daemon,daemon->overflow_counter,"", verbose);
1616 /* Reset overflow state */
1617 daemon->message_buffer_overflow = DLT_MESSAGE_BUFFER_NO_OVERFLOW;
1622 /* message was not sent, so report to caller that sending failed */
1631 int dlt_daemon_process_user_message_register_application(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1634 DltDaemonApplication *application;
1635 char description[DLT_DAEMON_DESCSIZE];
1636 DltUserControlMsgRegisterApplication *usercontext;
1638 PRINT_FUNCTION_VERBOSE(verbose);
1640 if ((daemon==0) || (daemon_local==0))
1642 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_register_application()\n");
1646 if (daemon_local->receiver.bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterApplication)))
1648 /* Not enough bytes received */
1652 usercontext = (DltUserControlMsgRegisterApplication*) (daemon_local->receiver.buf+sizeof(DltUserHeader));
1654 memset(description,0,sizeof(description));
1656 len=usercontext->description_length;
1657 if ((len>0) && (len<=DLT_DAEMON_DESCSIZE))
1659 /* Read and store application description */
1660 strncpy(description, (daemon_local->receiver.buf+sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterApplication)), len);
1663 application=dlt_daemon_application_add(daemon,usercontext->apid,usercontext->pid,description,verbose);
1665 /* send log state to new application */
1666 dlt_daemon_user_send_log_state(daemon,application,verbose);
1668 /* keep not read data in buffer */
1669 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterApplication)+len)==-1)
1671 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register application\n");
1677 dlt_log(LOG_CRIT,"Can't add application");
1684 int dlt_daemon_process_user_message_register_context(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1687 int8_t loglevel, tracestatus;
1688 DltUserControlMsgRegisterContext *usercontext;
1689 char description[DLT_DAEMON_DESCSIZE];
1690 DltDaemonApplication *application;
1691 DltDaemonContext *context;
1692 DltServiceGetLogInfoRequest *req;
1698 PRINT_FUNCTION_VERBOSE(verbose);
1700 if ((daemon==0) || (daemon_local==0))
1702 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_register_context()\n");
1706 if (daemon_local->receiver.bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)))
1708 /* Not enough bytes received */
1712 usercontext = (DltUserControlMsgRegisterContext*) (daemon_local->receiver.buf+sizeof(DltUserHeader));
1714 memset(description,0,sizeof(description));
1716 len=usercontext->description_length;
1717 if ((len>0) && (len<=DLT_DAEMON_DESCSIZE))
1719 /* Read and store context description */
1720 strncpy(description, (daemon_local->receiver.buf+sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)), len);
1723 application = dlt_daemon_application_find(daemon,usercontext->apid,verbose);
1727 dlt_log(LOG_ERR, "Application not found in dlt_daemon_process_user_message_register_context()\n");
1728 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)+len)==-1)
1730 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register context\n");
1736 /* Pre-set loglevel */
1737 if (usercontext->log_level == DLT_USER_LOG_LEVEL_NOT_SET)
1739 loglevel=DLT_LOG_DEFAULT;
1743 loglevel=usercontext->log_level;
1744 /* Plausibility check */
1745 if ((loglevel<DLT_LOG_DEFAULT) || (loglevel>DLT_LOG_VERBOSE))
1747 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)+len)==-1)
1749 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register context\n");
1755 /* Pre-set tracestatus */
1756 if (usercontext->trace_status == DLT_USER_TRACE_STATUS_NOT_SET)
1758 tracestatus=DLT_TRACE_STATUS_DEFAULT;
1762 tracestatus=usercontext->trace_status;
1764 /* Plausibility check */
1765 if ((tracestatus<DLT_TRACE_STATUS_DEFAULT) || (tracestatus>DLT_TRACE_STATUS_ON))
1767 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)+len)==-1)
1769 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register context\n");
1775 context = dlt_daemon_context_add(daemon,usercontext->apid,usercontext->ctid, loglevel, tracestatus, usercontext->log_level_pos,application->user_handle,description,verbose);
1779 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)+len)==-1)
1781 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register context\n");
1784 dlt_log(LOG_CRIT,"Can't add context");
1787 /* Create automatic get log info response for registered context */
1788 if (daemon_local->flags.rflag)
1790 /* Prepare request for get log info with one application and one context */
1791 if (dlt_message_init(&msg, verbose)==-1)
1793 dlt_log(LOG_ERR,"Can't initialize message");
1797 msg.datasize = sizeof(DltServiceGetLogInfoRequest);
1798 if (msg.databuffer && (msg.databuffersize < msg.datasize))
1800 free(msg.databuffer);
1803 if (msg.databuffer == 0){
1804 msg.databuffer = (uint8_t *) malloc(msg.datasize);
1805 msg.databuffersize = msg.datasize;
1807 if (msg.databuffer==0)
1809 dlt_log(LOG_ERR,"Can't allocate buffer for get log info message\n");
1813 req = (DltServiceGetLogInfoRequest*) msg.databuffer;
1815 req->service_id = DLT_SERVICE_ID_GET_LOG_INFO;
1817 dlt_set_id(req->apid, usercontext->apid);
1818 dlt_set_id(req->ctid, usercontext->ctid);
1819 dlt_set_id(req->com,"remo");
1823 /* Send response to get log info request to DLT clients */
1824 for (j = 0; j <= daemon_local->fdmax; j++)
1826 /* send to everyone! */
1827 if (FD_ISSET(j, &(daemon_local->master)))
1829 /* except the listener and ourselves */
1830 if ((j != daemon_local->fp) && (j != daemon_local->sock))
1832 dlt_daemon_control_get_log_info(j , daemon, &msg, verbose);
1840 /* Store to buffer */
1841 dlt_daemon_control_get_log_info(DLT_DAEMON_STORE_TO_BUFFER , daemon, &msg, verbose);
1844 dlt_message_free(&msg, verbose);
1847 if (context->user_handle >= DLT_FD_MINIMUM)
1849 /* This call also replaces the default values with the values defined for default */
1850 if (dlt_daemon_user_send_log_level(daemon, context, verbose)==-1)
1852 dlt_log(LOG_ERR,"Can't send current log level as response to user message register context\n");
1857 /* keep not read data in buffer */
1858 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)+len)==-1)
1860 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register context\n");
1867 int dlt_daemon_process_user_message_unregister_application(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1869 DltUserControlMsgUnregisterApplication *usercontext;
1870 DltDaemonApplication *application;
1871 DltDaemonContext *context;
1874 PRINT_FUNCTION_VERBOSE(verbose);
1876 if ((daemon==0) || (daemon_local==0))
1878 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_unregister_application()\n");
1882 if (daemon_local->receiver.bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgUnregisterApplication)))
1884 /* Not enough bytes received */
1888 if (daemon->num_applications>0)
1890 usercontext = (DltUserControlMsgUnregisterApplication*) (daemon_local->receiver.buf+sizeof(DltUserHeader));
1892 /* Delete this application and all corresponding contexts for this application from internal table */
1893 application = dlt_daemon_application_find(daemon,usercontext->apid, verbose);
1897 /* Calculate start offset within contexts[] */
1899 for (i=0; i<(application-(daemon->applications)); i++)
1901 offset_base+=daemon->applications[i].num_contexts;
1904 for (i=application->num_contexts-1; i>=0; i--)
1906 context = &(daemon->contexts[offset_base+i]);
1909 /* Delete context */
1910 if (dlt_daemon_context_del(daemon, context, verbose)==-1)
1912 dlt_log(LOG_ERR,"Can't delete context for user message unregister application\n");
1918 /* Delete this application entry from internal table*/
1919 if (dlt_daemon_application_del(daemon, application, verbose)==-1)
1921 dlt_log(LOG_ERR,"Can't delete application for user message unregister application\n");
1927 /* keep not read data in buffer */
1928 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgUnregisterApplication))==-1)
1930 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message unregister application\n");
1937 int dlt_daemon_process_user_message_unregister_context(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1939 DltUserControlMsgUnregisterContext *usercontext;
1940 DltDaemonContext *context;
1942 PRINT_FUNCTION_VERBOSE(verbose);
1944 if ((daemon==0) || (daemon_local==0))
1946 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_unregister_context()\n");
1950 if (daemon_local->receiver.bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgUnregisterContext)))
1952 /* Not enough bytes received */
1956 usercontext = (DltUserControlMsgUnregisterContext*) (daemon_local->receiver.buf+sizeof(DltUserHeader));
1957 context = dlt_daemon_context_find(daemon,usercontext->apid, usercontext->ctid, verbose);
1961 /* Delete this connection entry from internal table*/
1962 if (dlt_daemon_context_del(daemon, context, verbose)==-1)
1964 dlt_log(LOG_ERR,"Can't delete context for user message unregister context\n");
1969 /* keep not read data in buffer */
1970 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgUnregisterContext))==-1)
1972 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message unregister context\n");
1979 int dlt_daemon_process_user_message_log(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1981 int bytes_to_be_removed;
1982 int j,sent,third_value;
1985 static char text[DLT_DAEMON_TEXTSIZE];
1987 PRINT_FUNCTION_VERBOSE(verbose);
1989 if ((daemon==0) || (daemon_local==0))
1991 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_log()\n");
1995 if (dlt_message_read(&(daemon_local->msg),(unsigned char*)daemon_local->receiver.buf+sizeof(DltUserHeader),daemon_local->receiver.bytesRcvd-sizeof(DltUserHeader),0,verbose)==0)
1997 /* set overwrite ecu id */
1998 if (daemon_local->flags.evalue!=0)
2000 /* Set header extra parameters */
2001 dlt_set_id(daemon_local->msg.headerextra.ecu, daemon->ecuid );
2002 //msg.headerextra.seid = 0;
2003 if (dlt_message_set_extraparameters(&(daemon_local->msg),0)==-1)
2005 dlt_log(LOG_ERR,"Can't set message extra parameters in process user message log\n");
2009 /* Correct value of timestamp, this was changed by dlt_message_set_extraparameters() */
2010 daemon_local->msg.headerextra.tmsp = DLT_BETOH_32(daemon_local->msg.headerextra.tmsp);
2013 /* prepare storage header */
2014 if (DLT_IS_HTYP_WEID(daemon_local->msg.standardheader->htyp))
2016 if (dlt_set_storageheader(daemon_local->msg.storageheader,daemon_local->msg.headerextra.ecu)==-1)
2018 dlt_log(LOG_ERR,"Can't set storage header in process user message log\n");
2024 if (dlt_set_storageheader(daemon_local->msg.storageheader,daemon->ecuid)==-1)
2026 dlt_log(LOG_ERR,"Can't set storage header in process user message log\n");
2032 /* if no filter set or filter is matching display message */
2033 if (daemon_local->flags.xflag)
2035 if (dlt_message_print_hex(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1)
2037 dlt_log(LOG_ERR,"dlt_message_print_hex() failed!\n");
2040 else if (daemon_local->flags.aflag)
2042 if (dlt_message_print_ascii(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1)
2044 dlt_log(LOG_ERR,"dlt_message_print_ascii() failed!\n");
2047 else if (daemon_local->flags.sflag)
2049 if (dlt_message_print_header(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1)
2051 dlt_log(LOG_ERR,"dlt_message_print_header() failed!\n");
2053 /* print message header only */
2058 /* write message to offline trace */
2059 if(((daemon->mode == DLT_USER_MODE_INTERNAL) || (daemon->mode == DLT_USER_MODE_BOTH)) && daemon_local->flags.offlineTraceDirectory[0])
2061 dlt_offline_trace_write(&(daemon_local->offlineTrace),daemon_local->msg.headerbuffer,daemon_local->msg.headersize,
2062 daemon_local->msg.databuffer,daemon_local->msg.datasize,0,0);
2066 /* check if overflow occurred */
2067 if(daemon->overflow_counter)
2069 if(dlt_daemon_send_message_overflow(daemon,daemon_local,verbose)==0)
2071 sprintf(str,"%u messages discarded!\n",daemon->overflow_counter);
2072 dlt_log(LOG_ERR, str);
2073 daemon->overflow_counter=0;
2077 /* look if TCP connection to client is available */
2078 for (j = 0;((daemon->mode == DLT_USER_MODE_EXTERNAL) || (daemon->mode == DLT_USER_MODE_BOTH)) && (j <= daemon_local->fdmax); j++)
2080 /* send to everyone! */
2081 if (FD_ISSET(j, &(daemon_local->master)))
2083 /* except the listener and ourselves */
2084 if (daemon_local->flags.yvalue[0])
2086 third_value = daemon_local->fdserial;
2090 third_value = daemon_local->sock;
2093 if ((j != daemon_local->fp) && (j != daemon_local->sock) && (j != third_value))
2095 DLT_DAEMON_SEM_LOCK();
2097 if (daemon_local->flags.lflag)
2099 send(j,dltSerialHeader,sizeof(dltSerialHeader),0);
2102 send(j,daemon_local->msg.headerbuffer+sizeof(DltStorageHeader),daemon_local->msg.headersize-sizeof(DltStorageHeader),0);
2103 send(j,daemon_local->msg.databuffer,daemon_local->msg.datasize,0);
2105 DLT_DAEMON_SEM_FREE();
2109 else if ((j == daemon_local->fdserial) && (daemon_local->flags.yvalue!=0))
2111 DLT_DAEMON_SEM_LOCK();
2113 if (daemon_local->flags.lflag)
2115 ret=write(j,dltSerialHeader,sizeof(dltSerialHeader));
2118 dlt_log(LOG_ERR,"write(j,dltSerialHeader failed\n");
2121 int32_t diff = daemon_local->msg.headersize-sizeof(DltStorageHeader);
2122 //extra calculation for coverity
2124 ret=write(j,daemon_local->msg.headerbuffer+sizeof(DltStorageHeader),diff);
2127 dlt_log(LOG_ERR,"write(j,daemon_local->msg.headerbuffer failed\n");
2129 ret=write(j,daemon_local->msg.databuffer,daemon_local->msg.datasize);
2132 dlt_log(LOG_ERR,"write(j,daemon_local->msg.databuffer failed\n");
2136 DLT_DAEMON_SEM_FREE();
2143 /* Message was not sent to client, so store it in client ringbuffer */
2146 DLT_DAEMON_SEM_LOCK();
2147 if (dlt_buffer_push3(&(daemon->client_ringbuffer),
2148 daemon_local->msg.headerbuffer+sizeof(DltStorageHeader),daemon_local->msg.headersize-sizeof(DltStorageHeader),
2149 daemon_local->msg.databuffer,daemon_local->msg.datasize,
2153 if(daemon->overflow_counter==0)
2154 dlt_log(LOG_ERR,"Buffer full! Messages will be discarded.\n");
2155 daemon->overflow_counter+=1;
2157 DLT_DAEMON_SEM_FREE();
2161 /* keep not read data in buffer */
2162 bytes_to_be_removed = daemon_local->msg.headersize+daemon_local->msg.datasize-sizeof(DltStorageHeader)+sizeof(DltUserHeader);
2163 if (daemon_local->msg.found_serialheader)
2165 bytes_to_be_removed += sizeof(dltSerialHeader);
2168 if (dlt_receiver_remove(&(daemon_local->receiver),bytes_to_be_removed)==-1)
2170 dlt_log(LOG_ERR,"Can't remove bytes from receiver\n");
2176 dlt_log(LOG_ERR,"Can't read messages from receiver\n");
2183 #ifdef DLT_SHM_ENABLE
2184 int dlt_daemon_process_user_message_log_shm(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
2186 int bytes_to_be_removed=0;
2187 int j,sent,third_value;
2189 uint8_t rcv_buffer[10000];
2191 DltUserHeader *userheader;
2193 static char text[DLT_DAEMON_TEXTSIZE];
2195 PRINT_FUNCTION_VERBOSE(verbose);
2197 if ((daemon==0) || (daemon_local==0))
2199 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_log()\n");
2203 userheader = (DltUserHeader*) (daemon_local->receiver.buf);
2205 //dlt_shm_status(&(daemon_local->dlt_shm));
2208 /* log message in SHM */
2209 if((size = dlt_shm_copy(&(daemon_local->dlt_shm),rcv_buffer,10000)) <= 0)
2211 if (dlt_message_read(&(daemon_local->msg),rcv_buffer,size,0,verbose)!=0) {
2213 dlt_log(LOG_ERR,"Can't read messages from shm\n");
2216 bytes_to_be_removed = daemon_local->msg.headersize+daemon_local->msg.datasize-sizeof(DltStorageHeader)+sizeof(DltUserHeader);
2217 if (daemon_local->msg.found_serialheader)
2219 bytes_to_be_removed += sizeof(dltSerialHeader);
2222 /* set overwrite ecu id */
2223 if (daemon_local->flags.evalue[0])
2225 /* Set header extra parameters */
2226 dlt_set_id(daemon_local->msg.headerextra.ecu, daemon->ecuid );
2227 //msg.headerextra.seid = 0;
2228 if (dlt_message_set_extraparameters(&(daemon_local->msg),0)==-1)
2230 dlt_log(LOG_ERR,"Can't set message extra parameters in process user message log\n");
2231 dlt_shm_remove(&(daemon_local->dlt_shm));
2235 /* Correct value of timestamp, this was changed by dlt_message_set_extraparameters() */
2236 daemon_local->msg.headerextra.tmsp = DLT_BETOH_32(daemon_local->msg.headerextra.tmsp);
2239 /* prepare storage header */
2240 if (DLT_IS_HTYP_WEID(daemon_local->msg.standardheader->htyp))
2242 if (dlt_set_storageheader(daemon_local->msg.storageheader,daemon_local->msg.headerextra.ecu)==-1)
2244 dlt_log(LOG_ERR,"Can't set storage header in process user message log\n");
2245 dlt_shm_remove(&(daemon_local->dlt_shm));
2251 if (dlt_set_storageheader(daemon_local->msg.storageheader,daemon->ecuid)==-1)
2253 dlt_log(LOG_ERR,"Can't set storage header in process user message log\n");
2254 dlt_shm_remove(&(daemon_local->dlt_shm));
2259 /* display message */
2260 if (daemon_local->flags.xflag)
2262 if (dlt_message_print_hex(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1)
2264 dlt_log(LOG_ERR,"dlt_message_print_hex() failed!\n");
2267 else if (daemon_local->flags.aflag)
2269 if (dlt_message_print_ascii(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1)
2271 dlt_log(LOG_ERR,"dlt_message_print_ascii() failed!\n");
2274 else if (daemon_local->flags.sflag)
2276 if (dlt_message_print_header(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1)
2278 dlt_log(LOG_ERR,"dlt_message_print_header() failed!\n");
2280 /* print message header only */
2285 /* write message to offline trace */
2286 if(((daemon->mode == DLT_USER_MODE_INTERNAL) || (daemon->mode == DLT_USER_MODE_BOTH)) && daemon_local->flags.offlineTraceDirectory[0])
2288 dlt_offline_trace_write(&(daemon_local->offlineTrace),daemon_local->msg.headerbuffer,daemon_local->msg.headersize,
2289 daemon_local->msg.databuffer,daemon_local->msg.datasize,0,0);
2293 /* look if TCP connection to client is available */
2294 for (j = 0;((daemon->mode == DLT_USER_MODE_EXTERNAL) || (daemon->mode == DLT_USER_MODE_BOTH)) && (j <= daemon_local->fdmax); j++)
2296 /* send to everyone! */
2297 if (FD_ISSET(j, &(daemon_local->master)))
2299 /* except the listener and ourselves */
2300 if (daemon_local->flags.yvalue[0])
2302 third_value = daemon_local->fdserial;
2306 third_value = daemon_local->sock;
2309 if ((j != daemon_local->fp) && (j != daemon_local->sock) && (j != third_value))
2311 DLT_DAEMON_SEM_LOCK();
2313 if (daemon_local->flags.lflag)
2315 send(j,dltSerialHeader,sizeof(dltSerialHeader),0);
2318 send(j,daemon_local->msg.headerbuffer+sizeof(DltStorageHeader),daemon_local->msg.headersize-sizeof(DltStorageHeader),0);
2319 send(j,daemon_local->msg.databuffer,daemon_local->msg.datasize,0);
2321 DLT_DAEMON_SEM_FREE();
2325 else if ((j == daemon_local->fdserial) && (daemon_local->flags.yvalue[0]))
2327 DLT_DAEMON_SEM_LOCK();
2329 if (daemon_local->flags.lflag)
2331 ret=write(j,dltSerialHeader,sizeof(dltSerialHeader));
2334 ret=write(j,daemon_local->msg.headerbuffer+sizeof(DltStorageHeader),daemon_local->msg.headersize-sizeof(DltStorageHeader));
2335 ret=write(j,daemon_local->msg.databuffer,daemon_local->msg.datasize);
2337 DLT_DAEMON_SEM_FREE();
2344 /* Message was not sent to client, so store it in client ringbuffer */
2345 if (sent==1 || (daemon->mode == DLT_USER_MODE_OFF))
2347 if(userheader->message == DLT_USER_MESSAGE_LOG_SHM) {
2348 /* dlt message was sent, remove from buffer if log message from shm */
2349 dlt_shm_remove(&(daemon_local->dlt_shm));
2354 /* dlt message was not sent, keep in buffer */
2360 /* keep not read data in buffer */
2361 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader))==-1)
2363 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message overflow\n");
2371 int dlt_daemon_process_user_message_set_app_ll_ts(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
2373 DltUserControlMsgAppLogLevelTraceStatus *usercontext;
2374 DltDaemonApplication *application;
2375 DltDaemonContext *context;
2377 int8_t old_log_level, old_trace_status;
2379 PRINT_FUNCTION_VERBOSE(verbose);
2381 if ((daemon==0) || (daemon_local==0))
2383 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_set_app_ll_ts()\n");
2387 if (daemon_local->receiver.bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgAppLogLevelTraceStatus )))
2389 /* Not enough bytes receeived */
2393 if (daemon->num_applications>0)
2395 usercontext = (DltUserControlMsgAppLogLevelTraceStatus*) (daemon_local->receiver.buf+sizeof(DltUserHeader));
2397 /* Get all contexts with application id matching the received application id */
2398 application = dlt_daemon_application_find(daemon, usercontext->apid, verbose);
2401 /* Calculate start offset within contexts[] */
2403 for (i=0; i<(application-(daemon->applications)); i++)
2405 offset_base+=daemon->applications[i].num_contexts;
2408 for (i=0; i < application->num_contexts; i++)
2410 context = &(daemon->contexts[offset_base+i]);
2413 old_log_level = context->log_level;
2414 context->log_level = usercontext->log_level; /* No endianess conversion necessary*/
2416 old_trace_status = context->trace_status;
2417 context->trace_status = usercontext->trace_status; /* No endianess conversion necessary */
2419 /* The folowing function sends also the trace status */
2420 if (context->user_handle >= DLT_FD_MINIMUM && dlt_daemon_user_send_log_level(daemon, context, verbose)!=0)
2422 context->log_level = old_log_level;
2423 context->trace_status = old_trace_status;
2430 /* keep not read data in buffer */
2431 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgAppLogLevelTraceStatus))==-1)
2433 dlt_log(LOG_ERR,"Can't remove bytes from receiver\n");
2440 int dlt_daemon_process_user_message_log_mode(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
2442 DltUserControlMsgLogMode *logmode;
2444 PRINT_FUNCTION_VERBOSE(verbose);
2446 if ((daemon==0) || (daemon_local==0))
2448 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_log_mode()\n");
2452 if (daemon_local->receiver.bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgUnregisterContext)))
2454 /* Not enough bytes received */
2458 logmode = (DltUserControlMsgLogMode*) (daemon_local->receiver.buf+sizeof(DltUserHeader));
2460 /* set the new log mode */
2461 daemon->mode = logmode->log_mode;
2463 /* write configuration persistantly */
2464 dlt_daemon_configuration_save(daemon, daemon->runtime_configuration, verbose);
2466 /* keep not read data in buffer */
2467 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogMode))==-1)
2469 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message log mode\n");
2476 int dlt_daemon_send_ringbuffer_to_client(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
2478 static uint8_t data[DLT_DAEMON_RCVBUFSIZE];
2483 PRINT_FUNCTION_VERBOSE(verbose);
2485 if ((daemon==0) || (daemon_local==0))
2487 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_send_ringbuffer_to_client()\n");
2491 /* Attention: If the message can't be send at this time, it will be silently discarded. */
2492 while ((length = dlt_buffer_pull(&(daemon->client_ringbuffer), data, sizeof(data) )) > 0)
2494 /* look if TCP connection to client is available */
2495 for (j = 0; j <= daemon_local->fdmax; j++)
2497 /* send to everyone! */
2498 if (FD_ISSET(j, &(daemon_local->master)))
2500 /* except the listener and ourselves */
2501 if (daemon_local->flags.yvalue[0])
2503 third_value = daemon_local->fdserial;
2507 third_value = daemon_local->sock;
2510 if ((j != daemon_local->fp) && (j != daemon_local->sock) && (j != third_value))
2512 DLT_DAEMON_SEM_LOCK();
2514 if (daemon_local->flags.lflag)
2516 send(j,dltSerialHeader,sizeof(dltSerialHeader),0);
2518 send(j,data,length,0);
2520 DLT_DAEMON_SEM_FREE();
2523 else if ((j == daemon_local->fdserial) && (daemon_local->flags.yvalue[0]))
2525 DLT_DAEMON_SEM_LOCK();
2527 if (daemon_local->flags.lflag)
2529 ret=write(j,dltSerialHeader,sizeof(dltSerialHeader));
2532 dlt_log(LOG_ERR, "dlt_daemon_send_ringbuffer_to_client: write(j,dltSerialHeader,sizeof(dltSerialHeader)) failed!\n");
2533 DLT_DAEMON_SEM_FREE();
2537 ret=write(j,data,length);
2540 dlt_log(LOG_ERR, "dlt_daemon_send_ringbuffer_to_client: write(j,data,length) failed!\n");
2541 DLT_DAEMON_SEM_FREE();
2544 DLT_DAEMON_SEM_FREE();
2549 length = sizeof(data);
2555 void dlt_daemon_timingpacket_thread(void *ptr)
2557 DltDaemonPeriodicData info;
2560 DltDaemonTimingPacketThreadData *data;
2562 DltDaemonLocal *daemon_local;
2566 dlt_log(LOG_ERR, "No data pointer passed to timingpacket thread\n");
2570 data = (DltDaemonTimingPacketThreadData*)ptr;
2571 daemon = data->daemon;
2572 daemon_local = data->daemon_local;
2574 if ((daemon==0) || (daemon_local==0))
2576 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_timingpacket_thread()");
2580 if (dlt_daemon_make_periodic (1000000, &info, daemon_local->flags.vflag)<0)
2582 dlt_log(LOG_CRIT,"Can't initialize thread timer!\n");
2588 /* If enabled, send timing packets to all clients */
2589 if (daemon->timingpackets)
2591 for (j = 0; j <= daemon_local->fdmax; j++)
2593 /* send to everyone! */
2594 if (FD_ISSET(j, &(daemon_local->master)))
2596 /* except the listener and ourselves */
2597 if ((j != daemon_local->fp) && (j != daemon_local->sock))
2599 dlt_daemon_control_message_time(j, daemon, daemon_local->flags.vflag);
2604 /* Wait for next period */
2605 dlt_daemon_wait_period (&info, daemon_local->flags.vflag);
2609 void dlt_daemon_ecu_version_thread(void *ptr)
2611 DltDaemonECUVersionThreadData *data = (DltDaemonECUVersionThreadData *)ptr;
2612 DltDaemonPeriodicData info;
2613 const unsigned int DLT_ECU_VERSION_PERIOD_TIME = 1000000*60; // 60 Seconds
2615 if (dlt_daemon_make_periodic (DLT_ECU_VERSION_PERIOD_TIME, &info, data->daemon_local->flags.vflag)<0)
2617 dlt_log(LOG_CRIT,"Can't initialize thread timer!\n");
2624 for (i = 0; i <= data->daemon_local->fdmax; i++)
2626 /* send to everyone! */
2627 if (FD_ISSET(i, &(data->daemon_local->master)))
2629 /* except the listener and ourselves */
2630 if ((i != data->daemon_local->fp) && (i != data->daemon_local->sock))
2632 dlt_daemon_control_get_software_version(i, data->daemon, data->daemon_local->flags.vflag);
2636 dlt_daemon_wait_period (&info, data->daemon_local->flags.vflag);
2640 #if defined(DLT_SYSTEMD_WATCHDOG_ENABLE)
2641 void dlt_daemon_systemd_watchdog_thread(void *ptr)
2644 int watchdogTimeoutSeconds;
2645 int notifyPeriodNSec;
2646 DltDaemonPeriodicData info;
2647 DltDaemonTimingPacketThreadData *data;
2649 DltDaemonLocal *daemon_local;
2650 static uint32_t lastDaemonOperation;
2654 dlt_log(LOG_ERR, "No data pointer passed to systemd watchdog thread\n");
2658 data = (DltDaemonTimingPacketThreadData*)ptr;
2659 daemon = data->daemon;
2660 daemon_local = data->daemon_local;
2662 if ((daemon==0) || (daemon_local==0))
2664 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_timingpacket_thread()");
2668 watchdogUSec = getenv("WATCHDOG_USEC");
2672 watchdogTimeoutSeconds = atoi(watchdogUSec);
2673 // Calculate half of WATCHDOG_USEC in ns for timer tick
2674 notifyPeriodNSec = watchdogTimeoutSeconds / 2 ;
2676 if( notifyPeriodNSec > 0 )
2678 sprintf(str,"systemd watchdog timeout: %i nsec - timer will be initialized: %i nsec\n", watchdogTimeoutSeconds, notifyPeriodNSec );
2679 dlt_log(LOG_INFO, str);
2681 if (dlt_daemon_make_periodic (notifyPeriodNSec, &info, daemon_local->flags.vflag)<0)
2683 dlt_log(LOG_CRIT, "Could not initialize systemd watchdog timer");
2689 /* If main thread has changed its last operation time, reset watchdog */
2690 if(daemon_local->lastOperationTime != lastDaemonOperation)
2692 if(sd_notify(0, "WATCHDOG=1") < 0)
2694 dlt_log(LOG_CRIT, "Could not reset systemd watchdog\n");
2696 lastDaemonOperation = daemon_local->lastOperationTime;
2699 /* Wait for next period */
2700 dlt_daemon_wait_period (&info, daemon_local->flags.vflag);
2705 sprintf(str,"systemd watchdog timeout incorrect: %i\n", watchdogTimeoutSeconds);
2706 dlt_log(LOG_CRIT, str);
2711 dlt_log(LOG_CRIT, "systemd watchdog timeout (WATCHDOG_USEC) is null!\n");
2716 int dlt_daemon_make_periodic (unsigned int period, DltDaemonPeriodicData *info, int verbose)
2722 struct itimerspec itval;
2724 PRINT_FUNCTION_VERBOSE(verbose);
2728 dlt_log(LOG_ERR,"No data pointer passed!\n");
2732 /* Create the timer */
2733 fd = timerfd_create (CLOCK_MONOTONIC, 0);
2735 info->wakeups_missed = 0;
2736 info->timer_fd = fd;
2740 dlt_log(LOG_ERR,"Can't create timer filedescriptor");
2744 /* Make the timer periodic */
2745 sec = period/1000000;
2746 ns = (period - (sec * 1000000)) * 1000;
2747 itval.it_interval.tv_sec = sec;
2748 itval.it_interval.tv_nsec = ns;
2749 itval.it_value.tv_sec = sec;
2750 itval.it_value.tv_nsec = ns;
2752 ret = timerfd_settime (fd, 0, &itval, NULL);
2757 void dlt_daemon_wait_period (DltDaemonPeriodicData *info, int verbose)
2759 unsigned long long missed;
2762 PRINT_FUNCTION_VERBOSE(verbose);
2764 ret = read (info->timer_fd, &missed, sizeof (missed));
2766 dlt_log(LOG_ERR,"dlt_daemon_wait_period: Read failed");
2771 info->wakeups_missed += (missed - 1);