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"
88 #include "dlt_daemon_common_cfg.h"
90 #include "dlt_daemon_socket.h"
91 #include "dlt_daemon_serial.h"
93 #include "dlt_daemon_client.h"
95 #if defined(DLT_SYSTEMD_WATCHDOG_ENABLE) || defined(DLT_SYSTEMD_ENABLE)
96 #include "sd-daemon.h"
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];
109 * Print usage information of tool.
113 char version[DLT_DAEMON_TEXTBUFSIZE];
114 dlt_get_version(version);
116 //printf("DLT logging daemon %s %s\n", _DLT_PACKAGE_VERSION, _DLT_PACKAGE_VERSION_STATE);
117 //printf("Compile options: %s %s %s %s",_DLT_SYSTEMD_ENABLE, _DLT_SYSTEMD_WATCHDOG_ENABLE, _DLT_TEST_ENABLE, _DLT_SHM_ENABLE);
118 printf("%s", version);
119 printf("Usage: dlt-daemon [options]\n");
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,NAME_MAX);
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)
199 int value_length = 1024;
200 char line[value_length-1];
201 char token[value_length];
202 char value[value_length];
204 const char *filename;
206 /* set default values for configuration */
207 daemon_local->flags.sharedMemorySize = DLT_SHM_SIZE;
208 daemon_local->flags.sendMessageTime = 0;
209 daemon_local->flags.offlineTraceDirectory[0] = 0;
210 daemon_local->flags.offlineTraceFileSize = 1000000;
211 daemon_local->flags.offlineTraceMaxSize = 0;
212 daemon_local->flags.loggingMode = 0;
213 daemon_local->flags.loggingLevel = 6;
214 strncpy(daemon_local->flags.loggingFilename, DLT_USER_DIR "/dlt.log",sizeof(daemon_local->flags.loggingFilename));
215 daemon_local->timeoutOnSend = 4;
216 daemon_local->flags.sendECUSoftwareVersion = 0;
217 memset(daemon_local->flags.pathToECUSoftwareVersion, 0, sizeof(daemon_local->flags.pathToECUSoftwareVersion));
218 daemon_local->flags.sendTimezone = 0;
220 /* open configuration file */
221 if(daemon_local->flags.cvalue[0])
222 filename = daemon_local->flags.cvalue;
224 filename = "/etc/dlt.conf";
225 //printf("Load configuration from file: %s\n",filename);
226 pFile = fopen (filename,"r");
232 /* fetch line from configuration file */
233 if ( fgets (line , value_length - 1 , pFile) != NULL )
235 pch = strtok (line," =\r\n");
241 if(strcmp(pch,"#")==0)
246 strncpy(token,pch,sizeof(token) - 1);
250 strncpy(value,pch,sizeof(value) - 1);
254 pch = strtok (NULL, " =\r\n");
257 if(token[0] && value[0])
259 /* parse arguments here */
260 if(strcmp(token,"Verbose")==0)
262 daemon_local->flags.vflag = atoi(value);
263 //printf("Option: %s=%s\n",token,value);
265 else if(strcmp(token,"PrintASCII")==0)
267 daemon_local->flags.aflag = atoi(value);
268 //printf("Option: %s=%s\n",token,value);
270 else if(strcmp(token,"PrintHex")==0)
272 daemon_local->flags.xflag = atoi(value);
273 //printf("Option: %s=%s\n",token,value);
275 else if(strcmp(token,"PrintHeadersOnly")==0)
277 daemon_local->flags.sflag = atoi(value);
278 //printf("Option: %s=%s\n",token,value);
280 else if(strcmp(token,"SendSerialHeader")==0)
282 daemon_local->flags.lflag = atoi(value);
283 //printf("Option: %s=%s\n",token,value);
285 else if(strcmp(token,"SendContextRegistration")==0)
287 daemon_local->flags.rflag = atoi(value);
288 //printf("Option: %s=%s\n",token,value);
290 else if(strcmp(token,"SendMessageTime")==0)
292 daemon_local->flags.sendMessageTime = atoi(value);
293 //printf("Option: %s=%s\n",token,value);
295 else if(strcmp(token,"RS232SyncSerialHeader")==0)
297 daemon_local->flags.mflag = atoi(value);
298 //printf("Option: %s=%s\n",token,value);
300 else if(strcmp(token,"TCPSyncSerialHeader")==0)
302 daemon_local->flags.nflag = atoi(value);
303 //printf("Option: %s=%s\n",token,value);
305 else if(strcmp(token,"RS232DeviceName")==0)
307 strncpy(daemon_local->flags.yvalue,value,NAME_MAX);
308 //printf("Option: %s=%s\n",token,value);
310 else if(strcmp(token,"RS232Baudrate")==0)
312 strncpy(daemon_local->flags.bvalue,value,NAME_MAX);
313 //printf("Option: %s=%s\n",token,value);
315 else if(strcmp(token,"ECUId")==0)
317 strncpy(daemon_local->flags.evalue,value,NAME_MAX);
318 //printf("Option: %s=%s\n",token,value);
320 else if(strcmp(token,"PersistanceStoragePath")==0)
322 strncpy(daemon_local->flags.ivalue,value,NAME_MAX);
323 //printf("Option: %s=%s\n",token,value);
325 else if(strcmp(token,"LoggingMode")==0)
327 daemon_local->flags.loggingMode = atoi(value);
328 //printf("Option: %s=%s\n",token,value);
330 else if(strcmp(token,"LoggingLevel")==0)
332 daemon_local->flags.loggingLevel = atoi(value);
333 //printf("Option: %s=%s\n",token,value);
335 else if(strcmp(token,"LoggingFilename")==0)
337 strncpy(daemon_local->flags.loggingFilename,value,sizeof(daemon_local->flags.loggingFilename) - 1);
338 //printf("Option: %s=%s\n",token,value);
340 else if(strcmp(token,"TimeOutOnSend")==0)
342 daemon_local->timeoutOnSend = atoi(value);
343 //printf("Option: %s=%s\n",token,value);
345 else if(strcmp(token,"SharedMemorySize")==0)
347 daemon_local->flags.sharedMemorySize = atoi(value);
348 //printf("Option: %s=%s\n",token,value);
350 else if(strcmp(token,"OfflineTraceDirectory")==0)
352 strncpy(daemon_local->flags.offlineTraceDirectory,value,sizeof(daemon_local->flags.offlineTraceDirectory) - 1);
353 //printf("Option: %s=%s\n",token,value);
355 else if(strcmp(token,"OfflineTraceFileSize")==0)
357 daemon_local->flags.offlineTraceFileSize = atoi(value);
358 //printf("Option: %s=%s\n",token,value);
360 else if(strcmp(token,"OfflineTraceMaxSize")==0)
362 daemon_local->flags.offlineTraceMaxSize = atoi(value);
363 //printf("Option: %s=%s\n",token,value);
365 else if(strcmp(token,"SendECUSoftwareVersion")==0)
367 daemon_local->flags.sendECUSoftwareVersion = atoi(value);
368 //printf("Option: %s=%s\n",token,value);
370 else if(strcmp(token,"PathToECUSoftwareVersion")==0)
372 strncpy(daemon_local->flags.pathToECUSoftwareVersion,value,sizeof(daemon_local->flags.pathToECUSoftwareVersion) - 1);
373 //printf("Option: %s=%s\n",token,value);
375 else if(strcmp(token,"SendTimezone")==0)
377 daemon_local->flags.sendTimezone = atoi(value);
378 //printf("Option: %s=%s\n",token,value);
382 fprintf(stderr, "Unknown option: %s=%s\n",token,value);
395 fprintf(stderr, "Cannot open configuration file: %s\n",filename);
402 * Main function of tool.
404 int main(int argc, char* argv[])
406 char version[DLT_DAEMON_TEXTBUFSIZE];
407 DltDaemonLocal daemon_local;
411 /* Command line option handling */
412 if ((back = option_handling(&daemon_local,argc,argv))<0)
415 fprintf (stderr, "option_handling() failed!\n");
420 /* Configuration file option handling */
421 if ((back = option_file_parser(&daemon_local))<0)
424 fprintf (stderr, "option_file_parser() failed!\n");
429 /* Initialize internal logging facility */
430 dlt_log_set_filename(daemon_local.flags.loggingFilename);
431 dlt_log_set_level(daemon_local.flags.loggingLevel);
432 dlt_log_init(daemon_local.flags.loggingMode);
434 /* Print version information */
435 dlt_get_version(version);
437 sprintf(str,"Starting DLT Daemon; %s\n", version );
438 dlt_log(LOG_NOTICE, str);
440 PRINT_FUNCTION_VERBOSE(daemon_local.flags.vflag);
442 /* --- Daemon init phase 1 begin --- */
443 if (dlt_daemon_local_init_p1(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
445 dlt_log(LOG_CRIT,"Initialization of phase 1 failed!\n");
448 /* --- Daemon init phase 1 end --- */
450 /* --- Daemon connection init begin */
451 if (dlt_daemon_local_connection_init(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
453 dlt_log(LOG_CRIT,"Initialization of local connections failed!\n");
456 /* --- Daemon connection init end */
458 /* --- Daemon init phase 2 begin --- */
459 if (dlt_daemon_local_init_p2(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
461 dlt_log(LOG_CRIT,"Initialization of phase 2 failed!\n");
464 /* --- Daemon init phase 2 end --- */
466 // create fd for watchdog
467 #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE
469 char* watchdogUSec = getenv("WATCHDOG_USEC");
470 int watchdogTimeoutSeconds = 0;
472 dlt_log(LOG_DEBUG, "Systemd watchdog initialization\n");
475 watchdogTimeoutSeconds = atoi(watchdogUSec)/2000000;
477 create_timer_fd(&daemon_local, watchdogTimeoutSeconds, watchdogTimeoutSeconds, &daemon_local.timer_wd, "Systemd watchdog");
481 // create fd for timer timing packets
482 create_timer_fd(&daemon_local, 1, 1, &daemon_local.timer_one_s, "Timing packet");
484 // create fd for timer ecu version
485 if(daemon_local.flags.sendECUSoftwareVersion > 0 || daemon_local.flags.sendTimezone > 0)
487 //dlt_daemon_init_ecuversion(&daemon_local);
488 create_timer_fd(&daemon_local, 60, 60, &daemon_local.timer_sixty_s, "ECU version");
491 if(daemon_local.flags.yvalue[0])
492 dlt_daemon_change_state(&daemon,DLT_DAEMON_STATE_SEND_DIRECT);
494 dlt_daemon_change_state(&daemon,DLT_DAEMON_STATE_BUFFER);
499 /* wait for events from all FIFO and sockets */
500 daemon_local.read_fds = daemon_local.master;
501 if (select(daemon_local.fdmax+1, &(daemon_local.read_fds), NULL, NULL, NULL) == -1)
503 dlt_log(LOG_CRIT, "select() failed!\n");
507 /* run through the existing FIFO and sockets to check for events */
508 for (i = 0; i <= daemon_local.fdmax; i++)
510 if (FD_ISSET(i, &(daemon_local.read_fds)))
512 if (i == daemon_local.sock && ((daemon.mode == DLT_USER_MODE_EXTERNAL) || (daemon.mode == DLT_USER_MODE_BOTH)))
514 /* event from TCP server socket, new connection */
515 if (dlt_daemon_process_client_connect(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
517 dlt_log(LOG_CRIT,"Connect to dlt client failed!\n");
521 else if (i == daemon_local.fp)
523 /* event from the FIFO happened */
524 if (dlt_daemon_process_user_messages(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
526 dlt_log(LOG_CRIT,"Processing of messages from user connection failed!\n");
530 else if ((i == daemon_local.fdserial) && (daemon_local.flags.yvalue[0]))
532 /* event from serial connection to client received */
533 if (dlt_daemon_process_client_messages_serial(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
535 dlt_log(LOG_CRIT,"Processing of messages from serial connection failed!\n");
539 #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE
540 else if (i == daemon_local.timer_wd)
543 ssize_t res = read(daemon_local.timer_wd, &expir, sizeof(expir));
545 sprintf(str,"Failed to read timer_wd; %s\n", strerror(errno) );
546 dlt_log(LOG_WARNING, str);
547 // Activity received on timer_wd, but unable to read the fd:
548 // let's go on sending notification
551 dlt_log(LOG_DEBUG, "Timer watchdog\n");
553 if(sd_notify(0, "WATCHDOG=1") < 0)
555 dlt_log(LOG_CRIT, "Could not reset systemd watchdog\n");
559 else if (i == daemon_local.timer_one_s)
562 ssize_t res = read(daemon_local.timer_one_s, &expir, sizeof(expir));
564 sprintf(str,"Failed to read timer_timingpacket; %s\n", strerror(errno) );
565 dlt_log(LOG_WARNING, str);
566 // Activity received on timer_wd, but unable to read the fd:
567 // let's go on sending notification
569 if(daemon.state == DLT_DAEMON_STATE_SEND_BUFFER || daemon.state == DLT_DAEMON_STATE_BUFFER_FULL)
571 if (dlt_daemon_send_ringbuffer_to_client(&daemon, &daemon_local, daemon_local.flags.vflag))
573 dlt_log(LOG_DEBUG,"Can't send contents of ringbuffer to clients\n");
576 if (daemon.timingpackets && daemon.state == DLT_DAEMON_STATE_SEND_DIRECT)
578 dlt_daemon_control_message_time(DLT_DAEMON_SEND_TO_ALL, &daemon, &daemon_local, daemon_local.flags.vflag);
580 dlt_log(LOG_DEBUG, "Timer timingpacket\n");
584 else if (i == daemon_local.timer_sixty_s)
587 ssize_t res = read(daemon_local.timer_sixty_s, &expir, sizeof(expir));
589 sprintf(str,"Failed to read timer_ecuversion; %s\n", strerror(errno) );
590 dlt_log(LOG_WARNING, str);
591 // Activity received on timer_wd, but unable to read the fd:
592 // let's go on sending notification
594 if(daemon_local.flags.sendECUSoftwareVersion > 0)
595 dlt_daemon_control_get_software_version(DLT_DAEMON_SEND_TO_ALL, &daemon,&daemon_local, daemon_local.flags.vflag);
597 if(daemon_local.flags.sendTimezone > 0)
599 dlt_daemon_control_message_timezone(DLT_DAEMON_SEND_TO_ALL,&daemon,&daemon_local,daemon_local.flags.vflag);
601 dlt_log(LOG_DEBUG, "Timer ecuversion\n");
606 /* event from tcp connection to client received */
607 daemon_local.receiverSock.fd = i;
608 if (dlt_daemon_process_client_messages(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
610 dlt_log(LOG_CRIT,"Processing of messages from client connection failed!\n");
618 dlt_daemon_local_cleanup(&daemon, &daemon_local, daemon_local.flags.vflag);
620 dlt_log(LOG_NOTICE, "Leaving DLT daemon\n");
626 int dlt_daemon_local_init_p1(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
628 #if defined(DLT_SYSTEMD_WATCHDOG_ENABLE) || defined(DLT_SYSTEMD_ENABLE)
633 PRINT_FUNCTION_VERBOSE(verbose);
635 if ((daemon==0) || (daemon_local==0))
637 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_local_init_p1()\n");
641 #if defined(DLT_SYSTEMD_WATCHDOG_ENABLE) || defined(DLT_SYSTEMD_ENABLE)
645 dlt_log(LOG_CRIT, "system not booted with systemd!\n");
650 dlt_log(LOG_CRIT, "sd_booted failed!\n");
655 dlt_log(LOG_INFO, "system booted with systemd\n");
661 /* Check for daemon mode */
662 if (daemon_local->flags.dflag)
664 dlt_daemon_daemonize(daemon_local->flags.vflag);
667 /* initialise structure to use DLT file */
668 if (dlt_file_init(&(daemon_local->file),daemon_local->flags.vflag)==-1)
670 dlt_log(LOG_ERR,"Could not initialize file structure\n");
671 /* Return value ignored, dlt daemon will exit */
672 dlt_file_free(&(daemon_local->file),daemon_local->flags.vflag);
676 signal(SIGPIPE,SIG_IGN);
678 signal(SIGTERM, dlt_daemon_signal_handler); /* software termination signal from kill */
679 signal(SIGHUP, dlt_daemon_signal_handler); /* hangup signal */
680 signal(SIGQUIT, dlt_daemon_signal_handler);
681 signal(SIGINT, dlt_daemon_signal_handler);
686 int dlt_daemon_local_init_p2(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
688 PRINT_FUNCTION_VERBOSE(verbose);
690 if ((daemon==0) || (daemon_local==0))
692 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_local_init_p2()\n");
697 if (dlt_daemon_init(daemon,daemon_local->flags.ivalue,daemon_local->flags.vflag)==-1)
699 dlt_log(LOG_ERR,"Could not initialize daemon data\n");
703 /* init offline trace */
704 if(((daemon->mode == DLT_USER_MODE_INTERNAL) || (daemon->mode == DLT_USER_MODE_BOTH)) && daemon_local->flags.offlineTraceDirectory[0])
706 if (dlt_offline_trace_init(&(daemon_local->offlineTrace),daemon_local->flags.offlineTraceDirectory,daemon_local->flags.offlineTraceFileSize,daemon_local->flags.offlineTraceMaxSize)==-1)
708 dlt_log(LOG_ERR,"Could not initialize offline trace\n");
713 /* Set ECU id of daemon */
714 if (daemon_local->flags.evalue[0])
716 dlt_set_id(daemon->ecuid,daemon_local->flags.evalue);
720 dlt_set_id(daemon->ecuid,DLT_DAEMON_ECU_ID);
723 /* Set flag for optional sending of serial header */
724 daemon->sendserialheader = daemon_local->flags.lflag;
726 #ifdef DLT_SHM_ENABLE
727 /* init shared memory */
728 if (dlt_shm_init_server(&(daemon_local->dlt_shm),DLT_SHM_KEY,daemon_local->flags.sharedMemorySize)==-1)
730 dlt_log(LOG_ERR,"Could not initialize shared memory\n");
735 /* prepare main loop */
736 if (dlt_message_init(&(daemon_local->msg),daemon_local->flags.vflag)==-1)
738 dlt_log(LOG_ERR,"Could not initialize message\n");
742 if (dlt_receiver_init(&(daemon_local->receiver),daemon_local->fp,DLT_DAEMON_RCVBUFSIZE)==-1)
744 dlt_log(LOG_ERR,"Could not initialize receiver\n");
747 if (dlt_receiver_init(&(daemon_local->receiverSock),daemon_local->sock,DLT_DAEMON_RCVBUFSIZESOCK)==-1)
749 dlt_log(LOG_ERR,"Could not initialize receiver for socket\n");
752 if (daemon_local->flags.yvalue[0])
754 if (dlt_receiver_init(&(daemon_local->receiverSerial),daemon_local->fdserial,DLT_DAEMON_RCVBUFSIZESERIAL)==-1)
756 dlt_log(LOG_ERR,"Could not initialize receiver for serial connection\n");
761 /* configure sending timing packets */
762 if (daemon_local->flags.sendMessageTime)
764 daemon->timingpackets = 1;
767 /* Binary semaphore for thread */
768 if (sem_init(&dlt_daemon_mutex, 0, 1)==-1)
770 dlt_log(LOG_ERR,"Could not initialize binary semaphore\n");
774 /* Get ECU version info from a file. If it fails, use dlt_version as fallback. */
775 if(dlt_daemon_local_ecu_version_init(daemon, daemon_local, daemon_local->flags.vflag) < 0)
777 daemon->ECUVersionString = malloc(DLT_DAEMON_TEXTBUFSIZE);
778 dlt_get_version(daemon->ECUVersionString);
784 int dlt_daemon_local_connection_init(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
788 PRINT_FUNCTION_VERBOSE(verbose);
790 if ((daemon==0) || (daemon_local==0))
792 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_local_connection_init()\n");
796 /* open named pipe(FIFO) to receive DLT messages from users */
799 ret=mkdir(DLT_USER_DIR, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH | S_ISVTX );
800 if (ret==-1 && errno != EEXIST)
802 sprintf(str,"FIFO user dir %s cannot be created!\n", DLT_USER_DIR);
803 dlt_log(LOG_ERR, str);
807 // S_ISGID cannot be set by mkdir, let's reassign right bits
808 ret=chmod(DLT_USER_DIR, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH | S_ISGID | S_ISVTX );
811 sprintf(str,"FIFO user dir %s cannot be chmoded!\n", DLT_USER_DIR);
812 dlt_log(LOG_ERR, str);
816 /* Try to delete existing pipe, ignore result of unlink */
817 unlink(DLT_USER_FIFO);
819 ret=mkfifo(DLT_USER_FIFO, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP );
822 sprintf(str,"FIFO user %s cannot be created!\n",DLT_USER_FIFO);
823 dlt_log(LOG_ERR, str);
827 daemon_local->fp = open(DLT_USER_FIFO, O_RDWR);
828 if (daemon_local->fp==-1)
830 sprintf(str,"FIFO user %s cannot be opened!\n",DLT_USER_FIFO);
831 dlt_log(LOG_ERR, str);
835 /* create and open socket to receive incoming connections from client */
836 if(dlt_daemon_socket_open(&(daemon_local->sock)))
839 /* prepare usage of select(), add FIFO and receiving socket */
840 FD_ZERO(&(daemon_local->master));
841 FD_ZERO(&(daemon_local->read_fds));
842 FD_SET(daemon_local->sock, &(daemon_local->master));
844 daemon_local->fdmax = daemon_local->sock;
846 FD_SET(daemon_local->fp, &(daemon_local->master));
848 if (daemon_local->fp > daemon_local->fdmax)
850 daemon_local->fdmax = daemon_local->fp;
853 if (daemon_local->flags.yvalue[0])
855 /* create and open serial connection from/to client */
856 /* open serial connection */
857 daemon_local->fdserial=open(daemon_local->flags.yvalue,O_RDWR);
858 if (daemon_local->fdserial<0)
860 sprintf(str,"Failed to open serial device %s\n", daemon_local->flags.yvalue);
861 daemon_local->flags.yvalue[0] = 0;
862 dlt_log(LOG_ERR, str);
866 if (isatty(daemon_local->fdserial))
868 if (daemon_local->flags.bvalue[0])
870 daemon_local->baudrate = dlt_convert_serial_speed(atoi(daemon_local->flags.bvalue));
874 daemon_local->baudrate = dlt_convert_serial_speed(DLT_DAEMON_SERIAL_DEFAULT_BAUDRATE);
877 if (dlt_setup_serial(daemon_local->fdserial,daemon_local->baudrate)<0)
879 close(daemon_local->fdserial);
880 sprintf(str,"Failed to configure serial device %s (%s) \n", daemon_local->flags.yvalue, strerror(errno));
881 daemon_local->flags.yvalue[0] = 0;
882 dlt_log(LOG_ERR, str);
886 FD_SET(daemon_local->fdserial, &(daemon_local->master));
888 if (daemon_local->fdserial > daemon_local->fdmax)
890 daemon_local->fdmax = daemon_local->fdserial;
893 if (daemon_local->flags.vflag)
895 dlt_log(LOG_INFO, "Serial init done\n");
900 close(daemon_local->fdserial);
901 fprintf(stderr,"Device is not a serial device, device = %s (%s) \n", daemon_local->flags.yvalue, strerror(errno));
902 daemon_local->flags.yvalue[0] = 0;
910 int dlt_daemon_local_ecu_version_init(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
912 char *version = NULL;
915 PRINT_FUNCTION_VERBOSE(verbose);
917 /* By default, version string is null. */
918 daemon->ECUVersionString = NULL;
920 /* Open the file. Bail out if error occurs */
921 f = fopen(daemon_local->flags.pathToECUSoftwareVersion, "r");
924 /* Error level notice, because this might be deliberate choice */
925 dlt_log(LOG_NOTICE, "Failed to open ECU Software version file.\n");
929 /* Get the file size. Bail out if stat fails. */
932 if(fstat(fd, &s_buf) < 0)
934 dlt_log(LOG_ERR, "Failed to stat ECU Software version file.\n");
939 /* Bail out if file is too large. Use DLT_DAEMON_TEXTBUFSIZE max.
940 * Reserve one byte for trailing '\0' */
941 off_t size = s_buf.st_size;
942 if(size >= DLT_DAEMON_TEXTBUFSIZE)
944 dlt_log(LOG_ERR, "Too large file for ECU version.\n");
949 /* Allocate permanent buffer for version info */
950 version = malloc(size + 1);
954 offset += fread(version + offset, 1, size, f);
957 dlt_log(LOG_ERR, "Failed to read ECU Software version file.\n");
964 dlt_log(LOG_ERR, "Too long file for ECU Software version info.\n");
970 version[offset] = '\0';//append null termination at end of version string
971 daemon->ECUVersionString = version;
976 void dlt_daemon_local_cleanup(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
978 PRINT_FUNCTION_VERBOSE(verbose);
980 if ((daemon==0) || (daemon_local==0))
982 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_local_cleanup()\n");
987 dlt_receiver_free(&(daemon_local->receiver));
989 dlt_receiver_free(&(daemon_local->receiverSock));
992 dlt_message_free(&(daemon_local->msg),daemon_local->flags.vflag);
993 close(daemon_local->fp);
995 /* free shared memory */
996 if(daemon_local->flags.offlineTraceDirectory[0])
997 dlt_offline_trace_free(&(daemon_local->offlineTrace));
999 if (daemon_local->flags.ovalue[0])
1001 close(daemon_local->ohandle);
1006 dlt_file_free(&(daemon_local->file),daemon_local->flags.vflag);
1008 /* Try to delete existing pipe, ignore result of unlink() */
1009 unlink(DLT_USER_FIFO);
1011 #ifdef DLT_SHM_ENABLE
1012 /* free shared memory */
1013 dlt_shm_free_server(&(daemon_local->dlt_shm));
1016 /* Try to delete lock file, ignore result of unlink() */
1017 unlink(DLT_DAEMON_LOCK_FILE);
1020 void dlt_daemon_signal_handler(int sig)
1029 /* finalize the server */
1030 //dlt_log("terminate signal catched");
1031 dlt_log(LOG_NOTICE, "Exiting DLT daemon\n");
1033 /* Try to delete existing pipe, ignore result of unlink() */
1034 unlink(DLT_USER_FIFO);
1036 /* Try to delete lock file, ignore result of unlink() */
1037 unlink(DLT_DAEMON_LOCK_FILE);
1039 /* Terminate program */
1045 /* This case should never occur */
1049 } /* dlt_daemon_signal_handler() */
1051 void dlt_daemon_daemonize(int verbose)
1056 PRINT_FUNCTION_VERBOSE(verbose);
1058 dlt_log(LOG_NOTICE, "Daemon mode\n");
1064 dlt_log(LOG_CRIT, "Unable to fork(), exiting DLT daemon\n");
1065 exit(-1); /* fork error */
1070 exit(0); /* parent exits */
1072 /* child (daemon) continues */
1074 /* Process independency */
1076 /* obtain a new process group */
1079 dlt_log(LOG_CRIT, "setsid() failed, exiting DLT daemon\n");
1080 exit(-1); /* fork error */
1083 /* Close descriptors */
1084 for (i=getdtablesize();i>=0;--i)
1086 close(i); /* close all descriptors */
1089 /* Open standard descriptors stdin, stdout, stderr */
1090 i=open("/dev/null",O_RDWR); /* open stdin */
1094 dlt_log(LOG_ERR, "Failed to direct stdout to /dev/null.\n");/* stdout */
1096 dlt_log(LOG_ERR, "Failed to direct stderr to /dev/null.\n"); /* stderr */
1100 umask(DLT_DAEMON_UMASK);
1102 /* Change to known directory */
1103 if(chdir(DLT_USER_DIR) < 0)
1104 dlt_log(LOG_ERR, "Failed to chdir to DLT_USER_DIR.\n");;
1106 /* Ensure single copy of daemon;
1107 run only one instance at a time */
1108 lfp=open(DLT_DAEMON_LOCK_FILE,O_RDWR|O_CREAT,DLT_DAEMON_LOCK_FILE_PERM);
1111 dlt_log(LOG_CRIT, "can't open lock file, exiting DLT daemon\n");
1112 exit(-1); /* can not open */
1114 if (lockf(lfp,F_TLOCK,0)<0)
1116 dlt_log(LOG_CRIT, "can't lock lock file, exiting DLT daemon\n");
1117 exit(-1); /* can not lock */
1119 /* only first instance continues */
1121 sprintf(str,"%d\n",getpid());
1122 pid_len = strlen(str);
1123 if(write(lfp,str,pid_len) != pid_len) /* record pid to lockfile */
1124 dlt_log(LOG_ERR, "Could not write pid to file in dlt_daemon_daemonize.\n");
1127 signal(SIGCHLD,SIG_IGN); /* ignore child */
1128 signal(SIGTSTP,SIG_IGN); /* ignore tty signals */
1129 signal(SIGTTOU,SIG_IGN);
1130 signal(SIGTTIN,SIG_IGN);
1132 } /* dlt_daemon_daemonize() */
1134 int dlt_daemon_process_client_connect(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1137 struct sockaddr cli;
1141 PRINT_FUNCTION_VERBOSE(verbose);
1143 if ((daemon==0) || (daemon_local==0))
1145 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_client_connect()\n");
1149 /* event from TCP server socket, new connection */
1150 cli_size = sizeof(cli);
1151 if ((in_sock = accept(daemon_local->sock,&cli, &cli_size)) < 0)
1153 dlt_log(LOG_ERR, "accept() failed!\n");
1157 /* check if file file descriptor was already used, and make it invalid if it is reused */
1158 /* This prevents sending messages to wrong file descriptor */
1159 dlt_daemon_applications_invalidate_fd(daemon,in_sock,verbose);
1160 dlt_daemon_contexts_invalidate_fd(daemon,in_sock,verbose);
1162 /* Set socket timeout in reception */
1163 struct timeval timeout_send;
1164 timeout_send.tv_sec = daemon_local->timeoutOnSend;
1165 timeout_send.tv_usec = 0;
1166 if (setsockopt (in_sock, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout_send, sizeof(timeout_send)) < 0)
1167 dlt_log(LOG_ERR, "setsockopt failed\n");
1169 /* Set to non blocking mode */
1170 //flags = fcntl(in_sock, F_GETFL, 0);
1171 //fcntl(in_sock, F_SETFL, flags | O_NONBLOCK);
1173 //sprintf("str,"Client Connection from %s\n", inet_ntoa(cli.sin_addr));
1175 FD_SET(in_sock, &(daemon_local->master)); /* add to master set */
1176 if (in_sock > daemon_local->fdmax)
1178 /* keep track of the maximum */
1179 daemon_local->fdmax = in_sock;
1182 daemon_local->client_connections++;
1183 if (daemon_local->flags.vflag)
1185 sprintf(str, "New connection to client established, #connections: %d\n",daemon_local->client_connections);
1186 dlt_log(LOG_INFO, str);
1189 // send connection info about connected
1190 dlt_daemon_control_message_connection_info(in_sock,daemon,daemon_local,DLT_CONNECTION_STATUS_CONNECTED,"",verbose);
1192 // send ecu version string
1193 if(daemon_local->flags.sendECUSoftwareVersion > 0)
1195 if(daemon_local->flags.sendECUSoftwareVersion > 0)
1196 dlt_daemon_control_get_software_version(DLT_DAEMON_SEND_TO_ALL, daemon,daemon_local, daemon_local->flags.vflag);
1198 if(daemon_local->flags.sendTimezone > 0)
1200 dlt_daemon_control_message_timezone(DLT_DAEMON_SEND_TO_ALL,daemon,daemon_local,daemon_local->flags.vflag);
1204 if (daemon_local->client_connections==1)
1206 if (daemon_local->flags.vflag)
1208 dlt_log(LOG_INFO, "Send ring-buffer to client\n");
1210 dlt_daemon_change_state(daemon, DLT_DAEMON_STATE_SEND_BUFFER);
1211 if (dlt_daemon_send_ringbuffer_to_client(daemon, daemon_local, verbose)==-1)
1213 dlt_log(LOG_ERR,"Can't send contents of ringbuffer to clients\n");
1217 /* send new log state to all applications */
1218 daemon->connectionState = 1;
1219 dlt_daemon_user_send_all_log_state(daemon,verbose);
1225 int dlt_daemon_process_client_messages(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1227 int bytes_to_be_removed=0;
1229 PRINT_FUNCTION_VERBOSE(verbose);
1231 if ((daemon==0) || (daemon_local==0))
1233 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_client_messages()\n");
1237 if (dlt_receiver_receive_socket(&(daemon_local->receiverSock))<=0)
1239 dlt_daemon_close_socket(daemon_local->receiverSock.fd, daemon, daemon_local, verbose);
1240 daemon_local->receiverSock.fd = -1;
1241 /* check: return 0; */
1244 /* Process all received messages */
1245 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)==DLT_MESSAGE_ERROR_OK)
1247 /* Check for control message */
1248 if ( 0 < daemon_local->receiverSock.fd && DLT_MSG_IS_CONTROL_REQUEST(&(daemon_local->msg)) )
1250 dlt_daemon_client_process_control(daemon_local->receiverSock.fd, daemon,daemon_local, &(daemon_local->msg), daemon_local->flags.vflag);
1253 bytes_to_be_removed = daemon_local->msg.headersize+daemon_local->msg.datasize-sizeof(DltStorageHeader);
1254 if (daemon_local->msg.found_serialheader)
1256 bytes_to_be_removed += sizeof(dltSerialHeader);
1258 if (daemon_local->msg.resync_offset)
1260 bytes_to_be_removed += daemon_local->msg.resync_offset;
1263 if (dlt_receiver_remove(&(daemon_local->receiverSock),bytes_to_be_removed)==-1)
1265 dlt_log(LOG_ERR,"Can't remove bytes from receiver for sockets\n");
1272 if (dlt_receiver_move_to_begin(&(daemon_local->receiverSock))==-1)
1274 dlt_log(LOG_ERR,"Can't move bytes to beginning of receiver buffer for sockets\n");
1281 int dlt_daemon_process_client_messages_serial(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1283 int bytes_to_be_removed=0;
1285 PRINT_FUNCTION_VERBOSE(verbose);
1287 if ((daemon==0) || (daemon_local==0))
1289 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_client_messages_serial()\n");
1293 if (dlt_receiver_receive_fd(&(daemon_local->receiverSerial))<=0)
1295 dlt_log(LOG_ERR, "dlt_receiver_receive_fd() for messages from serial interface failed!\n");
1299 /* Process all received messages */
1300 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)==DLT_MESSAGE_ERROR_OK)
1302 /* Check for control message */
1303 if (DLT_MSG_IS_CONTROL_REQUEST(&(daemon_local->msg)))
1305 if (dlt_daemon_client_process_control(daemon_local->receiverSerial.fd, daemon,daemon_local, &(daemon_local->msg), daemon_local->flags.vflag)==-1)
1307 dlt_log(LOG_ERR,"Can't process control messages\n");
1312 bytes_to_be_removed = daemon_local->msg.headersize+daemon_local->msg.datasize-sizeof(DltStorageHeader);
1313 if (daemon_local->msg.found_serialheader)
1315 bytes_to_be_removed += sizeof(dltSerialHeader);
1317 if (daemon_local->msg.resync_offset)
1319 bytes_to_be_removed += daemon_local->msg.resync_offset;
1322 if (dlt_receiver_remove(&(daemon_local->receiverSerial),bytes_to_be_removed)==-1)
1324 dlt_log(LOG_ERR,"Can't remove bytes from receiver for serial connection\n");
1331 if (dlt_receiver_move_to_begin(&(daemon_local->receiverSerial))==-1)
1333 dlt_log(LOG_ERR,"Can't move bytes to beginning of receiver buffer for serial connection\n");
1340 int dlt_daemon_process_user_messages(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1344 DltUserHeader *userheader;
1346 PRINT_FUNCTION_VERBOSE(verbose);
1348 if ((daemon==0) || (daemon_local==0))
1350 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_messages()\n");
1354 /* read data from FIFO */
1355 if (dlt_receiver_receive_fd(&(daemon_local->receiver))<0)
1357 dlt_log(LOG_ERR, "dlt_receiver_receive_fd() for user messages failed!\n");
1361 /* look through buffer as long as data is in there */
1364 if (daemon_local->receiver.bytesRcvd < (int32_t)sizeof(DltUserHeader))
1369 /* resync if necessary */
1373 userheader = (DltUserHeader*) (daemon_local->receiver.buf+offset);
1375 /* Check for user header pattern */
1376 if (dlt_user_check_userheader(userheader))
1384 while ((int32_t)(sizeof(DltUserHeader)+offset)<=daemon_local->receiver.bytesRcvd);
1386 /* Check for user header pattern */
1387 if (dlt_user_check_userheader(userheader)==0)
1392 /* Set new start offset */
1395 daemon_local->receiver.buf+=offset;
1396 daemon_local->receiver.bytesRcvd-=offset;
1399 switch (userheader->message)
1401 case DLT_USER_MESSAGE_OVERFLOW:
1403 if (dlt_daemon_process_user_message_overflow(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1409 case DLT_USER_MESSAGE_REGISTER_CONTEXT:
1411 if (dlt_daemon_process_user_message_register_context(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1417 case DLT_USER_MESSAGE_UNREGISTER_CONTEXT:
1419 if (dlt_daemon_process_user_message_unregister_context(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1425 case DLT_USER_MESSAGE_LOG:
1427 if (dlt_daemon_process_user_message_log(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1433 #ifdef DLT_SHM_ENABLE
1434 case DLT_USER_MESSAGE_LOG_SHM:
1436 if (dlt_daemon_process_user_message_log_shm(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1443 case DLT_USER_MESSAGE_REGISTER_APPLICATION:
1445 if (dlt_daemon_process_user_message_register_application(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1451 case DLT_USER_MESSAGE_UNREGISTER_APPLICATION:
1453 if (dlt_daemon_process_user_message_unregister_application(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1459 case DLT_USER_MESSAGE_APP_LL_TS:
1461 if (dlt_daemon_process_user_message_set_app_ll_ts(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1467 case DLT_USER_MESSAGE_LOG_MODE:
1469 if (dlt_daemon_process_user_message_log_mode(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1477 dlt_log(LOG_ERR,"(Internal) Invalid user message type received!\n");
1479 /* remove user header */
1480 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader))==-1)
1482 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user messages\n");
1486 /* In next invocation of do-while loop, a resync will be triggered if additional data was received */
1496 /* keep not read data in buffer */
1497 if (dlt_receiver_move_to_begin(&(daemon_local->receiver))==-1)
1499 dlt_log(LOG_ERR,"Can't move bytes to beginning of receiver buffer for user messages\n");
1506 int dlt_daemon_process_user_message_overflow(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1509 DltUserControlMsgBufferOverflow *userpayload;
1511 PRINT_FUNCTION_VERBOSE(verbose);
1513 if ((daemon==0) || (daemon_local==0))
1515 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_overflow()\n");
1519 if (daemon_local->receiver.bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgBufferOverflow)))
1521 /* Not enough bytes received */
1525 /* get the payload of the user message */
1526 userpayload = (DltUserControlMsgBufferOverflow*) (daemon_local->receiver.buf+sizeof(DltUserHeader));
1528 /* Store in daemon, that a message buffer overflow has occured */
1529 /* look if TCP connection to client is available or it least message can be put into buffer */
1530 if((ret=dlt_daemon_control_message_buffer_overflow(DLT_DAEMON_SEND_TO_ALL, daemon,daemon_local, userpayload->overflow_counter,userpayload->apid,verbose)))
1532 /* there was an error when storing message */
1533 /* add the counter of lost messages to the daemon counter */
1534 daemon->overflow_counter+=userpayload->overflow_counter;
1537 /* keep not read data in buffer */
1538 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgBufferOverflow))==-1)
1540 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message overflow\n");
1547 int dlt_daemon_send_message_overflow(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1550 PRINT_FUNCTION_VERBOSE(verbose);
1552 if ((daemon==0) || (daemon_local==0))
1554 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_overflow()\n");
1555 return DLT_DAEMON_ERROR_UNKNOWN;
1558 /* Store in daemon, that a message buffer overflow has occured */
1559 if((ret=dlt_daemon_control_message_buffer_overflow(DLT_DAEMON_SEND_TO_ALL, daemon,daemon_local,daemon->overflow_counter,"", verbose)))
1564 return DLT_DAEMON_ERROR_OK;
1567 int dlt_daemon_process_user_message_register_application(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1570 DltDaemonApplication *application;
1571 char description[DLT_DAEMON_DESCSIZE];
1572 DltUserControlMsgRegisterApplication *usercontext;
1574 PRINT_FUNCTION_VERBOSE(verbose);
1576 if ((daemon==0) || (daemon_local==0))
1578 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_register_application()\n");
1582 if (daemon_local->receiver.bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterApplication)))
1584 /* Not enough bytes received */
1588 usercontext = (DltUserControlMsgRegisterApplication*) (daemon_local->receiver.buf+sizeof(DltUserHeader));
1590 memset(description,0,sizeof(description));
1592 len=usercontext->description_length;
1593 if ((len>0) && (len<=DLT_DAEMON_DESCSIZE))
1595 /* Read and store application description */
1596 strncpy(description, (daemon_local->receiver.buf+sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterApplication)), len);
1599 application=dlt_daemon_application_add(daemon,usercontext->apid,usercontext->pid,description,verbose);
1601 /* send log state to new application */
1602 dlt_daemon_user_send_log_state(daemon,application,verbose);
1604 /* keep not read data in buffer */
1605 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterApplication)+len)==-1)
1607 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register application\n");
1613 dlt_log(LOG_CRIT,"Can't add application");
1620 int dlt_daemon_process_user_message_register_context(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1623 int8_t loglevel, tracestatus;
1624 DltUserControlMsgRegisterContext *usercontext;
1625 char description[DLT_DAEMON_DESCSIZE];
1626 DltDaemonApplication *application;
1627 DltDaemonContext *context;
1628 DltServiceGetLogInfoRequest *req;
1632 PRINT_FUNCTION_VERBOSE(verbose);
1634 if ((daemon==0) || (daemon_local==0))
1636 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_register_context()\n");
1640 if (daemon_local->receiver.bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)))
1642 /* Not enough bytes received */
1646 usercontext = (DltUserControlMsgRegisterContext*) (daemon_local->receiver.buf+sizeof(DltUserHeader));
1648 memset(description,0,sizeof(description));
1650 len=usercontext->description_length;
1651 if ((len>0) && (len<=DLT_DAEMON_DESCSIZE))
1653 /* Read and store context description */
1654 strncpy(description, (daemon_local->receiver.buf+sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)), len);
1657 application = dlt_daemon_application_find(daemon,usercontext->apid,verbose);
1661 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)+len)==-1)
1663 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register context\n");
1666 dlt_log(LOG_ERR, "Application not found in dlt_daemon_process_user_message_register_context()\n");
1670 /* Pre-set loglevel */
1671 if (usercontext->log_level == DLT_USER_LOG_LEVEL_NOT_SET)
1673 loglevel=DLT_LOG_DEFAULT;
1677 loglevel=usercontext->log_level;
1678 /* Plausibility check */
1679 if ((loglevel<DLT_LOG_DEFAULT) || (loglevel>DLT_LOG_VERBOSE))
1681 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)+len)==-1)
1683 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register context\n");
1689 /* Pre-set tracestatus */
1690 if (usercontext->trace_status == DLT_USER_TRACE_STATUS_NOT_SET)
1692 tracestatus=DLT_TRACE_STATUS_DEFAULT;
1696 tracestatus=usercontext->trace_status;
1698 /* Plausibility check */
1699 if ((tracestatus<DLT_TRACE_STATUS_DEFAULT) || (tracestatus>DLT_TRACE_STATUS_ON))
1701 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)+len)==-1)
1703 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register context\n");
1709 context = dlt_daemon_context_add(daemon,usercontext->apid,usercontext->ctid, loglevel, tracestatus, usercontext->log_level_pos,application->user_handle,description,verbose);
1713 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)+len)==-1)
1715 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register context\n");
1718 dlt_log(LOG_CRIT,"Can't add context");
1721 /* Create automatic get log info response for registered context */
1722 if (daemon_local->flags.rflag)
1724 /* Prepare request for get log info with one application and one context */
1725 if (dlt_message_init(&msg, verbose)==-1)
1727 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)+len)==-1)
1729 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register context\n");
1732 dlt_log(LOG_ERR,"Can't initialize message");
1736 msg.datasize = sizeof(DltServiceGetLogInfoRequest);
1737 if (msg.databuffer && (msg.databuffersize < msg.datasize))
1739 free(msg.databuffer);
1742 if (msg.databuffer == 0){
1743 msg.databuffer = (uint8_t *) malloc(msg.datasize);
1744 msg.databuffersize = msg.datasize;
1746 if (msg.databuffer==0)
1748 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)+len)==-1)
1750 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register context\n");
1753 dlt_log(LOG_ERR,"Can't allocate buffer for get log info message\n");
1757 req = (DltServiceGetLogInfoRequest*) msg.databuffer;
1759 req->service_id = DLT_SERVICE_ID_GET_LOG_INFO;
1761 dlt_set_id(req->apid, usercontext->apid);
1762 dlt_set_id(req->ctid, usercontext->ctid);
1763 dlt_set_id(req->com,"remo");
1765 dlt_daemon_control_get_log_info(DLT_DAEMON_SEND_TO_ALL , daemon,daemon_local, &msg, verbose);
1767 dlt_message_free(&msg, verbose);
1770 if (context->user_handle >= DLT_FD_MINIMUM)
1772 /* This call also replaces the default values with the values defined for default */
1773 if (dlt_daemon_user_send_log_level(daemon, context, verbose)==-1)
1775 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)+len)==-1)
1777 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register context\n");
1780 dlt_log(LOG_ERR,"Can't send current log level as response to user message register context\n");
1785 /* keep not read data in buffer */
1786 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)+len)==-1)
1788 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register context\n");
1795 int dlt_daemon_process_user_message_unregister_application(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1797 DltUserControlMsgUnregisterApplication *usercontext;
1798 DltDaemonApplication *application;
1799 DltDaemonContext *context;
1802 PRINT_FUNCTION_VERBOSE(verbose);
1804 if ((daemon==0) || (daemon_local==0))
1806 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_unregister_application()\n");
1810 if (daemon_local->receiver.bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgUnregisterApplication)))
1812 /* Not enough bytes received */
1816 if (daemon->num_applications>0)
1818 usercontext = (DltUserControlMsgUnregisterApplication*) (daemon_local->receiver.buf+sizeof(DltUserHeader));
1820 /* Delete this application and all corresponding contexts for this application from internal table */
1821 application = dlt_daemon_application_find(daemon,usercontext->apid, verbose);
1825 /* Calculate start offset within contexts[] */
1827 for (i=0; i<(application-(daemon->applications)); i++)
1829 offset_base+=daemon->applications[i].num_contexts;
1832 for (i=application->num_contexts-1; i>=0; i--)
1834 context = &(daemon->contexts[offset_base+i]);
1837 /* Delete context */
1838 if (dlt_daemon_context_del(daemon, context, verbose)==-1)
1840 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgUnregisterApplication))==-1)
1842 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message unregister application\n");
1845 dlt_log(LOG_ERR,"Can't delete context for user message unregister application\n");
1851 /* Delete this application entry from internal table*/
1852 if (dlt_daemon_application_del(daemon, application, verbose)==-1)
1854 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgUnregisterApplication))==-1)
1856 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message unregister application\n");
1859 dlt_log(LOG_ERR,"Can't delete application for user message unregister application\n");
1865 /* keep not read data in buffer */
1866 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgUnregisterApplication))==-1)
1868 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message unregister application\n");
1875 int dlt_daemon_process_user_message_unregister_context(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1877 DltUserControlMsgUnregisterContext *usercontext;
1878 DltDaemonContext *context;
1880 PRINT_FUNCTION_VERBOSE(verbose);
1882 if ((daemon==0) || (daemon_local==0))
1884 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_unregister_context()\n");
1888 if (daemon_local->receiver.bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgUnregisterContext)))
1890 /* Not enough bytes received */
1894 usercontext = (DltUserControlMsgUnregisterContext*) (daemon_local->receiver.buf+sizeof(DltUserHeader));
1895 context = dlt_daemon_context_find(daemon,usercontext->apid, usercontext->ctid, verbose);
1899 /* Delete this connection entry from internal table*/
1900 if (dlt_daemon_context_del(daemon, context, verbose)==-1)
1902 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgUnregisterContext))==-1)
1904 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message unregister context\n");
1907 dlt_log(LOG_ERR,"Can't delete context for user message unregister context\n");
1912 /* Create automatic unregister context response for unregistered context */
1913 if (daemon_local->flags.rflag)
1915 dlt_daemon_control_message_unregister_context(DLT_DAEMON_SEND_TO_ALL,daemon,daemon_local,usercontext->apid, usercontext->ctid, "remo",verbose);
1918 /* keep not read data in buffer */
1919 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgUnregisterContext))==-1)
1921 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message unregister context\n");
1928 int dlt_daemon_process_user_message_log(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1931 int bytes_to_be_removed;
1933 static char text[DLT_DAEMON_TEXTSIZE];
1935 PRINT_FUNCTION_VERBOSE(verbose);
1937 if ((daemon==0) || (daemon_local==0))
1939 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_log()\n");
1940 return DLT_DAEMON_ERROR_UNKNOWN;
1943 ret=dlt_message_read(&(daemon_local->msg),(unsigned char*)daemon_local->receiver.buf+sizeof(DltUserHeader),daemon_local->receiver.bytesRcvd-sizeof(DltUserHeader),0,verbose);
1944 if(ret!=DLT_MESSAGE_ERROR_OK)
1946 if(ret!=DLT_MESSAGE_ERROR_SIZE)
1948 dlt_log(LOG_ERR,"Can't read messages from receiver\n");
1950 return DLT_DAEMON_ERROR_UNKNOWN;
1953 /* set overwrite ecu id */
1954 if (daemon_local->flags.evalue!=0)
1956 /* Set header extra parameters */
1957 dlt_set_id(daemon_local->msg.headerextra.ecu, daemon->ecuid );
1958 //msg.headerextra.seid = 0;
1959 if (dlt_message_set_extraparameters(&(daemon_local->msg),0)==-1)
1961 dlt_log(LOG_ERR,"Can't set message extra parameters in process user message log\n");
1962 return DLT_DAEMON_ERROR_UNKNOWN;
1965 /* Correct value of timestamp, this was changed by dlt_message_set_extraparameters() */
1966 daemon_local->msg.headerextra.tmsp = DLT_BETOH_32(daemon_local->msg.headerextra.tmsp);
1969 /* prepare storage header */
1970 if (DLT_IS_HTYP_WEID(daemon_local->msg.standardheader->htyp))
1972 if (dlt_set_storageheader(daemon_local->msg.storageheader,daemon_local->msg.headerextra.ecu)==-1)
1974 dlt_log(LOG_ERR,"Can't set storage header in process user message log\n");
1975 return DLT_DAEMON_ERROR_UNKNOWN;
1980 if (dlt_set_storageheader(daemon_local->msg.storageheader,daemon->ecuid)==-1)
1982 dlt_log(LOG_ERR,"Can't set storage header in process user message log\n");
1983 return DLT_DAEMON_ERROR_UNKNOWN;
1988 /* if no filter set or filter is matching display message */
1989 if (daemon_local->flags.xflag)
1991 if (dlt_message_print_hex(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1)
1993 dlt_log(LOG_ERR,"dlt_message_print_hex() failed!\n");
1996 else if (daemon_local->flags.aflag)
1998 if (dlt_message_print_ascii(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1)
2000 dlt_log(LOG_ERR,"dlt_message_print_ascii() failed!\n");
2003 else if (daemon_local->flags.sflag)
2005 if (dlt_message_print_header(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1)
2007 dlt_log(LOG_ERR,"dlt_message_print_header() failed!\n");
2009 /* print message header only */
2013 /* check if overflow occurred */
2014 if(daemon->overflow_counter)
2016 if(dlt_daemon_send_message_overflow(daemon,daemon_local,verbose)==0)
2018 sprintf(str,"%u messages discarded!\n",daemon->overflow_counter);
2019 dlt_log(LOG_ERR, str);
2020 daemon->overflow_counter=0;
2024 /* look if TCP connection to client is available */
2025 if((daemon->mode == DLT_USER_MODE_EXTERNAL) || (daemon->mode == DLT_USER_MODE_BOTH))
2028 if((ret = dlt_daemon_client_send(DLT_DAEMON_SEND_TO_ALL,daemon,daemon_local,daemon_local->msg.headerbuffer+sizeof(DltStorageHeader),daemon_local->msg.headersize-sizeof(DltStorageHeader),
2029 daemon_local->msg.databuffer,daemon_local->msg.datasize,verbose)))
2031 if(ret == DLT_DAEMON_ERROR_BUFFER_FULL)
2033 daemon->overflow_counter++;
2039 /* keep not read data in buffer */
2040 bytes_to_be_removed = daemon_local->msg.headersize+daemon_local->msg.datasize-sizeof(DltStorageHeader)+sizeof(DltUserHeader);
2041 if (daemon_local->msg.found_serialheader)
2043 bytes_to_be_removed += sizeof(dltSerialHeader);
2046 if (dlt_receiver_remove(&(daemon_local->receiver),bytes_to_be_removed)==-1)
2048 dlt_log(LOG_ERR,"Can't remove bytes from receiver\n");
2049 return DLT_DAEMON_ERROR_UNKNOWN;
2052 return DLT_DAEMON_ERROR_OK;
2055 #ifdef DLT_SHM_ENABLE
2056 int dlt_daemon_process_user_message_log_shm(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
2058 int bytes_to_be_removed=0;
2059 int j,sent,third_value;
2061 uint8_t rcv_buffer[10000];
2063 DltUserHeader *userheader;
2065 static char text[DLT_DAEMON_TEXTSIZE];
2067 PRINT_FUNCTION_VERBOSE(verbose);
2069 if ((daemon==0) || (daemon_local==0))
2071 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_log()\n");
2075 userheader = (DltUserHeader*) (daemon_local->receiver.buf);
2077 //dlt_shm_status(&(daemon_local->dlt_shm));
2080 /* log message in SHM */
2081 if((size = dlt_shm_copy(&(daemon_local->dlt_shm),rcv_buffer,10000)) <= 0)
2083 if (dlt_message_read(&(daemon_local->msg),rcv_buffer,size,0,verbose)!=0) {
2085 dlt_log(LOG_ERR,"Can't read messages from shm\n");
2088 bytes_to_be_removed = daemon_local->msg.headersize+daemon_local->msg.datasize-sizeof(DltStorageHeader)+sizeof(DltUserHeader);
2089 if (daemon_local->msg.found_serialheader)
2091 bytes_to_be_removed += sizeof(dltSerialHeader);
2094 /* set overwrite ecu id */
2095 if (daemon_local->flags.evalue[0])
2097 /* Set header extra parameters */
2098 dlt_set_id(daemon_local->msg.headerextra.ecu, daemon->ecuid );
2099 //msg.headerextra.seid = 0;
2100 if (dlt_message_set_extraparameters(&(daemon_local->msg),0)==-1)
2102 dlt_log(LOG_ERR,"Can't set message extra parameters in process user message log\n");
2103 dlt_shm_remove(&(daemon_local->dlt_shm));
2107 /* Correct value of timestamp, this was changed by dlt_message_set_extraparameters() */
2108 daemon_local->msg.headerextra.tmsp = DLT_BETOH_32(daemon_local->msg.headerextra.tmsp);
2111 /* prepare storage header */
2112 if (DLT_IS_HTYP_WEID(daemon_local->msg.standardheader->htyp))
2114 if (dlt_set_storageheader(daemon_local->msg.storageheader,daemon_local->msg.headerextra.ecu)==-1)
2116 dlt_log(LOG_ERR,"Can't set storage header in process user message log\n");
2117 dlt_shm_remove(&(daemon_local->dlt_shm));
2123 if (dlt_set_storageheader(daemon_local->msg.storageheader,daemon->ecuid)==-1)
2125 dlt_log(LOG_ERR,"Can't set storage header in process user message log\n");
2126 dlt_shm_remove(&(daemon_local->dlt_shm));
2131 /* display message */
2132 if (daemon_local->flags.xflag)
2134 if (dlt_message_print_hex(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1)
2136 dlt_log(LOG_ERR,"dlt_message_print_hex() failed!\n");
2139 else if (daemon_local->flags.aflag)
2141 if (dlt_message_print_ascii(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1)
2143 dlt_log(LOG_ERR,"dlt_message_print_ascii() failed!\n");
2146 else if (daemon_local->flags.sflag)
2148 if (dlt_message_print_header(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1)
2150 dlt_log(LOG_ERR,"dlt_message_print_header() failed!\n");
2152 /* print message header only */
2157 /* write message to offline trace */
2158 if(((daemon->mode == DLT_USER_MODE_INTERNAL) || (daemon->mode == DLT_USER_MODE_BOTH)) && daemon_local->flags.offlineTraceDirectory[0])
2160 dlt_offline_trace_write(&(daemon_local->offlineTrace),daemon_local->msg.headerbuffer,daemon_local->msg.headersize,
2161 daemon_local->msg.databuffer,daemon_local->msg.datasize,0,0);
2165 /* look if TCP connection to client is available */
2166 for (j = 0;((daemon->mode == DLT_USER_MODE_EXTERNAL) || (daemon->mode == DLT_USER_MODE_BOTH)) && (j <= daemon_local->fdmax); j++)
2168 /* send to everyone! */
2169 if (FD_ISSET(j, &(daemon_local->master)))
2171 /* except the listener and ourselves */
2172 if (daemon_local->flags.yvalue[0])
2174 third_value = daemon_local->fdserial;
2178 third_value = daemon_local->sock;
2181 if ((j != daemon_local->fp) && (j != daemon_local->sock) && (j != third_value))
2183 DLT_DAEMON_SEM_LOCK();
2185 if (daemon_local->flags.lflag)
2187 send(j,dltSerialHeader,sizeof(dltSerialHeader),0);
2190 send(j,daemon_local->msg.headerbuffer+sizeof(DltStorageHeader),daemon_local->msg.headersize-sizeof(DltStorageHeader),0);
2191 send(j,daemon_local->msg.databuffer,daemon_local->msg.datasize,0);
2193 DLT_DAEMON_SEM_FREE();
2197 else if ((j == daemon_local->fdserial) && (daemon_local->flags.yvalue[0]))
2199 DLT_DAEMON_SEM_LOCK();
2201 if (daemon_local->flags.lflag)
2203 ret=write(j,dltSerialHeader,sizeof(dltSerialHeader));
2206 ret=write(j,daemon_local->msg.headerbuffer+sizeof(DltStorageHeader),daemon_local->msg.headersize-sizeof(DltStorageHeader));
2207 ret=write(j,daemon_local->msg.databuffer,daemon_local->msg.datasize);
2209 DLT_DAEMON_SEM_FREE();
2216 /* Message was not sent to client, so store it in client ringbuffer */
2217 if (sent==1 || (daemon->mode == DLT_USER_MODE_OFF))
2219 if(userheader->message == DLT_USER_MESSAGE_LOG_SHM) {
2220 /* dlt message was sent, remove from buffer if log message from shm */
2221 dlt_shm_remove(&(daemon_local->dlt_shm));
2226 /* dlt message was not sent, keep in buffer */
2232 /* keep not read data in buffer */
2233 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader))==-1)
2235 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message overflow\n");
2243 int dlt_daemon_process_user_message_set_app_ll_ts(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
2245 DltUserControlMsgAppLogLevelTraceStatus *usercontext;
2246 DltDaemonApplication *application;
2247 DltDaemonContext *context;
2249 int8_t old_log_level, old_trace_status;
2251 PRINT_FUNCTION_VERBOSE(verbose);
2253 if ((daemon==0) || (daemon_local==0))
2255 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_set_app_ll_ts()\n");
2259 if (daemon_local->receiver.bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgAppLogLevelTraceStatus )))
2261 /* Not enough bytes receeived */
2265 if (daemon->num_applications>0)
2267 usercontext = (DltUserControlMsgAppLogLevelTraceStatus*) (daemon_local->receiver.buf+sizeof(DltUserHeader));
2269 /* Get all contexts with application id matching the received application id */
2270 application = dlt_daemon_application_find(daemon, usercontext->apid, verbose);
2273 /* Calculate start offset within contexts[] */
2275 for (i=0; i<(application-(daemon->applications)); i++)
2277 offset_base+=daemon->applications[i].num_contexts;
2280 for (i=0; i < application->num_contexts; i++)
2282 context = &(daemon->contexts[offset_base+i]);
2285 old_log_level = context->log_level;
2286 context->log_level = usercontext->log_level; /* No endianess conversion necessary*/
2288 old_trace_status = context->trace_status;
2289 context->trace_status = usercontext->trace_status; /* No endianess conversion necessary */
2291 /* The folowing function sends also the trace status */
2292 if (context->user_handle >= DLT_FD_MINIMUM && dlt_daemon_user_send_log_level(daemon, context, verbose)!=0)
2294 context->log_level = old_log_level;
2295 context->trace_status = old_trace_status;
2302 /* keep not read data in buffer */
2303 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgAppLogLevelTraceStatus))==-1)
2305 dlt_log(LOG_ERR,"Can't remove bytes from receiver\n");
2312 int dlt_daemon_process_user_message_log_mode(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
2314 DltUserControlMsgLogMode *logmode;
2316 PRINT_FUNCTION_VERBOSE(verbose);
2318 if ((daemon==0) || (daemon_local==0))
2320 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_log_mode()\n");
2324 if (daemon_local->receiver.bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgUnregisterContext)))
2326 /* Not enough bytes received */
2330 logmode = (DltUserControlMsgLogMode*) (daemon_local->receiver.buf+sizeof(DltUserHeader));
2332 /* set the new log mode */
2333 daemon->mode = logmode->log_mode;
2335 /* write configuration persistantly */
2336 dlt_daemon_configuration_save(daemon, daemon->runtime_configuration, verbose);
2338 /* keep not read data in buffer */
2339 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogMode))==-1)
2341 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message log mode\n");
2348 int dlt_daemon_send_ringbuffer_to_client(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
2351 static uint8_t data[DLT_DAEMON_RCVBUFSIZE];
2354 PRINT_FUNCTION_VERBOSE(verbose);
2356 if ((daemon==0) || (daemon_local==0))
2358 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_send_ringbuffer_to_client()\n");
2359 return DLT_DAEMON_ERROR_UNKNOWN;
2362 if(dlt_buffer_get_message_count(&(daemon->client_ringbuffer)) <= 0)
2364 dlt_daemon_change_state(daemon, DLT_DAEMON_STATE_SEND_DIRECT);
2365 return DLT_DAEMON_ERROR_OK;
2368 while ( (length = dlt_buffer_copy(&(daemon->client_ringbuffer), data, sizeof(data)) ) > 0)
2370 if((ret = dlt_daemon_client_send(DLT_DAEMON_SEND_FORCE,daemon,daemon_local,data,length,0,0,verbose)))
2374 dlt_buffer_remove(&(daemon->client_ringbuffer));
2375 if(daemon->state != DLT_DAEMON_STATE_SEND_BUFFER)
2376 dlt_daemon_change_state(daemon,DLT_DAEMON_STATE_SEND_BUFFER);
2378 if(dlt_buffer_get_message_count(&(daemon->client_ringbuffer)) <= 0)
2380 dlt_daemon_change_state(daemon,DLT_DAEMON_STATE_SEND_DIRECT);
2381 return DLT_DAEMON_ERROR_OK;
2385 return DLT_DAEMON_ERROR_OK;
2388 int create_timer_fd(DltDaemonLocal *daemon_local, int period_sec, int starts_in, int* fd, const char* timer_name)
2391 struct itimerspec l_timer_spec;
2393 if(timer_name == NULL)
2395 timer_name = "timer_not_named";
2400 snprintf(str, sizeof(str), "<%s> fd is NULL pointer\n", timer_name );
2401 dlt_log(DLT_LOG_ERROR, str);
2405 if( period_sec > 0 ) {
2406 local_fd = timerfd_create(CLOCK_MONOTONIC, 0);
2409 snprintf(str, sizeof(str), "<%s> timerfd_create failed: %s\n", timer_name, strerror(errno));
2410 dlt_log(DLT_LOG_ERROR, str);
2413 l_timer_spec.it_interval.tv_sec = period_sec;
2414 l_timer_spec.it_interval.tv_nsec = 0;
2415 l_timer_spec.it_value.tv_sec = starts_in;
2416 l_timer_spec.it_value.tv_nsec = 0;
2418 if( timerfd_settime( local_fd, 0, &l_timer_spec, NULL) < 0)
2420 snprintf(str, sizeof(str), "<%s> timerfd_settime failed: %s\n", timer_name, strerror(errno));
2421 dlt_log(DLT_LOG_ERROR, str);
2426 // timer not activated via the service file
2427 snprintf(str, sizeof(str), "<%s> not set: period=0\n", timer_name);
2428 dlt_log(DLT_LOG_INFO, str);
2432 // If fd is fully initialized, let's add it to the fd sets
2435 snprintf(str, sizeof(str), "<%s> initialized with %ds timer\n", timer_name, period_sec);
2436 dlt_log(DLT_LOG_INFO, str);
2438 FD_SET(local_fd, &(daemon_local->master));
2439 //FD_SET(local_fd, &(daemon_local->timer_fds));
2440 if (local_fd > daemon_local->fdmax)
2442 daemon_local->fdmax = local_fd;
2451 /* Close connection function */
2452 int dlt_daemon_close_socket(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
2454 dlt_daemon_socket_close(sock);
2456 FD_CLR(sock, &(daemon_local->master));
2458 if (daemon_local->client_connections)
2460 daemon_local->client_connections--;
2463 if(daemon_local->client_connections==0)
2465 /* send new log state to all applications */
2466 daemon->connectionState = 0;
2467 dlt_daemon_user_send_all_log_state(daemon,verbose);
2468 dlt_daemon_change_state(daemon,DLT_DAEMON_STATE_BUFFER);
2471 if (daemon_local->flags.vflag)
2473 sprintf(str, "Connection to client lost, #connections: %d\n",daemon_local->client_connections);
2474 dlt_log(LOG_INFO, str);
2477 dlt_daemon_control_message_connection_info(DLT_DAEMON_SEND_TO_ALL,daemon,daemon_local,DLT_CONNECTION_STATUS_DISCONNECTED,"",verbose);