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"
90 * The package automotive-dlt includes the following items:
91 * - dlt daemon (dlt-daemon)
92 * - adptors to to interface the daemon (dlt-adaptor-stdin, dlt-adaptor-udp)
93 * - dlt client gui (dlt-viewer)
94 * - dlt console tools (dlt-receive, dlt-convert)
95 * - examples (dlt-example-user, dlt-example-user-func, dlt-example-ringbuffer)
96 * - a library including user-application, client and common functions
100 \defgroup daemon DLT Daemon
105 /** Global text output buffer, mainly used for creation of error/warning strings */
106 static char str[DLT_DAEMON_TEXTBUFSIZE];
108 static DltDaemonTimingPacketThreadData dlt_daemon_timingpacket_thread_data;
110 static pthread_t dlt_daemon_timingpacket_thread_handle;
111 static pthread_attr_t dlt_daemon_timingpacket_thread_attr;
114 * Print usage information of tool.
118 printf("Usage: dlt-daemon [options]\n");
119 printf("DLT logging daemon %s\n", _DLT_PACKAGE_REVISION);
120 printf("Options:\n");
121 printf(" -d Daemonize\n");
122 printf(" -h Usage\n");
123 printf(" -c filename DLT daemon configuration file (Default: /etc/dlt.conf)\n");
129 int option_handling(DltDaemonLocal *daemon_local,int argc, char* argv[])
135 fprintf (stderr, "Invalid parameter passed to option_handling()\n");
139 /* Initialize flags */
140 memset(daemon_local,0,sizeof(DltDaemonLocal));
144 while ((c = getopt (argc, argv, "hdc:")) != -1)
150 daemon_local->flags.dflag = 1;
155 strncpy(daemon_local->flags.cvalue,optarg,sizeof(daemon_local->flags.cvalue));
161 return -2; /* return no error */
167 fprintf (stderr, "Option -%c requires an argument.\n", optopt);
169 else if (isprint (optopt))
171 fprintf (stderr, "Unknown option `-%c'.\n", optopt);
175 fprintf (stderr, "Unknown option character `\\x%x'.\n",optopt);
177 /* unknown or wrong option used, show usage information and terminate */
183 fprintf (stderr, "Invalid option, this should never occur!\n");
191 } /* option_handling() */
196 int option_file_parser(DltDaemonLocal *daemon_local)
203 const char *filename;
205 /* set default values for configuration */
206 daemon_local->flags.sharedMemorySize = DLT_SHM_SIZE;
207 daemon_local->flags.sendMessageTime = 0;
208 daemon_local->flags.offlineTraceDirectory[0] = 0;
209 daemon_local->flags.offlineTraceFileSize = 1000000;
210 daemon_local->flags.offlineTraceMaxSize = 0;
211 daemon_local->flags.loggingMode = 0;
212 daemon_local->flags.loggingLevel = 6;
213 strncpy(daemon_local->flags.loggingFilename, DLT_USER_DIR "/dlt.log",sizeof(daemon_local->flags.loggingFilename));
215 /* open configuration file */
216 if(daemon_local->flags.cvalue[0])
217 filename = daemon_local->flags.cvalue;
219 filename = "/etc/dlt.conf";
220 //printf("Load configuration from file: %s\n",filename);
221 pFile = fopen (filename,"r");
227 /* fetch line from configuration file */
228 if ( fgets (line , 1024 , pFile) != NULL )
230 pch = strtok (line," =\r\n");
236 if(strcmp(pch,"#")==0)
241 strncpy(token,pch,sizeof(token));
245 strncpy(value,pch,sizeof(value));
249 pch = strtok (NULL, " =\r\n");
252 if(token[0] && value[0])
254 /* parse arguments here */
255 if(strcmp(token,"Verbose")==0)
257 daemon_local->flags.vflag = atoi(value);
258 //printf("Option: %s=%s\n",token,value);
260 else if(strcmp(token,"PrintASCII")==0)
262 daemon_local->flags.aflag = atoi(value);
263 //printf("Option: %s=%s\n",token,value);
265 else if(strcmp(token,"PrintHex")==0)
267 daemon_local->flags.xflag = atoi(value);
268 //printf("Option: %s=%s\n",token,value);
270 else if(strcmp(token,"PrintHeadersOnly")==0)
272 daemon_local->flags.sflag = atoi(value);
273 //printf("Option: %s=%s\n",token,value);
275 else if(strcmp(token,"SendSerialHeader")==0)
277 daemon_local->flags.lflag = atoi(value);
278 //printf("Option: %s=%s\n",token,value);
280 else if(strcmp(token,"SendContextRegistration")==0)
282 daemon_local->flags.rflag = atoi(value);
283 //printf("Option: %s=%s\n",token,value);
285 else if(strcmp(token,"SendMessageTime")==0)
287 daemon_local->flags.sendMessageTime = atoi(value);
288 //printf("Option: %s=%s\n",token,value);
290 else if(strcmp(token,"RS232SyncSerialHeader")==0)
292 daemon_local->flags.mflag = atoi(value);
293 //printf("Option: %s=%s\n",token,value);
295 else if(strcmp(token,"TCPSyncSerialHeader")==0)
297 daemon_local->flags.nflag = atoi(value);
298 //printf("Option: %s=%s\n",token,value);
300 else if(strcmp(token,"RS232DeviceName")==0)
302 strncpy(daemon_local->flags.yvalue,value,sizeof(daemon_local->flags.yvalue));
303 //printf("Option: %s=%s\n",token,value);
305 else if(strcmp(token,"RS232Baudrate")==0)
307 strncpy(daemon_local->flags.bvalue,value,sizeof(daemon_local->flags.bvalue));
308 //printf("Option: %s=%s\n",token,value);
310 else if(strcmp(token,"ECUId")==0)
312 strncpy(daemon_local->flags.evalue,value,sizeof(daemon_local->flags.evalue));
313 //printf("Option: %s=%s\n",token,value);
315 else if(strcmp(token,"PersistanceStoragePath")==0)
317 strncpy(daemon_local->flags.ivalue,value,sizeof(daemon_local->flags.ivalue));
318 //printf("Option: %s=%s\n",token,value);
320 else if(strcmp(token,"LoggingMode")==0)
322 daemon_local->flags.loggingMode = atoi(value);
323 //printf("Option: %s=%s\n",token,value);
325 else if(strcmp(token,"LoggingLevel")==0)
327 daemon_local->flags.loggingLevel = atoi(value);
328 //printf("Option: %s=%s\n",token,value);
330 else if(strcmp(token,"LoggingFilename")==0)
332 strncpy(daemon_local->flags.loggingFilename,value,sizeof(daemon_local->flags.loggingFilename));
333 //printf("Option: %s=%s\n",token,value);
335 else if(strcmp(token,"SharedMemorySize")==0)
337 daemon_local->flags.sharedMemorySize = atoi(value);
338 //printf("Option: %s=%s\n",token,value);
340 else if(strcmp(token,"OfflineTraceDirectory")==0)
342 strncpy(daemon_local->flags.offlineTraceDirectory,value,sizeof(daemon_local->flags.offlineTraceDirectory));
343 //printf("Option: %s=%s\n",token,value);
345 else if(strcmp(token,"OfflineTraceFileSize")==0)
347 daemon_local->flags.offlineTraceFileSize = atoi(value);
348 //printf("Option: %s=%s\n",token,value);
350 else if(strcmp(token,"OfflineTraceMaxSize")==0)
352 daemon_local->flags.offlineTraceMaxSize = atoi(value);
353 //printf("Option: %s=%s\n",token,value);
357 fprintf(stderr, "Unknown option: %s=%s\n",token,value);
370 fprintf(stderr, "Cannot open configuration file: %s\n",filename);
377 * Main function of tool.
379 int main(int argc, char* argv[])
381 char version[DLT_DAEMON_TEXTBUFSIZE];
382 DltDaemonLocal daemon_local;
387 /* Command line option handling */
388 if ((back = option_handling(&daemon_local,argc,argv))<0)
391 fprintf (stderr, "option_handling() failed!\n");
396 /* Configuration file option handling */
397 if ((back = option_file_parser(&daemon_local))<0)
400 fprintf (stderr, "option_file_parser() failed!\n");
405 /* Initialize internal logging facility */
406 dlt_log_set_filename(daemon_local.flags.loggingFilename);
407 dlt_log_set_level(daemon_local.flags.loggingLevel);
408 dlt_log_init(daemon_local.flags.loggingMode);
410 /* Print version information */
411 dlt_get_version(version);
413 sprintf(str,"Starting DLT Daemon; %s\n", version );
414 dlt_log(LOG_NOTICE, str);
416 PRINT_FUNCTION_VERBOSE(daemon_local.flags.vflag);
418 /* --- Daemon init phase 1 begin --- */
419 if (dlt_daemon_local_init_p1(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
421 dlt_log(LOG_CRIT,"Initialization of phase 1 failed!\n");
424 /* --- Daemon init phase 1 end --- */
426 /* --- Daemon connection init begin */
427 if (dlt_daemon_local_connection_init(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
429 dlt_log(LOG_CRIT,"Initialization of local connections failed!\n");
432 /* --- Daemon connection init end */
434 /* --- Daemon init phase 2 begin --- */
435 if (dlt_daemon_local_init_p2(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
437 dlt_log(LOG_CRIT,"Initialization of phase 2 failed!\n");
440 /* --- Daemon init phase 2 end --- */
444 /* wait for events form all FIFO and sockets */
445 daemon_local.read_fds = daemon_local.master;
446 if (select(daemon_local.fdmax+1, &(daemon_local.read_fds), NULL, NULL, NULL) == -1)
448 dlt_log(LOG_CRIT, "select() failed!\n");
452 /* run through the existing FIFO and sockets to check for events */
453 for (i = 0; i <= daemon_local.fdmax; i++)
455 if (FD_ISSET(i, &(daemon_local.read_fds)))
457 if (i == daemon_local.sock && ((daemon.mode == DLT_USER_MODE_EXTERNAL) || (daemon.mode == DLT_USER_MODE_BOTH)))
459 /* event from TCP server socket, new connection */
460 if (dlt_daemon_process_client_connect(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
462 dlt_log(LOG_CRIT,"Connect to dlt client failed!\n");
466 else if (i == daemon_local.fp)
468 /* event from the FIFO happened */
469 if (dlt_daemon_process_user_messages(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
471 dlt_log(LOG_CRIT,"Processing of messages from user connection failed!\n");
475 else if ((i == daemon_local.fdserial) && (daemon_local.flags.yvalue[0]))
477 /* event from serial connection to client received */
478 if (dlt_daemon_process_client_messages_serial(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
480 dlt_log(LOG_CRIT,"Processing of messages from serial connection failed!\n");
486 /* event from tcp connection to client received */
487 daemon_local.receiverSock.fd = i;
488 if (dlt_daemon_process_client_messages(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
490 dlt_log(LOG_CRIT,"Processing of messages from client connection failed!\n");
498 dlt_daemon_local_cleanup(&daemon, &daemon_local, daemon_local.flags.vflag);
500 dlt_log(LOG_NOTICE, "Leaving DLT daemon\n");
506 int dlt_daemon_local_init_p1(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
508 PRINT_FUNCTION_VERBOSE(verbose);
510 if ((daemon==0) || (daemon_local==0))
512 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_local_init_p1()\n");
516 /* Check for daemon mode */
517 if (daemon_local->flags.dflag)
519 dlt_daemon_daemonize(daemon_local->flags.vflag);
522 /* initialise structure to use DLT file */
523 if (dlt_file_init(&(daemon_local->file),daemon_local->flags.vflag)==-1)
525 dlt_log(LOG_ERR,"Could not initialize file structure\n");
526 /* Return value ignored, dlt daemon will exit */
527 dlt_file_free(&(daemon_local->file),daemon_local->flags.vflag);
531 signal(SIGPIPE,SIG_IGN);
533 signal(SIGTERM, dlt_daemon_signal_handler); /* software termination signal from kill */
534 signal(SIGHUP, dlt_daemon_signal_handler); /* hangup signal */
535 signal(SIGQUIT, dlt_daemon_signal_handler);
536 signal(SIGINT, dlt_daemon_signal_handler);
538 /* init offline trace */
539 if(((daemon->mode == DLT_USER_MODE_INTERNAL) || (daemon->mode == DLT_USER_MODE_BOTH)) && daemon_local->flags.offlineTraceDirectory[0])
541 if (dlt_offline_trace_init(&(daemon_local->offlineTrace),daemon_local->flags.offlineTraceDirectory,daemon_local->flags.offlineTraceFileSize,daemon_local->flags.offlineTraceMaxSize)==-1)
543 dlt_log(LOG_ERR,"Could not initialize offline trace\n");
551 int dlt_daemon_local_init_p2(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
553 PRINT_FUNCTION_VERBOSE(verbose);
555 if ((daemon==0) || (daemon_local==0))
557 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_local_init_p2()\n");
562 if (dlt_daemon_init(daemon,daemon_local->flags.ivalue,daemon_local->flags.vflag)==-1)
564 dlt_log(LOG_ERR,"Could not initialize daemon data\n");
568 /* Set ECU id of daemon */
569 if (daemon_local->flags.evalue[0])
571 dlt_set_id(daemon->ecuid,daemon_local->flags.evalue);
575 dlt_set_id(daemon->ecuid,DLT_DAEMON_ECU_ID);
578 /* Set flag for optional sending of serial header */
579 daemon->sendserialheader = daemon_local->flags.lflag;
581 #ifdef DLT_SHM_ENABLE
582 /* init shared memory */
583 if (dlt_shm_init_server(&(daemon_local->dlt_shm),DLT_SHM_KEY,daemon_local->flags.sharedMemorySize)==-1)
585 dlt_log(LOG_ERR,"Could not initialize shared memory\n");
590 /* prepare main loop */
591 if (dlt_message_init(&(daemon_local->msg),daemon_local->flags.vflag)==-1)
593 dlt_log(LOG_ERR,"Could not initialize message\n");
597 if (dlt_receiver_init(&(daemon_local->receiver),daemon_local->fp,DLT_DAEMON_RCVBUFSIZE)==-1)
599 dlt_log(LOG_ERR,"Could not initialize receiver\n");
602 if (dlt_receiver_init(&(daemon_local->receiverSock),daemon_local->sock,DLT_DAEMON_RCVBUFSIZESOCK)==-1)
604 dlt_log(LOG_ERR,"Could not initialize receiver for socket\n");
607 if (daemon_local->flags.yvalue[0])
609 if (dlt_receiver_init(&(daemon_local->receiverSerial),daemon_local->fdserial,DLT_DAEMON_RCVBUFSIZESERIAL)==-1)
611 dlt_log(LOG_ERR,"Could not initialize receiver for serial connection\n");
616 /* setup period thread for timing packets */
617 if (pthread_attr_init(&dlt_daemon_timingpacket_thread_attr)<0)
619 dlt_log(LOG_WARNING, "Initialization of default thread stack size failed!\n");
623 if (pthread_attr_setstacksize(&dlt_daemon_timingpacket_thread_attr,DLT_DAEMON_TIMINGPACKET_THREAD_STACKSIZE)<0)
625 dlt_log(LOG_WARNING, "Setting of default thread stack size failed!\n");
629 /* configure sending timing packets */
630 if (daemon_local->flags.sendMessageTime)
632 daemon->timingpackets = 1;
635 /* Binary semaphore for thread */
636 if (sem_init(&dlt_daemon_mutex, 0, 1)==-1)
638 dlt_log(LOG_ERR,"Could not initialize binary semaphore\n");
643 dlt_daemon_timingpacket_thread_data.daemon = daemon;
644 dlt_daemon_timingpacket_thread_data.daemon_local = daemon_local;
646 if (pthread_create(&(dlt_daemon_timingpacket_thread_handle),
647 &dlt_daemon_timingpacket_thread_attr,
648 (void *) &dlt_daemon_timingpacket_thread,
649 (void *)&dlt_daemon_timingpacket_thread_data)!=0)
651 dlt_log(LOG_ERR,"Could not initialize timing packet thread\n");
652 pthread_attr_destroy(&dlt_daemon_timingpacket_thread_attr);
656 pthread_attr_destroy(&dlt_daemon_timingpacket_thread_attr);
661 int dlt_daemon_local_connection_init(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
666 struct sockaddr_in servAddr;
667 unsigned int servPort = DLT_DAEMON_TCP_PORT;
669 PRINT_FUNCTION_VERBOSE(verbose);
671 if ((daemon==0) || (daemon_local==0))
673 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_local_connection_init()\n");
677 /* open named pipe(FIFO) to receive DLT messages from users */
680 /* Try to delete existing pipe, ignore result of unlink */
681 unlink(DLT_USER_FIFO);
683 ret=mkfifo(DLT_USER_FIFO, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH );
686 sprintf(str,"FIFO user %s cannot be created!\n",DLT_USER_FIFO);
687 dlt_log(LOG_ERR, str);
691 daemon_local->fp = open(DLT_USER_FIFO, O_RDWR);
692 if (daemon_local->fp==-1)
694 sprintf(str,"FIFO user %s cannot be opened!\n",DLT_USER_FIFO);
695 dlt_log(LOG_ERR, str);
699 /* create and open socket to receive incoming connections from client */
700 if ((daemon_local->sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
702 dlt_log(LOG_ERR, "socket() failed!\n");
706 setsockopt(daemon_local->sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
707 memset(&servAddr, 0, sizeof(servAddr));
708 servAddr.sin_family = AF_INET;
709 servAddr.sin_addr.s_addr = INADDR_ANY;
710 servAddr.sin_port = htons(servPort);
712 if (bind(daemon_local->sock, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0)
714 dlt_log(LOG_ERR, "bind() failed!\n");
718 if (daemon_local->flags.vflag)
720 dlt_log(LOG_INFO, "Bind succesfull\n");
723 if (listen(daemon_local->sock, 3) < 0)
725 dlt_log(LOG_ERR, "listen() failed!\n");
729 if (daemon_local->flags.vflag)
731 dlt_log(LOG_INFO, "Listen succesfull\n");
734 /* prepare usage of select(), add FIFO and receiving socket */
735 FD_ZERO(&(daemon_local->master));
736 FD_ZERO(&(daemon_local->read_fds));
737 FD_SET(daemon_local->sock, &(daemon_local->master));
739 daemon_local->fdmax = daemon_local->sock;
741 FD_SET(daemon_local->fp, &(daemon_local->master));
743 if (daemon_local->fp > daemon_local->fdmax)
745 daemon_local->fdmax = daemon_local->fp;
748 if (daemon_local->flags.yvalue[0])
750 /* create and open serial connection from/to client */
751 /* open serial connection */
752 daemon_local->fdserial=open(daemon_local->flags.yvalue,O_RDWR);
753 if (daemon_local->fdserial<0)
755 sprintf(str,"Failed to open serial device %s\n", daemon_local->flags.yvalue);
756 daemon_local->flags.yvalue[0] = 0;
757 dlt_log(LOG_ERR, str);
761 if (isatty(daemon_local->fdserial))
763 if (daemon_local->flags.bvalue[0])
765 daemon_local->baudrate = dlt_convert_serial_speed(atoi(daemon_local->flags.bvalue));
769 daemon_local->baudrate = dlt_convert_serial_speed(DLT_DAEMON_SERIAL_DEFAULT_BAUDRATE);
772 if (dlt_setup_serial(daemon_local->fdserial,daemon_local->baudrate)<0)
774 close(daemon_local->fdserial);
775 sprintf(str,"Failed to configure serial device %s (%s) \n", daemon_local->flags.yvalue, strerror(errno));
776 daemon_local->flags.yvalue[0] = 0;
777 dlt_log(LOG_ERR, str);
781 FD_SET(daemon_local->fdserial, &(daemon_local->master));
783 if (daemon_local->fdserial > daemon_local->fdmax)
785 daemon_local->fdmax = daemon_local->fdserial;
788 if (daemon_local->flags.vflag)
790 dlt_log(LOG_INFO, "Serial init done\n");
795 close(daemon_local->fdserial);
796 fprintf(stderr,"Device is not a serial device, device = %s (%s) \n", daemon_local->flags.yvalue, strerror(errno));
797 daemon_local->flags.yvalue[0] = 0;
806 void dlt_daemon_local_cleanup(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
808 PRINT_FUNCTION_VERBOSE(verbose);
810 if ((daemon==0) || (daemon_local==0))
812 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_local_cleanup()\n");
817 dlt_receiver_free(&(daemon_local->receiver));
819 dlt_receiver_free(&(daemon_local->receiverSock));
822 dlt_message_free(&(daemon_local->msg),daemon_local->flags.vflag);
823 close(daemon_local->fp);
825 /* free shared memory */
826 if(daemon_local->flags.offlineTraceDirectory[0])
827 dlt_offline_trace_free(&(daemon_local->offlineTrace));
829 if (daemon_local->flags.ovalue[0])
831 close(daemon_local->ohandle);
836 dlt_file_free(&(daemon_local->file),daemon_local->flags.vflag);
838 /* Try to delete existing pipe, ignore result of unlink() */
839 unlink(DLT_USER_FIFO);
841 #ifdef DLT_SHM_ENABLE
842 /* free shared memory */
843 dlt_shm_free_server(&(daemon_local->dlt_shm));
846 /* Try to delete lock file, ignore result of unlink() */
847 unlink(DLT_DAEMON_LOCK_FILE);
850 void dlt_daemon_signal_handler(int sig)
859 /* finalize the server */
860 //dlt_log("terminate signal catched");
861 dlt_log(LOG_NOTICE, "Exiting DLT daemon\n");
863 /* Try to delete existing pipe, ignore result of unlink() */
864 unlink(DLT_USER_FIFO);
866 /* Try to delete lock file, ignore result of unlink() */
867 unlink(DLT_DAEMON_LOCK_FILE);
869 /* Terminate program */
875 /* This case should never occur */
879 } /* dlt_daemon_signal_handler() */
881 void dlt_daemon_daemonize(int verbose)
883 int i,lfp,bytes_written,ret;
885 PRINT_FUNCTION_VERBOSE(verbose);
887 dlt_log(LOG_NOTICE, "Daemon mode\n");
893 dlt_log(LOG_CRIT, "Unable to fork(), exiting DLT daemon\n");
894 exit(-1); /* fork error */
899 exit(0); /* parent exits */
901 /* child (daemon) continues */
903 /* Process independency */
905 /* obtain a new process group */
908 dlt_log(LOG_CRIT, "setsid() failed, exiting DLT daemon\n");
909 exit(-1); /* fork error */
912 /* Close descriptors */
913 for (i=getdtablesize();i>=0;--i)
915 close(i); /* close all descriptors */
918 /* Open standard descriptors stdin, stdout, stderr */
919 i=open("/dev/null",O_RDWR); /* open stdin */
920 ret=dup(i); /* stdout */
921 ret=dup(i); /* stderr */
924 umask(DLT_DAEMON_UMASK);
926 /* Change to known directory */
927 ret=chdir(DLT_USER_DIR);
929 /* Ensure single copy of daemon;
930 run only one instance at a time */
931 lfp=open(DLT_DAEMON_LOCK_FILE,O_RDWR|O_CREAT,DLT_DAEMON_LOCK_FILE_PERM);
934 dlt_log(LOG_CRIT, "can't open lock file, exiting DLT daemon\n");
935 exit(-1); /* can not open */
937 if (lockf(lfp,F_TLOCK,0)<0)
939 dlt_log(LOG_CRIT, "can't lock lock file, exiting DLT daemon\n");
940 exit(-1); /* can not lock */
942 /* only first instance continues */
944 sprintf(str,"%d\n",getpid());
945 bytes_written=write(lfp,str,strlen(str)); /* record pid to lockfile */
948 signal(SIGCHLD,SIG_IGN); /* ignore child */
949 signal(SIGTSTP,SIG_IGN); /* ignore tty signals */
950 signal(SIGTTOU,SIG_IGN);
951 signal(SIGTTIN,SIG_IGN);
953 } /* dlt_daemon_daemonize() */
955 int dlt_daemon_process_client_connect(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
962 PRINT_FUNCTION_VERBOSE(verbose);
964 if ((daemon==0) || (daemon_local==0))
966 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_client_connect()\n");
970 /* event from TCP server socket, new connection */
971 cli_size = sizeof(cli);
972 if ((in_sock = accept(daemon_local->sock,&cli, &cli_size)) < 0)
974 dlt_log(LOG_ERR, "accept() failed!\n");
978 /* check if file file descriptor was already used, and make it invalid if it is reused */
979 /* This prevents sending messages to wrong file descriptor */
980 dlt_daemon_applications_invalidate_fd(daemon,in_sock,verbose);
981 dlt_daemon_contexts_invalidate_fd(daemon,in_sock,verbose);
983 //sprintf("str,"Client Connection from %s\n", inet_ntoa(cli.sin_addr));
985 FD_SET(in_sock, &(daemon_local->master)); /* add to master set */
986 if (in_sock > daemon_local->fdmax)
988 /* keep track of the maximum */
989 daemon_local->fdmax = in_sock;
992 daemon_local->client_connections++;
993 if (daemon_local->flags.vflag)
995 sprintf(str, "New connection to client established, #connections: %d\n",daemon_local->client_connections);
996 dlt_log(LOG_INFO, str);
999 if (daemon_local->client_connections==1)
1001 if (daemon_local->flags.vflag)
1003 dlt_log(LOG_INFO, "Send ring-buffer to client\n");
1005 if (dlt_daemon_send_ringbuffer_to_client(daemon, daemon_local, verbose)==-1)
1007 dlt_log(LOG_ERR,"Can't send contents of ringbuffer to clients\n");
1011 /* send new log state to all applications */
1013 dlt_daemon_user_send_all_log_state(daemon,verbose);
1019 int dlt_daemon_process_client_messages(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1021 int bytes_to_be_removed=0;
1023 PRINT_FUNCTION_VERBOSE(verbose);
1025 if ((daemon==0) || (daemon_local==0))
1027 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_client_messages()\n");
1031 if (dlt_receiver_receive_socket(&(daemon_local->receiverSock))<=0)
1033 close(daemon_local->receiverSock.fd);
1034 FD_CLR(daemon_local->receiverSock.fd, &(daemon_local->master));
1036 if (daemon_local->client_connections)
1038 daemon_local->client_connections--;
1041 if(daemon_local->client_connections==0)
1043 /* send new log state to all applications */
1045 dlt_daemon_user_send_all_log_state(daemon,verbose);
1048 if (daemon_local->flags.vflag)
1050 sprintf(str, "Connection to client lost, #connections: %d\n",daemon_local->client_connections);
1051 dlt_log(LOG_INFO, str);
1054 /* check: return 0; */
1057 /* Process all received messages */
1058 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)
1060 /* Check for control message */
1061 if (DLT_MSG_IS_CONTROL_REQUEST(&(daemon_local->msg)))
1063 dlt_daemon_control_process_control(daemon_local->receiverSock.fd, daemon, &(daemon_local->msg), daemon_local->flags.vflag);
1066 bytes_to_be_removed = daemon_local->msg.headersize+daemon_local->msg.datasize-sizeof(DltStorageHeader);
1067 if (daemon_local->msg.found_serialheader)
1069 bytes_to_be_removed += sizeof(dltSerialHeader);
1071 if (daemon_local->msg.resync_offset)
1073 bytes_to_be_removed += daemon_local->msg.resync_offset;
1076 if (dlt_receiver_remove(&(daemon_local->receiverSock),bytes_to_be_removed)==-1)
1078 dlt_log(LOG_ERR,"Can't remove bytes from receiver for sockets\n");
1085 if (dlt_receiver_move_to_begin(&(daemon_local->receiverSock))==-1)
1087 dlt_log(LOG_ERR,"Can't move bytes to beginning of receiver buffer for sockets\n");
1094 int dlt_daemon_process_client_messages_serial(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1096 int bytes_to_be_removed=0;
1098 PRINT_FUNCTION_VERBOSE(verbose);
1100 if ((daemon==0) || (daemon_local==0))
1102 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_client_messages_serial()\n");
1106 if (dlt_receiver_receive_fd(&(daemon_local->receiverSerial))<=0)
1108 dlt_log(LOG_ERR, "dlt_receiver_receive_fd() for messages from serial interface failed!\n");
1112 /* Process all received messages */
1113 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)
1115 /* Check for control message */
1116 if (DLT_MSG_IS_CONTROL_REQUEST(&(daemon_local->msg)))
1118 if (dlt_daemon_control_process_control(daemon_local->receiverSerial.fd, daemon, &(daemon_local->msg), daemon_local->flags.vflag)==-1)
1120 dlt_log(LOG_ERR,"Can't process control messages\n");
1125 bytes_to_be_removed = daemon_local->msg.headersize+daemon_local->msg.datasize-sizeof(DltStorageHeader);
1126 if (daemon_local->msg.found_serialheader)
1128 bytes_to_be_removed += sizeof(dltSerialHeader);
1130 if (daemon_local->msg.resync_offset)
1132 bytes_to_be_removed += daemon_local->msg.resync_offset;
1135 if (dlt_receiver_remove(&(daemon_local->receiverSerial),bytes_to_be_removed)==-1)
1137 dlt_log(LOG_ERR,"Can't remove bytes from receiver for serial connection\n");
1144 if (dlt_receiver_move_to_begin(&(daemon_local->receiverSerial))==-1)
1146 dlt_log(LOG_ERR,"Can't move bytes to beginning of receiver buffer for serial connection\n");
1153 int dlt_daemon_process_user_messages(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1157 DltUserHeader *userheader;
1159 PRINT_FUNCTION_VERBOSE(verbose);
1161 if ((daemon==0) || (daemon_local==0))
1163 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_messages()\n");
1167 /* read data from FIFO */
1168 if (dlt_receiver_receive_fd(&(daemon_local->receiver))<0)
1170 dlt_log(LOG_ERR, "dlt_receiver_receive_fd() for user messages failed!\n");
1174 /* look through buffer as long as data is in there */
1177 if (daemon_local->receiver.bytesRcvd < (int32_t)sizeof(DltUserHeader))
1182 /* resync if necessary */
1186 userheader = (DltUserHeader*) (daemon_local->receiver.buf+offset);
1188 /* Check for user header pattern */
1189 if (dlt_user_check_userheader(userheader))
1197 while ((int32_t)(sizeof(DltUserHeader)+offset)<=daemon_local->receiver.bytesRcvd);
1199 /* Check for user header pattern */
1200 if (dlt_user_check_userheader(userheader)==0)
1205 /* Set new start offset */
1208 daemon_local->receiver.buf+=offset;
1209 daemon_local->receiver.bytesRcvd-=offset;
1212 switch (userheader->message)
1214 case DLT_USER_MESSAGE_OVERFLOW:
1216 if (dlt_daemon_process_user_message_overflow(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1222 case DLT_USER_MESSAGE_REGISTER_CONTEXT:
1224 if (dlt_daemon_process_user_message_register_context(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1230 case DLT_USER_MESSAGE_UNREGISTER_CONTEXT:
1232 if (dlt_daemon_process_user_message_unregister_context(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1238 case DLT_USER_MESSAGE_LOG:
1240 if (dlt_daemon_process_user_message_log(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1246 #ifdef DLT_SHM_ENABLE
1247 case DLT_USER_MESSAGE_LOG_SHM:
1249 if (dlt_daemon_process_user_message_log_shm(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1256 case DLT_USER_MESSAGE_REGISTER_APPLICATION:
1258 if (dlt_daemon_process_user_message_register_application(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1264 case DLT_USER_MESSAGE_UNREGISTER_APPLICATION:
1266 if (dlt_daemon_process_user_message_unregister_application(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1272 case DLT_USER_MESSAGE_APP_LL_TS:
1274 if (dlt_daemon_process_user_message_set_app_ll_ts(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1280 case DLT_USER_MESSAGE_LOG_MODE:
1282 if (dlt_daemon_process_user_message_log_mode(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1290 dlt_log(LOG_ERR,"(Internal) Invalid user message type received!\n");
1292 /* remove user header */
1293 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader))==-1)
1295 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user messages\n");
1299 /* In next invocation of do-while loop, a resync will be triggered if additional data was received */
1309 /* keep not read data in buffer */
1310 if (dlt_receiver_move_to_begin(&(daemon_local->receiver))==-1)
1312 dlt_log(LOG_ERR,"Can't move bytes to beginning of receiver buffer for user messages\n");
1319 int dlt_daemon_process_user_message_overflow(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1323 PRINT_FUNCTION_VERBOSE(verbose);
1325 if ((daemon==0) || (daemon_local==0))
1327 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_overflow()\n");
1331 /* Store in daemon, that a message buffer overflow has occured */
1332 daemon->message_buffer_overflow = DLT_MESSAGE_BUFFER_OVERFLOW;
1334 /* look if TCP connection to client is available */
1337 for (j = 0; j <= daemon_local->fdmax; j++)
1339 /* send to everyone! */
1340 if (FD_ISSET(j, &(daemon_local->master)))
1342 /* except the listener and ourselves */
1343 if ((j != daemon_local->fp) && (j != daemon_local->sock))
1345 dlt_daemon_control_message_buffer_overflow(j, daemon, verbose);
1347 /* Reset overflow state */
1348 daemon->message_buffer_overflow = DLT_MESSAGE_BUFFER_NO_OVERFLOW;
1353 /* message was not sent, so store it in ringbuffer */
1356 dlt_daemon_control_message_buffer_overflow(DLT_DAEMON_STORE_TO_BUFFER, daemon, verbose);
1359 /* keep not read data in buffer */
1360 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader))==-1)
1362 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message overflow\n");
1369 int dlt_daemon_process_user_message_register_application(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1372 DltDaemonApplication *application;
1373 char description[DLT_DAEMON_DESCSIZE];
1374 DltUserControlMsgRegisterApplication *usercontext;
1376 PRINT_FUNCTION_VERBOSE(verbose);
1378 if ((daemon==0) || (daemon_local==0))
1380 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_register_application()\n");
1384 if (daemon_local->receiver.bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterApplication)))
1386 /* Not enough bytes received */
1390 usercontext = (DltUserControlMsgRegisterApplication*) (daemon_local->receiver.buf+sizeof(DltUserHeader));
1392 memset(description,0,sizeof(description));
1394 len=usercontext->description_length;
1395 if ((len>0) && (len<=DLT_DAEMON_DESCSIZE))
1397 /* Read and store application description */
1398 strncpy(description, (daemon_local->receiver.buf+sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterApplication)), len);
1401 application=dlt_daemon_application_add(daemon,usercontext->apid,usercontext->pid,description,verbose);
1403 /* send log state to new application */
1404 dlt_daemon_user_send_log_state(daemon,application,verbose);
1406 /* keep not read data in buffer */
1407 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterApplication)+len)==-1)
1409 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register application\n");
1415 dlt_log(LOG_CRIT,"Can't add application");
1422 int dlt_daemon_process_user_message_register_context(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1425 int8_t loglevel, tracestatus;
1426 DltUserControlMsgRegisterContext *usercontext;
1427 char description[DLT_DAEMON_DESCSIZE];
1428 DltDaemonApplication *application;
1429 DltDaemonContext *context;
1430 DltServiceGetLogInfoRequest *req;
1436 PRINT_FUNCTION_VERBOSE(verbose);
1438 if ((daemon==0) || (daemon_local==0))
1440 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_register_context()\n");
1444 if (daemon_local->receiver.bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)))
1446 /* Not enough bytes received */
1450 usercontext = (DltUserControlMsgRegisterContext*) (daemon_local->receiver.buf+sizeof(DltUserHeader));
1452 memset(description,0,sizeof(description));
1454 len=usercontext->description_length;
1455 if ((len>0) && (len<=DLT_DAEMON_DESCSIZE))
1457 /* Read and store context description */
1458 strncpy(description, (daemon_local->receiver.buf+sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)), len);
1461 application = dlt_daemon_application_find(daemon,usercontext->apid,verbose);
1465 dlt_log(LOG_ERR, "Application not found in dlt_daemon_process_user_message_register_context()\n");
1466 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)+len)==-1)
1468 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register context\n");
1474 /* Pre-set loglevel */
1475 if (usercontext->log_level == DLT_USER_LOG_LEVEL_NOT_SET)
1477 loglevel=DLT_LOG_DEFAULT;
1481 loglevel=usercontext->log_level;
1482 /* Plausibility check */
1483 if ((loglevel<DLT_LOG_DEFAULT) || (loglevel>DLT_LOG_VERBOSE))
1485 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)+len)==-1)
1487 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register context\n");
1493 /* Pre-set tracestatus */
1494 if (usercontext->trace_status == DLT_USER_TRACE_STATUS_NOT_SET)
1496 tracestatus=DLT_TRACE_STATUS_DEFAULT;
1500 tracestatus=usercontext->trace_status;
1502 /* Plausibility check */
1503 if ((tracestatus<DLT_TRACE_STATUS_DEFAULT) || (tracestatus>DLT_TRACE_STATUS_ON))
1505 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)+len)==-1)
1507 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register context\n");
1513 context = dlt_daemon_context_add(daemon,usercontext->apid,usercontext->ctid, loglevel, tracestatus, usercontext->log_level_pos,application->user_handle,description,verbose);
1517 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)+len)==-1)
1519 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register context\n");
1522 dlt_log(LOG_CRIT,"Can't add context");
1525 /* Create automatic get log info response for registered context */
1526 if (daemon_local->flags.rflag)
1528 /* Prepare request for get log info with one application and one context */
1529 if (dlt_message_init(&msg, verbose)==-1)
1531 dlt_log(LOG_ERR,"Can't initialize message");
1535 msg.datasize = sizeof(DltServiceGetLogInfoRequest);
1536 if (msg.databuffer && (msg.databuffersize < msg.datasize))
1538 free(msg.databuffer);
1541 if (msg.databuffer == 0){
1542 msg.databuffer = (uint8_t *) malloc(msg.datasize);
1543 msg.databuffersize = msg.datasize;
1545 if (msg.databuffer==0)
1547 dlt_log(LOG_ERR,"Can't allocate buffer for get log info message\n");
1551 req = (DltServiceGetLogInfoRequest*) msg.databuffer;
1553 req->service_id = DLT_SERVICE_ID_GET_LOG_INFO;
1555 dlt_set_id(req->apid, usercontext->apid);
1556 dlt_set_id(req->ctid, usercontext->ctid);
1557 dlt_set_id(req->com,"remo");
1561 /* Send response to get log info request to DLT clients */
1562 for (j = 0; j <= daemon_local->fdmax; j++)
1564 /* send to everyone! */
1565 if (FD_ISSET(j, &(daemon_local->master)))
1567 /* except the listener and ourselves */
1568 if ((j != daemon_local->fp) && (j != daemon_local->sock))
1570 dlt_daemon_control_get_log_info(j , daemon, &msg, verbose);
1578 /* Store to buffer */
1579 dlt_daemon_control_get_log_info(DLT_DAEMON_STORE_TO_BUFFER , daemon, &msg, verbose);
1582 dlt_message_free(&msg, verbose);
1585 if (context->user_handle >= DLT_FD_MINIMUM)
1587 /* This call also replaces the default values with the values defined for default */
1588 if (dlt_daemon_user_send_log_level(daemon, context, verbose)==-1)
1590 dlt_log(LOG_ERR,"Can't send current log level as response to user message register context\n");
1595 /* keep not read data in buffer */
1596 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)+len)==-1)
1598 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register context\n");
1605 int dlt_daemon_process_user_message_unregister_application(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1607 DltUserControlMsgUnregisterApplication *usercontext;
1608 DltDaemonApplication *application;
1609 DltDaemonContext *context;
1612 PRINT_FUNCTION_VERBOSE(verbose);
1614 if ((daemon==0) || (daemon_local==0))
1616 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_unregister_application()\n");
1620 if (daemon_local->receiver.bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgUnregisterApplication)))
1622 /* Not enough bytes received */
1626 if (daemon->num_applications>0)
1628 usercontext = (DltUserControlMsgUnregisterApplication*) (daemon_local->receiver.buf+sizeof(DltUserHeader));
1630 /* Delete this application and all corresponding contexts for this application from internal table */
1631 application = dlt_daemon_application_find(daemon,usercontext->apid, verbose);
1635 /* Calculate start offset within contexts[] */
1637 for (i=0; i<(application-(daemon->applications)); i++)
1639 offset_base+=daemon->applications[i].num_contexts;
1642 for (i=application->num_contexts-1; i>=0; i--)
1644 context = &(daemon->contexts[offset_base+i]);
1647 /* Delete context */
1648 if (dlt_daemon_context_del(daemon, context, verbose)==-1)
1650 dlt_log(LOG_ERR,"Can't delete context for user message unregister application\n");
1656 /* Delete this application entry from internal table*/
1657 if (dlt_daemon_application_del(daemon, application, verbose)==-1)
1659 dlt_log(LOG_ERR,"Can't delete application for user message unregister application\n");
1665 /* keep not read data in buffer */
1666 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgUnregisterApplication))==-1)
1668 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message unregister application\n");
1675 int dlt_daemon_process_user_message_unregister_context(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1677 DltUserControlMsgUnregisterContext *usercontext;
1678 DltDaemonContext *context;
1680 PRINT_FUNCTION_VERBOSE(verbose);
1682 if ((daemon==0) || (daemon_local==0))
1684 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_unregister_context()\n");
1688 if (daemon_local->receiver.bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgUnregisterContext)))
1690 /* Not enough bytes received */
1694 usercontext = (DltUserControlMsgUnregisterContext*) (daemon_local->receiver.buf+sizeof(DltUserHeader));
1695 context = dlt_daemon_context_find(daemon,usercontext->apid, usercontext->ctid, verbose);
1699 /* Delete this connection entry from internal table*/
1700 if (dlt_daemon_context_del(daemon, context, verbose)==-1)
1702 dlt_log(LOG_ERR,"Can't delete context for user message unregister context\n");
1707 /* keep not read data in buffer */
1708 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgUnregisterContext))==-1)
1710 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message unregister context\n");
1717 int dlt_daemon_process_user_message_log(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1719 int bytes_to_be_removed;
1720 int j,sent,third_value;
1723 static char text[DLT_DAEMON_TEXTSIZE];
1725 PRINT_FUNCTION_VERBOSE(verbose);
1727 if ((daemon==0) || (daemon_local==0))
1729 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_log()\n");
1733 if (dlt_message_read(&(daemon_local->msg),(unsigned char*)daemon_local->receiver.buf+sizeof(DltUserHeader),daemon_local->receiver.bytesRcvd-sizeof(DltUserHeader),0,verbose)==0)
1735 /* set overwrite ecu id */
1736 if (daemon_local->flags.evalue!=0)
1738 /* Set header extra parameters */
1739 dlt_set_id(daemon_local->msg.headerextra.ecu, daemon->ecuid );
1740 //msg.headerextra.seid = 0;
1741 if (dlt_message_set_extraparameters(&(daemon_local->msg),0)==-1)
1743 dlt_log(LOG_ERR,"Can't set message extra parameters in process user message log\n");
1747 /* Correct value of timestamp, this was changed by dlt_message_set_extraparameters() */
1748 daemon_local->msg.headerextra.tmsp = DLT_BETOH_32(daemon_local->msg.headerextra.tmsp);
1751 /* prepare storage header */
1752 if (DLT_IS_HTYP_WEID(daemon_local->msg.standardheader->htyp))
1754 if (dlt_set_storageheader(daemon_local->msg.storageheader,daemon_local->msg.headerextra.ecu)==-1)
1756 dlt_log(LOG_ERR,"Can't set storage header in process user message log\n");
1762 if (dlt_set_storageheader(daemon_local->msg.storageheader,daemon->ecuid)==-1)
1764 dlt_log(LOG_ERR,"Can't set storage header in process user message log\n");
1770 /* if no filter set or filter is matching display message */
1771 if (daemon_local->flags.xflag)
1773 if (dlt_message_print_hex(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1)
1775 dlt_log(LOG_ERR,"dlt_message_print_hex() failed!\n");
1778 else if (daemon_local->flags.aflag)
1780 if (dlt_message_print_ascii(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1)
1782 dlt_log(LOG_ERR,"dlt_message_print_ascii() failed!\n");
1785 else if (daemon_local->flags.sflag)
1787 if (dlt_message_print_header(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1)
1789 dlt_log(LOG_ERR,"dlt_message_print_header() failed!\n");
1791 /* print message header only */
1796 /* write message to offline trace */
1797 if(((daemon->mode == DLT_USER_MODE_INTERNAL) || (daemon->mode == DLT_USER_MODE_BOTH)) && daemon_local->flags.offlineTraceDirectory[0])
1799 dlt_offline_trace_write(&(daemon_local->offlineTrace),daemon_local->msg.headerbuffer,daemon_local->msg.headersize,
1800 daemon_local->msg.databuffer,daemon_local->msg.datasize,0,0);
1804 /* look if TCP connection to client is available */
1805 for (j = 0;((daemon->mode == DLT_USER_MODE_EXTERNAL) || (daemon->mode == DLT_USER_MODE_BOTH)) && (j <= daemon_local->fdmax); j++)
1807 /* send to everyone! */
1808 if (FD_ISSET(j, &(daemon_local->master)))
1810 /* except the listener and ourselves */
1811 if (daemon_local->flags.yvalue[0])
1813 third_value = daemon_local->fdserial;
1817 third_value = daemon_local->sock;
1820 if ((j != daemon_local->fp) && (j != daemon_local->sock) && (j != third_value))
1822 DLT_DAEMON_SEM_LOCK();
1824 if (daemon_local->flags.lflag)
1826 send(j,dltSerialHeader,sizeof(dltSerialHeader),0);
1829 send(j,daemon_local->msg.headerbuffer+sizeof(DltStorageHeader),daemon_local->msg.headersize-sizeof(DltStorageHeader),0);
1830 send(j,daemon_local->msg.databuffer,daemon_local->msg.datasize,0);
1832 DLT_DAEMON_SEM_FREE();
1836 else if ((j == daemon_local->fdserial) && (daemon_local->flags.yvalue!=0))
1838 DLT_DAEMON_SEM_LOCK();
1840 if (daemon_local->flags.lflag)
1842 ret=write(j,dltSerialHeader,sizeof(dltSerialHeader));
1845 ret=write(j,daemon_local->msg.headerbuffer+sizeof(DltStorageHeader),daemon_local->msg.headersize-sizeof(DltStorageHeader));
1846 ret=write(j,daemon_local->msg.databuffer,daemon_local->msg.datasize);
1848 DLT_DAEMON_SEM_FREE();
1855 /* Message was not sent to client, so store it in client ringbuffer */
1858 if (dlt_buffer_push3(&(daemon->client_ringbuffer),
1859 daemon_local->msg.headerbuffer+sizeof(DltStorageHeader),daemon_local->msg.headersize-sizeof(DltStorageHeader),
1860 daemon_local->msg.databuffer,daemon_local->msg.datasize,
1864 dlt_log(LOG_ERR,"Storage of message in history buffer failed! Message discarded.\n");
1869 /* keep not read data in buffer */
1870 bytes_to_be_removed = daemon_local->msg.headersize+daemon_local->msg.datasize-sizeof(DltStorageHeader)+sizeof(DltUserHeader);
1871 if (daemon_local->msg.found_serialheader)
1873 bytes_to_be_removed += sizeof(dltSerialHeader);
1876 if (dlt_receiver_remove(&(daemon_local->receiver),bytes_to_be_removed)==-1)
1878 dlt_log(LOG_ERR,"Can't remove bytes from receiver\n");
1884 dlt_log(LOG_ERR,"Can't read messages from receiver\n");
1891 #ifdef DLT_SHM_ENABLE
1892 int dlt_daemon_process_user_message_log_shm(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1894 int bytes_to_be_removed=0;
1895 int j,sent,third_value;
1897 uint8_t rcv_buffer[10000];
1899 DltUserHeader *userheader;
1901 static char text[DLT_DAEMON_TEXTSIZE];
1903 PRINT_FUNCTION_VERBOSE(verbose);
1905 if ((daemon==0) || (daemon_local==0))
1907 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_log()\n");
1911 userheader = (DltUserHeader*) (daemon_local->receiver.buf);
1913 //dlt_shm_status(&(daemon_local->dlt_shm));
1916 /* log message in SHM */
1917 if((size = dlt_shm_copy(&(daemon_local->dlt_shm),rcv_buffer,10000)) <= 0)
1919 if (dlt_message_read(&(daemon_local->msg),rcv_buffer,size,0,verbose)!=0) {
1921 dlt_log(LOG_ERR,"Can't read messages from shm\n");
1924 bytes_to_be_removed = daemon_local->msg.headersize+daemon_local->msg.datasize-sizeof(DltStorageHeader)+sizeof(DltUserHeader);
1925 if (daemon_local->msg.found_serialheader)
1927 bytes_to_be_removed += sizeof(dltSerialHeader);
1930 /* set overwrite ecu id */
1931 if (daemon_local->flags.evalue[0])
1933 /* Set header extra parameters */
1934 dlt_set_id(daemon_local->msg.headerextra.ecu, daemon->ecuid );
1935 //msg.headerextra.seid = 0;
1936 if (dlt_message_set_extraparameters(&(daemon_local->msg),0)==-1)
1938 dlt_log(LOG_ERR,"Can't set message extra parameters in process user message log\n");
1939 dlt_shm_remove(&(daemon_local->dlt_shm));
1943 /* Correct value of timestamp, this was changed by dlt_message_set_extraparameters() */
1944 daemon_local->msg.headerextra.tmsp = DLT_BETOH_32(daemon_local->msg.headerextra.tmsp);
1947 /* prepare storage header */
1948 if (DLT_IS_HTYP_WEID(daemon_local->msg.standardheader->htyp))
1950 if (dlt_set_storageheader(daemon_local->msg.storageheader,daemon_local->msg.headerextra.ecu)==-1)
1952 dlt_log(LOG_ERR,"Can't set storage header in process user message log\n");
1953 dlt_shm_remove(&(daemon_local->dlt_shm));
1959 if (dlt_set_storageheader(daemon_local->msg.storageheader,daemon->ecuid)==-1)
1961 dlt_log(LOG_ERR,"Can't set storage header in process user message log\n");
1962 dlt_shm_remove(&(daemon_local->dlt_shm));
1967 /* display message */
1968 if (daemon_local->flags.xflag)
1970 if (dlt_message_print_hex(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1)
1972 dlt_log(LOG_ERR,"dlt_message_print_hex() failed!\n");
1975 else if (daemon_local->flags.aflag)
1977 if (dlt_message_print_ascii(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1)
1979 dlt_log(LOG_ERR,"dlt_message_print_ascii() failed!\n");
1982 else if (daemon_local->flags.sflag)
1984 if (dlt_message_print_header(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1)
1986 dlt_log(LOG_ERR,"dlt_message_print_header() failed!\n");
1988 /* print message header only */
1993 /* write message to offline trace */
1994 if(((daemon->mode == DLT_USER_MODE_INTERNAL) || (daemon->mode == DLT_USER_MODE_BOTH)) && daemon_local->flags.offlineTraceDirectory[0])
1996 dlt_offline_trace_write(&(daemon_local->offlineTrace),daemon_local->msg.headerbuffer,daemon_local->msg.headersize,
1997 daemon_local->msg.databuffer,daemon_local->msg.datasize,0,0);
2001 /* look if TCP connection to client is available */
2002 for (j = 0;((daemon->mode == DLT_USER_MODE_EXTERNAL) || (daemon->mode == DLT_USER_MODE_BOTH)) && (j <= daemon_local->fdmax); j++)
2004 /* send to everyone! */
2005 if (FD_ISSET(j, &(daemon_local->master)))
2007 /* except the listener and ourselves */
2008 if (daemon_local->flags.yvalue[0])
2010 third_value = daemon_local->fdserial;
2014 third_value = daemon_local->sock;
2017 if ((j != daemon_local->fp) && (j != daemon_local->sock) && (j != third_value))
2019 DLT_DAEMON_SEM_LOCK();
2021 if (daemon_local->flags.lflag)
2023 send(j,dltSerialHeader,sizeof(dltSerialHeader),0);
2026 send(j,daemon_local->msg.headerbuffer+sizeof(DltStorageHeader),daemon_local->msg.headersize-sizeof(DltStorageHeader),0);
2027 send(j,daemon_local->msg.databuffer,daemon_local->msg.datasize,0);
2029 DLT_DAEMON_SEM_FREE();
2033 else if ((j == daemon_local->fdserial) && (daemon_local->flags.yvalue[0]))
2035 DLT_DAEMON_SEM_LOCK();
2037 if (daemon_local->flags.lflag)
2039 ret=write(j,dltSerialHeader,sizeof(dltSerialHeader));
2042 ret=write(j,daemon_local->msg.headerbuffer+sizeof(DltStorageHeader),daemon_local->msg.headersize-sizeof(DltStorageHeader));
2043 ret=write(j,daemon_local->msg.databuffer,daemon_local->msg.datasize);
2045 DLT_DAEMON_SEM_FREE();
2052 /* Message was not sent to client, so store it in client ringbuffer */
2053 if (sent==1 || (daemon->mode == DLT_USER_MODE_OFF))
2055 if(userheader->message == DLT_USER_MESSAGE_LOG_SHM) {
2056 /* dlt message was sent, remove from buffer if log message from shm */
2057 dlt_shm_remove(&(daemon_local->dlt_shm));
2062 /* dlt message was not sent, keep in buffer */
2068 /* keep not read data in buffer */
2069 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader))==-1)
2071 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message overflow\n");
2079 int dlt_daemon_process_user_message_set_app_ll_ts(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
2081 DltUserControlMsgAppLogLevelTraceStatus *usercontext;
2082 DltDaemonApplication *application;
2083 DltDaemonContext *context;
2085 int8_t old_log_level, old_trace_status;
2087 PRINT_FUNCTION_VERBOSE(verbose);
2089 if ((daemon==0) || (daemon_local==0))
2091 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_set_app_ll_ts()\n");
2095 if (daemon_local->receiver.bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgAppLogLevelTraceStatus )))
2097 /* Not enough bytes receeived */
2101 if (daemon->num_applications>0)
2103 usercontext = (DltUserControlMsgAppLogLevelTraceStatus*) (daemon_local->receiver.buf+sizeof(DltUserHeader));
2105 /* Get all contexts with application id matching the received application id */
2106 application = dlt_daemon_application_find(daemon, usercontext->apid, verbose);
2109 /* Calculate start offset within contexts[] */
2111 for (i=0; i<(application-(daemon->applications)); i++)
2113 offset_base+=daemon->applications[i].num_contexts;
2116 for (i=0; i < application->num_contexts; i++)
2118 context = &(daemon->contexts[offset_base+i]);
2121 old_log_level = context->log_level;
2122 context->log_level = usercontext->log_level; /* No endianess conversion necessary*/
2124 old_trace_status = context->trace_status;
2125 context->trace_status = usercontext->trace_status; /* No endianess conversion necessary */
2127 /* The folowing function sends also the trace status */
2128 if (context->user_handle >= DLT_FD_MINIMUM && dlt_daemon_user_send_log_level(daemon, context, verbose)!=0)
2130 context->log_level = old_log_level;
2131 context->trace_status = old_trace_status;
2138 /* keep not read data in buffer */
2139 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgAppLogLevelTraceStatus))==-1)
2141 dlt_log(LOG_ERR,"Can't remove bytes from receiver\n");
2148 int dlt_daemon_process_user_message_log_mode(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
2150 DltUserControlMsgLogMode *logmode;
2152 PRINT_FUNCTION_VERBOSE(verbose);
2154 if ((daemon==0) || (daemon_local==0))
2156 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_log_mode()\n");
2160 if (daemon_local->receiver.bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgUnregisterContext)))
2162 /* Not enough bytes received */
2166 logmode = (DltUserControlMsgLogMode*) (daemon_local->receiver.buf+sizeof(DltUserHeader));
2168 /* set the new log mode */
2169 daemon->mode = logmode->log_mode;
2171 /* write configuration persistantly */
2172 dlt_daemon_configuration_save(daemon, daemon->runtime_configuration, verbose);
2174 /* keep not read data in buffer */
2175 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogMode))==-1)
2177 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message log mode\n");
2184 int dlt_daemon_send_ringbuffer_to_client(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
2186 static uint8_t data[DLT_DAEMON_RCVBUFSIZE];
2191 PRINT_FUNCTION_VERBOSE(verbose);
2193 if ((daemon==0) || (daemon_local==0))
2195 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_send_ringbuffer_to_client()\n");
2199 /* Attention: If the message can't be send at this time, it will be silently discarded. */
2200 while ((length = dlt_buffer_pull(&(daemon->client_ringbuffer), data, sizeof(data) )) > 0)
2202 /* look if TCP connection to client is available */
2203 for (j = 0; j <= daemon_local->fdmax; j++)
2205 /* send to everyone! */
2206 if (FD_ISSET(j, &(daemon_local->master)))
2208 /* except the listener and ourselves */
2209 if (daemon_local->flags.yvalue[0])
2211 third_value = daemon_local->fdserial;
2215 third_value = daemon_local->sock;
2218 if ((j != daemon_local->fp) && (j != daemon_local->sock) && (j != third_value))
2220 DLT_DAEMON_SEM_LOCK();
2222 if (daemon_local->flags.lflag)
2224 send(j,dltSerialHeader,sizeof(dltSerialHeader),0);
2226 send(j,data,length,0);
2228 DLT_DAEMON_SEM_FREE();
2231 else if ((j == daemon_local->fdserial) && (daemon_local->flags.yvalue[0]))
2233 DLT_DAEMON_SEM_LOCK();
2235 if (daemon_local->flags.lflag)
2237 ret=write(j,dltSerialHeader,sizeof(dltSerialHeader));
2239 ret=write(j,data,length);
2241 DLT_DAEMON_SEM_LOCK();
2245 length = sizeof(data);
2251 void dlt_daemon_timingpacket_thread(void *ptr)
2253 DltDaemonPeriodicData info;
2256 DltDaemonTimingPacketThreadData *data;
2258 DltDaemonLocal *daemon_local;
2262 dlt_log(LOG_ERR, "No data pointer passed to timingpacket thread\n");
2266 data = (DltDaemonTimingPacketThreadData*)ptr;
2267 daemon = data->daemon;
2268 daemon_local = data->daemon_local;
2270 if ((daemon==0) || (daemon_local==0))
2272 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_timingpacket_thread()");
2276 if (dlt_daemon_make_periodic (1000000, &info, daemon_local->flags.vflag)<0)
2278 dlt_log(LOG_CRIT,"Can't initialize thread timer!\n");
2284 /* If enabled, send timing packets to all clients */
2285 if (daemon->timingpackets)
2287 for (j = 0; j <= daemon_local->fdmax; j++)
2289 /* send to everyone! */
2290 if (FD_ISSET(j, &(daemon_local->master)))
2292 /* except the listener and ourselves */
2293 if ((j != daemon_local->fp) && (j != daemon_local->sock))
2295 dlt_daemon_control_message_time(j, daemon, daemon_local->flags.vflag);
2300 /* Wait for next period */
2301 dlt_daemon_wait_period (&info, daemon_local->flags.vflag);
2305 int dlt_daemon_make_periodic (unsigned int period, DltDaemonPeriodicData *info, int verbose)
2311 struct itimerspec itval;
2313 PRINT_FUNCTION_VERBOSE(verbose);
2317 dlt_log(LOG_ERR,"No data pointer passed!\n");
2321 /* Create the timer */
2322 fd = timerfd_create (CLOCK_MONOTONIC, 0);
2324 info->wakeups_missed = 0;
2325 info->timer_fd = fd;
2329 dlt_log(LOG_ERR,"Can't create timer filedescriptor");
2333 /* Make the timer periodic */
2334 sec = period/1000000;
2335 ns = (period - (sec * 1000000)) * 1000;
2336 itval.it_interval.tv_sec = sec;
2337 itval.it_interval.tv_nsec = ns;
2338 itval.it_value.tv_sec = sec;
2339 itval.it_value.tv_nsec = ns;
2341 ret = timerfd_settime (fd, 0, &itval, NULL);
2346 void dlt_daemon_wait_period (DltDaemonPeriodicData *info, int verbose)
2348 unsigned long long missed;
2351 PRINT_FUNCTION_VERBOSE(verbose);
2353 ret = read (info->timer_fd, &missed, sizeof (missed));
2357 info->wakeups_missed += (missed - 1);