3 * Copyright (C) 2012-2014 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/.
17 * Alexander Wenzel <alexander.aw.wenzel@bmw.de>
18 * Markus Klein <Markus.Klein@esk.fraunhofer.de>
19 * Mikko Rapeli <mikko.rapeli@bmw.de>
22 * For further information see http://www.genivi.org/.
28 #include <stdio.h> /* for printf() and fprintf() */
29 #include <sys/socket.h> /* for socket(), connect(), (), and recv() */
30 #include <arpa/inet.h> /* for sockaddr_in and inet_addr() */
31 #include <stdlib.h> /* for atoi() and exit() */
32 #include <string.h> /* for memset() */
33 #include <unistd.h> /* for close() */
41 #include <sys/timerfd.h>
46 #include <linux/stat.h>
49 #include "dlt_types.h"
50 #include "dlt-daemon.h"
51 #include "dlt-daemon_cfg.h"
52 #include "dlt_daemon_common_cfg.h"
54 #include "dlt_daemon_socket.h"
55 #include "dlt_daemon_serial.h"
57 #include "dlt_daemon_client.h"
59 #if defined(DLT_SYSTEMD_WATCHDOG_ENABLE) || defined(DLT_SYSTEMD_ENABLE)
60 #include "sd-daemon.h"
64 \defgroup daemon DLT Daemon
69 /** Global text output buffer, mainly used for creation of error/warning strings */
70 static char str[DLT_DAEMON_TEXTBUFSIZE];
73 * Print usage information of tool.
77 char version[DLT_DAEMON_TEXTBUFSIZE];
78 dlt_get_version(version,DLT_DAEMON_TEXTBUFSIZE);
80 //printf("DLT logging daemon %s %s\n", _DLT_PACKAGE_VERSION, _DLT_PACKAGE_VERSION_STATE);
81 //printf("Compile options: %s %s %s %s",_DLT_SYSTEMD_ENABLE, _DLT_SYSTEMD_WATCHDOG_ENABLE, _DLT_TEST_ENABLE, _DLT_SHM_ENABLE);
82 printf("%s", version);
83 printf("Usage: dlt-daemon [options]\n");
85 printf(" -d Daemonize\n");
86 printf(" -h Usage\n");
87 printf(" -c filename DLT daemon configuration file (Default: /etc/dlt.conf)\n");
93 int option_handling(DltDaemonLocal *daemon_local,int argc, char* argv[])
99 fprintf (stderr, "Invalid parameter passed to option_handling()\n");
103 /* Initialize flags */
104 memset(daemon_local,0,sizeof(DltDaemonLocal));
108 while ((c = getopt (argc, argv, "hdc:")) != -1)
114 daemon_local->flags.dflag = 1;
119 strncpy(daemon_local->flags.cvalue,optarg,NAME_MAX);
125 return -2; /* return no error */
131 fprintf (stderr, "Option -%c requires an argument.\n", optopt);
133 else if (isprint (optopt))
135 fprintf (stderr, "Unknown option `-%c'.\n", optopt);
139 fprintf (stderr, "Unknown option character `\\x%x'.\n",optopt);
141 /* unknown or wrong option used, show usage information and terminate */
147 fprintf (stderr, "Invalid option, this should never occur!\n");
155 } /* option_handling() */
160 int option_file_parser(DltDaemonLocal *daemon_local)
163 int value_length = 1024;
164 char line[value_length-1];
165 char token[value_length];
166 char value[value_length];
168 const char *filename;
170 /* set default values for configuration */
171 daemon_local->flags.sharedMemorySize = DLT_SHM_SIZE;
172 daemon_local->flags.sendMessageTime = 0;
173 daemon_local->flags.offlineTraceDirectory[0] = 0;
174 daemon_local->flags.offlineTraceFileSize = 1000000;
175 daemon_local->flags.offlineTraceMaxSize = 0;
176 daemon_local->flags.loggingMode = 0;
177 daemon_local->flags.loggingLevel = 6;
178 strncpy(daemon_local->flags.loggingFilename, DLT_USER_DIR "/dlt.log",sizeof(daemon_local->flags.loggingFilename)-1);
179 daemon_local->flags.loggingFilename[sizeof(daemon_local->flags.loggingFilename)-1]=0;
180 daemon_local->timeoutOnSend = 4;
181 daemon_local->flags.sendECUSoftwareVersion = 0;
182 memset(daemon_local->flags.pathToECUSoftwareVersion, 0, sizeof(daemon_local->flags.pathToECUSoftwareVersion));
183 daemon_local->flags.sendTimezone = 0;
185 /* open configuration file */
186 if(daemon_local->flags.cvalue[0])
187 filename = daemon_local->flags.cvalue;
189 filename = "/etc/dlt.conf";
190 //printf("Load configuration from file: %s\n",filename);
191 pFile = fopen (filename,"r");
197 /* fetch line from configuration file */
198 if ( fgets (line , value_length - 1 , pFile) != NULL )
200 pch = strtok (line," =\r\n");
206 if(strcmp(pch,"#")==0)
211 strncpy(token,pch,sizeof(token) - 1);
212 token[sizeof(token) - 1]=0;
216 strncpy(value,pch,sizeof(value) - 1);
217 value[sizeof(value) - 1]=0;
221 pch = strtok (NULL, " =\r\n");
224 if(token[0] && value[0])
226 /* parse arguments here */
227 if(strcmp(token,"Verbose")==0)
229 daemon_local->flags.vflag = atoi(value);
230 //printf("Option: %s=%s\n",token,value);
232 else if(strcmp(token,"PrintASCII")==0)
234 daemon_local->flags.aflag = atoi(value);
235 //printf("Option: %s=%s\n",token,value);
237 else if(strcmp(token,"PrintHex")==0)
239 daemon_local->flags.xflag = atoi(value);
240 //printf("Option: %s=%s\n",token,value);
242 else if(strcmp(token,"PrintHeadersOnly")==0)
244 daemon_local->flags.sflag = atoi(value);
245 //printf("Option: %s=%s\n",token,value);
247 else if(strcmp(token,"SendSerialHeader")==0)
249 daemon_local->flags.lflag = atoi(value);
250 //printf("Option: %s=%s\n",token,value);
252 else if(strcmp(token,"SendContextRegistration")==0)
254 daemon_local->flags.rflag = atoi(value);
255 //printf("Option: %s=%s\n",token,value);
257 else if(strcmp(token,"SendMessageTime")==0)
259 daemon_local->flags.sendMessageTime = atoi(value);
260 //printf("Option: %s=%s\n",token,value);
262 else if(strcmp(token,"RS232SyncSerialHeader")==0)
264 daemon_local->flags.mflag = atoi(value);
265 //printf("Option: %s=%s\n",token,value);
267 else if(strcmp(token,"TCPSyncSerialHeader")==0)
269 daemon_local->flags.nflag = atoi(value);
270 //printf("Option: %s=%s\n",token,value);
272 else if(strcmp(token,"RS232DeviceName")==0)
274 strncpy(daemon_local->flags.yvalue,value,NAME_MAX);
275 daemon_local->flags.yvalue[NAME_MAX]=0;
276 //printf("Option: %s=%s\n",token,value);
278 else if(strcmp(token,"RS232Baudrate")==0)
280 strncpy(daemon_local->flags.bvalue,value,NAME_MAX);
281 daemon_local->flags.bvalue[NAME_MAX]=0;
282 //printf("Option: %s=%s\n",token,value);
284 else if(strcmp(token,"ECUId")==0)
286 strncpy(daemon_local->flags.evalue,value,NAME_MAX);
287 daemon_local->flags.evalue[NAME_MAX]=0;
288 //printf("Option: %s=%s\n",token,value);
290 else if(strcmp(token,"PersistanceStoragePath")==0)
292 strncpy(daemon_local->flags.ivalue,value,NAME_MAX);
293 daemon_local->flags.ivalue[NAME_MAX]=0;
294 //printf("Option: %s=%s\n",token,value);
296 else if(strcmp(token,"LoggingMode")==0)
298 daemon_local->flags.loggingMode = atoi(value);
299 //printf("Option: %s=%s\n",token,value);
301 else if(strcmp(token,"LoggingLevel")==0)
303 daemon_local->flags.loggingLevel = atoi(value);
304 //printf("Option: %s=%s\n",token,value);
306 else if(strcmp(token,"LoggingFilename")==0)
308 strncpy(daemon_local->flags.loggingFilename,value,sizeof(daemon_local->flags.loggingFilename) - 1);
309 daemon_local->flags.loggingFilename[sizeof(daemon_local->flags.loggingFilename) - 1]=0;
310 //printf("Option: %s=%s\n",token,value);
312 else if(strcmp(token,"TimeOutOnSend")==0)
314 daemon_local->timeoutOnSend = atoi(value);
315 //printf("Option: %s=%s\n",token,value);
317 else if(strcmp(token,"SharedMemorySize")==0)
319 daemon_local->flags.sharedMemorySize = atoi(value);
320 //printf("Option: %s=%s\n",token,value);
322 else if(strcmp(token,"OfflineTraceDirectory")==0)
324 strncpy(daemon_local->flags.offlineTraceDirectory,value,sizeof(daemon_local->flags.offlineTraceDirectory) - 1);
325 daemon_local->flags.offlineTraceDirectory[sizeof(daemon_local->flags.offlineTraceDirectory) - 1]=0;
326 //printf("Option: %s=%s\n",token,value);
328 else if(strcmp(token,"OfflineTraceFileSize")==0)
330 daemon_local->flags.offlineTraceFileSize = atoi(value);
331 //printf("Option: %s=%s\n",token,value);
333 else if(strcmp(token,"OfflineTraceMaxSize")==0)
335 daemon_local->flags.offlineTraceMaxSize = atoi(value);
336 //printf("Option: %s=%s\n",token,value);
338 else if(strcmp(token,"SendECUSoftwareVersion")==0)
340 daemon_local->flags.sendECUSoftwareVersion = atoi(value);
341 //printf("Option: %s=%s\n",token,value);
343 else if(strcmp(token,"PathToECUSoftwareVersion")==0)
345 strncpy(daemon_local->flags.pathToECUSoftwareVersion,value,sizeof(daemon_local->flags.pathToECUSoftwareVersion) - 1);
346 daemon_local->flags.pathToECUSoftwareVersion[sizeof(daemon_local->flags.pathToECUSoftwareVersion) - 1]=0;
347 //printf("Option: %s=%s\n",token,value);
349 else if(strcmp(token,"SendTimezone")==0)
351 daemon_local->flags.sendTimezone = atoi(value);
352 //printf("Option: %s=%s\n",token,value);
356 fprintf(stderr, "Unknown option: %s=%s\n",token,value);
369 fprintf(stderr, "Cannot open configuration file: %s\n",filename);
376 * Main function of tool.
378 int main(int argc, char* argv[])
380 char version[DLT_DAEMON_TEXTBUFSIZE];
381 DltDaemonLocal daemon_local;
385 /* Command line option handling */
386 if ((back = option_handling(&daemon_local,argc,argv))<0)
389 fprintf (stderr, "option_handling() failed!\n");
394 /* Configuration file option handling */
395 if ((back = option_file_parser(&daemon_local))<0)
398 fprintf (stderr, "option_file_parser() failed!\n");
403 /* Initialize internal logging facility */
404 dlt_log_set_filename(daemon_local.flags.loggingFilename);
405 dlt_log_set_level(daemon_local.flags.loggingLevel);
406 dlt_log_init(daemon_local.flags.loggingMode);
408 /* Print version information */
409 dlt_get_version(version,DLT_DAEMON_TEXTBUFSIZE);
411 snprintf(str,DLT_DAEMON_TEXTBUFSIZE,"Starting DLT Daemon; %s\n", version );
412 dlt_log(LOG_NOTICE, str);
414 PRINT_FUNCTION_VERBOSE(daemon_local.flags.vflag);
416 /* --- Daemon init phase 1 begin --- */
417 if (dlt_daemon_local_init_p1(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
419 dlt_log(LOG_CRIT,"Initialization of phase 1 failed!\n");
422 /* --- Daemon init phase 1 end --- */
424 /* --- Daemon connection init begin */
425 if (dlt_daemon_local_connection_init(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
427 dlt_log(LOG_CRIT,"Initialization of local connections failed!\n");
430 /* --- Daemon connection init end */
432 /* --- Daemon init phase 2 begin --- */
433 if (dlt_daemon_local_init_p2(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
435 dlt_log(LOG_CRIT,"Initialization of phase 2 failed!\n");
438 /* --- Daemon init phase 2 end --- */
440 // create fd for watchdog
441 #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE
443 char* watchdogUSec = getenv("WATCHDOG_USEC");
444 int watchdogTimeoutSeconds = 0;
446 dlt_log(LOG_DEBUG, "Systemd watchdog initialization\n");
449 watchdogTimeoutSeconds = atoi(watchdogUSec)/2000000;
451 create_timer_fd(&daemon_local, watchdogTimeoutSeconds, watchdogTimeoutSeconds, &daemon_local.timer_wd, "Systemd watchdog");
455 // create fd for timer timing packets
456 create_timer_fd(&daemon_local, 1, 1, &daemon_local.timer_one_s, "Timing packet");
458 // create fd for timer ecu version
459 if(daemon_local.flags.sendECUSoftwareVersion > 0 || daemon_local.flags.sendTimezone > 0)
461 //dlt_daemon_init_ecuversion(&daemon_local);
462 create_timer_fd(&daemon_local, 60, 60, &daemon_local.timer_sixty_s, "ECU version");
465 if(daemon_local.flags.yvalue[0] || (daemon_local.flags.offlineTraceDirectory[0]))
466 dlt_daemon_change_state(&daemon,DLT_DAEMON_STATE_SEND_DIRECT);
468 dlt_daemon_change_state(&daemon,DLT_DAEMON_STATE_BUFFER);
473 /* wait for events from all FIFO and sockets */
474 daemon_local.read_fds = daemon_local.master;
475 if (select(daemon_local.fdmax+1, &(daemon_local.read_fds), NULL, NULL, NULL) == -1)
478 /* retry if SIGINT was received, else error out */
479 if ( error != EINTR ) {
480 snprintf(str,DLT_DAEMON_TEXTBUFSIZE,"select() failed: %s\n", strerror(error) );
481 dlt_log(LOG_CRIT, str);
486 /* run through the existing FIFO and sockets to check for events */
487 for (i = 0; i <= daemon_local.fdmax; i++)
489 if (FD_ISSET(i, &(daemon_local.read_fds)))
491 if (i == daemon_local.sock && ((daemon.mode == DLT_USER_MODE_EXTERNAL) || (daemon.mode == DLT_USER_MODE_BOTH)))
493 /* event from TCP server socket, new connection */
494 if (dlt_daemon_process_client_connect(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
496 dlt_log(LOG_CRIT,"Connect to dlt client failed!\n");
500 else if (i == daemon_local.fp)
502 /* event from the FIFO happened */
503 if (dlt_daemon_process_user_messages(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
505 dlt_log(LOG_CRIT,"Processing of messages from user connection failed!\n");
509 else if ((i == daemon_local.fdserial) && (daemon_local.flags.yvalue[0]))
511 /* event from serial connection to client received */
512 if (dlt_daemon_process_client_messages_serial(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
514 dlt_log(LOG_CRIT,"Processing of messages from serial connection failed!\n");
518 #ifdef DLT_SYSTEMD_WATCHDOG_ENABLE
519 else if (i == daemon_local.timer_wd)
522 ssize_t res = read(daemon_local.timer_wd, &expir, sizeof(expir));
524 snprintf(str,DLT_DAEMON_TEXTBUFSIZE,"Failed to read timer_wd; %s\n", strerror(errno) );
525 dlt_log(LOG_WARNING, str);
526 // Activity received on timer_wd, but unable to read the fd:
527 // let's go on sending notification
530 dlt_log(LOG_DEBUG, "Timer watchdog\n");
532 if(sd_notify(0, "WATCHDOG=1") < 0)
534 dlt_log(LOG_CRIT, "Could not reset systemd watchdog\n");
538 else if (i == daemon_local.timer_one_s)
541 ssize_t res = read(daemon_local.timer_one_s, &expir, sizeof(expir));
543 snprintf(str,DLT_DAEMON_TEXTBUFSIZE,"Failed to read timer_timingpacket; %s\n", strerror(errno) );
544 dlt_log(LOG_WARNING, str);
545 // Activity received on timer_wd, but unable to read the fd:
546 // let's go on sending notification
548 if(daemon.state == DLT_DAEMON_STATE_SEND_BUFFER || daemon.state == DLT_DAEMON_STATE_BUFFER_FULL)
550 if (dlt_daemon_send_ringbuffer_to_client(&daemon, &daemon_local, daemon_local.flags.vflag))
552 dlt_log(LOG_DEBUG,"Can't send contents of ringbuffer to clients\n");
555 if (daemon.timingpackets && daemon.state == DLT_DAEMON_STATE_SEND_DIRECT)
557 dlt_daemon_control_message_time(DLT_DAEMON_SEND_TO_ALL, &daemon, &daemon_local, daemon_local.flags.vflag);
559 dlt_log(LOG_DEBUG, "Timer timingpacket\n");
563 else if (i == daemon_local.timer_sixty_s)
566 ssize_t res = read(daemon_local.timer_sixty_s, &expir, sizeof(expir));
568 snprintf(str,DLT_DAEMON_TEXTBUFSIZE,"Failed to read timer_ecuversion; %s\n", strerror(errno) );
569 dlt_log(LOG_WARNING, str);
570 // Activity received on timer_wd, but unable to read the fd:
571 // let's go on sending notification
573 if(daemon_local.flags.sendECUSoftwareVersion > 0)
574 dlt_daemon_control_get_software_version(DLT_DAEMON_SEND_TO_ALL, &daemon,&daemon_local, daemon_local.flags.vflag);
576 if(daemon_local.flags.sendTimezone > 0)
578 dlt_daemon_control_message_timezone(DLT_DAEMON_SEND_TO_ALL,&daemon,&daemon_local,daemon_local.flags.vflag);
580 dlt_log(LOG_DEBUG, "Timer ecuversion\n");
585 /* event from tcp connection to client received */
586 daemon_local.receiverSock.fd = i;
587 if (dlt_daemon_process_client_messages(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
589 dlt_log(LOG_CRIT,"Processing of messages from client connection failed!\n");
597 dlt_daemon_local_cleanup(&daemon, &daemon_local, daemon_local.flags.vflag);
599 dlt_log(LOG_NOTICE, "Leaving DLT daemon\n");
605 int dlt_daemon_local_init_p1(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
609 PRINT_FUNCTION_VERBOSE(verbose);
611 if ((daemon==0) || (daemon_local==0))
613 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_local_init_p1()\n");
617 #if defined(DLT_SYSTEMD_WATCHDOG_ENABLE) || defined(DLT_SYSTEMD_ENABLE)
621 dlt_log(LOG_CRIT, "system not booted with systemd!\n");
626 dlt_log(LOG_CRIT, "sd_booted failed!\n");
631 dlt_log(LOG_INFO, "system booted with systemd\n");
635 /* create dlt pipes directory */
636 ret=mkdir(DLT_USER_DIR, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH | S_ISVTX );
637 if (ret==-1 && errno != EEXIST)
639 snprintf(str,DLT_DAEMON_TEXTBUFSIZE,"FIFO user dir %s cannot be created!\n", DLT_USER_DIR);
640 dlt_log(LOG_ERR, str);
644 // S_ISGID cannot be set by mkdir, let's reassign right bits
645 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 );
648 snprintf(str,DLT_DAEMON_TEXTBUFSIZE,"FIFO user dir %s cannot be chmoded!\n", DLT_USER_DIR);
649 dlt_log(LOG_ERR, str);
653 /* Check for daemon mode */
654 if (daemon_local->flags.dflag)
656 dlt_daemon_daemonize(daemon_local->flags.vflag);
659 /* initialise structure to use DLT file */
660 if (dlt_file_init(&(daemon_local->file),daemon_local->flags.vflag)==-1)
662 dlt_log(LOG_ERR,"Could not initialize file structure\n");
663 /* Return value ignored, dlt daemon will exit */
664 dlt_file_free(&(daemon_local->file),daemon_local->flags.vflag);
668 signal(SIGPIPE,SIG_IGN);
670 signal(SIGTERM, dlt_daemon_signal_handler); /* software termination signal from kill */
671 signal(SIGHUP, dlt_daemon_signal_handler); /* hangup signal */
672 signal(SIGQUIT, dlt_daemon_signal_handler);
673 signal(SIGINT, dlt_daemon_signal_handler);
678 int dlt_daemon_local_init_p2(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
680 PRINT_FUNCTION_VERBOSE(verbose);
682 if ((daemon==0) || (daemon_local==0))
684 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_local_init_p2()\n");
689 if (dlt_daemon_init(daemon,daemon_local->flags.ivalue,daemon_local->flags.vflag)==-1)
691 dlt_log(LOG_ERR,"Could not initialize daemon data\n");
695 /* init offline trace */
696 if(((daemon->mode == DLT_USER_MODE_INTERNAL) || (daemon->mode == DLT_USER_MODE_BOTH)) && daemon_local->flags.offlineTraceDirectory[0])
698 if (dlt_offline_trace_init(&(daemon_local->offlineTrace),daemon_local->flags.offlineTraceDirectory,daemon_local->flags.offlineTraceFileSize,daemon_local->flags.offlineTraceMaxSize)==-1)
700 dlt_log(LOG_ERR,"Could not initialize offline trace\n");
705 /* Set ECU id of daemon */
706 if (daemon_local->flags.evalue[0])
708 dlt_set_id(daemon->ecuid,daemon_local->flags.evalue);
712 dlt_set_id(daemon->ecuid,DLT_DAEMON_ECU_ID);
715 /* Set flag for optional sending of serial header */
716 daemon->sendserialheader = daemon_local->flags.lflag;
718 #ifdef DLT_SHM_ENABLE
719 /* init shared memory */
720 if (dlt_shm_init_server(&(daemon_local->dlt_shm),DLT_SHM_KEY,daemon_local->flags.sharedMemorySize)==-1)
722 dlt_log(LOG_ERR,"Could not initialize shared memory\n");
727 /* prepare main loop */
728 if (dlt_message_init(&(daemon_local->msg),daemon_local->flags.vflag)==-1)
730 dlt_log(LOG_ERR,"Could not initialize message\n");
734 if (dlt_receiver_init(&(daemon_local->receiver),daemon_local->fp,DLT_DAEMON_RCVBUFSIZE)==-1)
736 dlt_log(LOG_ERR,"Could not initialize receiver\n");
739 if (dlt_receiver_init(&(daemon_local->receiverSock),daemon_local->sock,DLT_DAEMON_RCVBUFSIZESOCK)==-1)
741 dlt_log(LOG_ERR,"Could not initialize receiver for socket\n");
744 if (daemon_local->flags.yvalue[0])
746 if (dlt_receiver_init(&(daemon_local->receiverSerial),daemon_local->fdserial,DLT_DAEMON_RCVBUFSIZESERIAL)==-1)
748 dlt_log(LOG_ERR,"Could not initialize receiver for serial connection\n");
753 /* configure sending timing packets */
754 if (daemon_local->flags.sendMessageTime)
756 daemon->timingpackets = 1;
759 /* Binary semaphore for thread */
760 if (sem_init(&dlt_daemon_mutex, 0, 1)==-1)
762 dlt_log(LOG_ERR,"Could not initialize binary semaphore\n");
766 /* Get ECU version info from a file. If it fails, use dlt_version as fallback. */
767 if(dlt_daemon_local_ecu_version_init(daemon, daemon_local, daemon_local->flags.vflag) < 0)
769 daemon->ECUVersionString = malloc(DLT_DAEMON_TEXTBUFSIZE);
770 if(daemon->ECUVersionString==0)
772 dlt_log(LOG_ERR,"Could not allocate memory for version string\n");
775 dlt_get_version(daemon->ECUVersionString,DLT_DAEMON_TEXTBUFSIZE);
781 int dlt_daemon_local_connection_init(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
785 PRINT_FUNCTION_VERBOSE(verbose);
787 if ((daemon==0) || (daemon_local==0))
789 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_local_connection_init()\n");
793 /* open named pipe(FIFO) to receive DLT messages from users */
796 /* Try to delete existing pipe, ignore result of unlink */
797 unlink(DLT_USER_FIFO);
799 ret=mkfifo(DLT_USER_FIFO, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP );
802 snprintf(str,DLT_DAEMON_TEXTBUFSIZE,"FIFO user %s cannot be created!\n",DLT_USER_FIFO);
803 dlt_log(LOG_ERR, str);
807 daemon_local->fp = open(DLT_USER_FIFO, O_RDWR);
808 if (daemon_local->fp==-1)
810 snprintf(str,DLT_DAEMON_TEXTBUFSIZE,"FIFO user %s cannot be opened!\n",DLT_USER_FIFO);
811 dlt_log(LOG_ERR, str);
815 /* create and open socket to receive incoming connections from client */
816 if(dlt_daemon_socket_open(&(daemon_local->sock)))
819 /* prepare usage of select(), add FIFO and receiving socket */
820 FD_ZERO(&(daemon_local->master));
821 FD_ZERO(&(daemon_local->read_fds));
822 FD_SET(daemon_local->sock, &(daemon_local->master));
824 daemon_local->fdmax = daemon_local->sock;
826 FD_SET(daemon_local->fp, &(daemon_local->master));
828 if (daemon_local->fp > daemon_local->fdmax)
830 daemon_local->fdmax = daemon_local->fp;
833 if (daemon_local->flags.yvalue[0])
835 /* create and open serial connection from/to client */
836 /* open serial connection */
837 daemon_local->fdserial=open(daemon_local->flags.yvalue,O_RDWR);
838 if (daemon_local->fdserial<0)
840 snprintf(str,DLT_DAEMON_TEXTBUFSIZE,"Failed to open serial device %s\n", daemon_local->flags.yvalue);
841 daemon_local->flags.yvalue[0] = 0;
842 dlt_log(LOG_ERR, str);
846 if (isatty(daemon_local->fdserial))
848 if (daemon_local->flags.bvalue[0])
850 daemon_local->baudrate = dlt_convert_serial_speed(atoi(daemon_local->flags.bvalue));
854 daemon_local->baudrate = dlt_convert_serial_speed(DLT_DAEMON_SERIAL_DEFAULT_BAUDRATE);
857 if (dlt_setup_serial(daemon_local->fdserial,daemon_local->baudrate)<0)
859 close(daemon_local->fdserial);
860 snprintf(str,DLT_DAEMON_TEXTBUFSIZE,"Failed to configure serial device %s (%s) \n", daemon_local->flags.yvalue, strerror(errno));
861 daemon_local->flags.yvalue[0] = 0;
862 dlt_log(LOG_ERR, str);
866 FD_SET(daemon_local->fdserial, &(daemon_local->master));
868 if (daemon_local->fdserial > daemon_local->fdmax)
870 daemon_local->fdmax = daemon_local->fdserial;
873 if (daemon_local->flags.vflag)
875 dlt_log(LOG_INFO, "Serial init done\n");
880 close(daemon_local->fdserial);
881 fprintf(stderr,"Device is not a serial device, device = %s (%s) \n", daemon_local->flags.yvalue, strerror(errno));
882 daemon_local->flags.yvalue[0] = 0;
890 int dlt_daemon_local_ecu_version_init(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
892 char *version = NULL;
895 PRINT_FUNCTION_VERBOSE(verbose);
897 /* By default, version string is null. */
898 daemon->ECUVersionString = NULL;
900 /* Open the file. Bail out if error occurs */
901 f = fopen(daemon_local->flags.pathToECUSoftwareVersion, "r");
904 /* Error level notice, because this might be deliberate choice */
905 dlt_log(LOG_NOTICE, "Failed to open ECU Software version file.\n");
909 /* Get the file size. Bail out if stat fails. */
912 if(fstat(fd, &s_buf) < 0)
914 dlt_log(LOG_ERR, "Failed to stat ECU Software version file.\n");
919 /* Bail out if file is too large. Use DLT_DAEMON_TEXTBUFSIZE max.
920 * Reserve one byte for trailing '\0' */
921 off_t size = s_buf.st_size;
922 if(size >= DLT_DAEMON_TEXTBUFSIZE)
924 dlt_log(LOG_ERR, "Too large file for ECU version.\n");
929 /* Allocate permanent buffer for version info */
930 version = malloc(size + 1);
933 dlt_log(LOG_ERR, "Cannot allocate memory for ECU version.\n");
940 offset += fread(version + offset, 1, size, f);
943 dlt_log(LOG_ERR, "Failed to read ECU Software version file.\n");
950 dlt_log(LOG_ERR, "Too long file for ECU Software version info.\n");
956 version[offset] = '\0';//append null termination at end of version string
957 daemon->ECUVersionString = version;
962 void dlt_daemon_local_cleanup(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
964 PRINT_FUNCTION_VERBOSE(verbose);
966 if ((daemon==0) || (daemon_local==0))
968 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_local_cleanup()\n");
973 dlt_receiver_free(&(daemon_local->receiver));
975 dlt_receiver_free(&(daemon_local->receiverSock));
978 dlt_message_free(&(daemon_local->msg),daemon_local->flags.vflag);
979 close(daemon_local->fp);
981 /* free shared memory */
982 if(daemon_local->flags.offlineTraceDirectory[0])
983 dlt_offline_trace_free(&(daemon_local->offlineTrace));
985 if (daemon_local->flags.ovalue[0])
987 close(daemon_local->ohandle);
992 dlt_file_free(&(daemon_local->file),daemon_local->flags.vflag);
994 /* Try to delete existing pipe, ignore result of unlink() */
995 unlink(DLT_USER_FIFO);
997 #ifdef DLT_SHM_ENABLE
998 /* free shared memory */
999 dlt_shm_free_server(&(daemon_local->dlt_shm));
1002 /* Try to delete lock file, ignore result of unlink() */
1003 unlink(DLT_DAEMON_LOCK_FILE);
1006 void dlt_daemon_signal_handler(int sig)
1015 /* finalize the server */
1016 snprintf(str,DLT_DAEMON_TEXTBUFSIZE,"Exiting DLT daemon due to signal: %s\n", strsignal(sig) );
1017 dlt_log(LOG_NOTICE, str);
1019 /* Try to delete existing pipe, ignore result of unlink() */
1020 unlink(DLT_USER_FIFO);
1022 /* Try to delete lock file, ignore result of unlink() */
1023 unlink(DLT_DAEMON_LOCK_FILE);
1025 /* Terminate program */
1031 dlt_log(LOG_CRIT, "This case should never happen!");
1035 } /* dlt_daemon_signal_handler() */
1037 void dlt_daemon_daemonize(int verbose)
1042 PRINT_FUNCTION_VERBOSE(verbose);
1044 dlt_log(LOG_NOTICE, "Daemon mode\n");
1050 dlt_log(LOG_CRIT, "Unable to fork(), exiting DLT daemon\n");
1051 exit(-1); /* fork error */
1056 exit(0); /* parent exits */
1058 /* child (daemon) continues */
1060 /* Process independency */
1062 /* obtain a new process group */
1065 dlt_log(LOG_CRIT, "setsid() failed, exiting DLT daemon\n");
1066 exit(-1); /* fork error */
1069 /* Close descriptors */
1070 for (i=getdtablesize();i>=0;--i)
1072 close(i); /* close all descriptors */
1075 /* Open standard descriptors stdin, stdout, stderr */
1076 i=open("/dev/null",O_RDWR); /* open stdin */
1080 dlt_log(LOG_ERR, "Failed to direct stdout to /dev/null.\n");/* stdout */
1082 dlt_log(LOG_ERR, "Failed to direct stderr to /dev/null.\n"); /* stderr */
1086 umask(DLT_DAEMON_UMASK);
1088 /* Change to known directory */
1089 if(chdir(DLT_USER_DIR) < 0)
1090 dlt_log(LOG_ERR, "Failed to chdir to DLT_USER_DIR.\n");;
1092 /* Ensure single copy of daemon;
1093 run only one instance at a time */
1094 lfp=open(DLT_DAEMON_LOCK_FILE,O_RDWR|O_CREAT,DLT_DAEMON_LOCK_FILE_PERM);
1097 dlt_log(LOG_CRIT, "can't open lock file, exiting DLT daemon\n");
1098 exit(-1); /* can not open */
1100 if (lockf(lfp,F_TLOCK,0)<0)
1102 dlt_log(LOG_CRIT, "can't lock lock file, exiting DLT daemon\n");
1103 exit(-1); /* can not lock */
1105 /* only first instance continues */
1107 snprintf(str,DLT_DAEMON_TEXTBUFSIZE,"%d\n",getpid());
1108 pid_len = strlen(str);
1109 if(write(lfp,str,pid_len) != pid_len) /* record pid to lockfile */
1110 dlt_log(LOG_ERR, "Could not write pid to file in dlt_daemon_daemonize.\n");
1113 signal(SIGCHLD,SIG_IGN); /* ignore child */
1114 signal(SIGTSTP,SIG_IGN); /* ignore tty signals */
1115 signal(SIGTTOU,SIG_IGN);
1116 signal(SIGTTIN,SIG_IGN);
1118 } /* dlt_daemon_daemonize() */
1120 int dlt_daemon_process_client_connect(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1123 struct sockaddr cli;
1127 PRINT_FUNCTION_VERBOSE(verbose);
1129 if ((daemon==0) || (daemon_local==0))
1131 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_client_connect()\n");
1135 /* event from TCP server socket, new connection */
1136 cli_size = sizeof(cli);
1137 if ((in_sock = accept(daemon_local->sock,&cli, &cli_size)) < 0)
1139 dlt_log(LOG_ERR, "accept() failed!\n");
1143 /* check if file file descriptor was already used, and make it invalid if it is reused */
1144 /* This prevents sending messages to wrong file descriptor */
1145 dlt_daemon_applications_invalidate_fd(daemon,in_sock,verbose);
1146 dlt_daemon_contexts_invalidate_fd(daemon,in_sock,verbose);
1148 /* Set socket timeout in reception */
1149 struct timeval timeout_send;
1150 timeout_send.tv_sec = daemon_local->timeoutOnSend;
1151 timeout_send.tv_usec = 0;
1152 if (setsockopt (in_sock, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout_send, sizeof(timeout_send)) < 0)
1153 dlt_log(LOG_ERR, "setsockopt failed\n");
1155 /* Set to non blocking mode */
1156 //flags = fcntl(in_sock, F_GETFL, 0);
1157 //fcntl(in_sock, F_SETFL, flags | O_NONBLOCK);
1159 //snprintf(str,DLT_DAEMON_TEXTBUFSIZE,"Client Connection from %s\n", inet_ntoa(cli.sin_addr));
1161 FD_SET(in_sock, &(daemon_local->master)); /* add to master set */
1162 if (in_sock > daemon_local->fdmax)
1164 /* keep track of the maximum */
1165 daemon_local->fdmax = in_sock;
1168 daemon_local->client_connections++;
1169 if (daemon_local->flags.vflag)
1171 snprintf(str,DLT_DAEMON_TEXTBUFSIZE, "New connection to client established, #connections: %d\n",daemon_local->client_connections);
1172 dlt_log(LOG_INFO, str);
1175 // send connection info about connected
1176 dlt_daemon_control_message_connection_info(in_sock,daemon,daemon_local,DLT_CONNECTION_STATUS_CONNECTED,"",verbose);
1178 // send ecu version string
1179 if(daemon_local->flags.sendECUSoftwareVersion > 0)
1181 if(daemon_local->flags.sendECUSoftwareVersion > 0)
1182 dlt_daemon_control_get_software_version(DLT_DAEMON_SEND_TO_ALL, daemon,daemon_local, daemon_local->flags.vflag);
1184 if(daemon_local->flags.sendTimezone > 0)
1186 dlt_daemon_control_message_timezone(DLT_DAEMON_SEND_TO_ALL,daemon,daemon_local,daemon_local->flags.vflag);
1190 if (daemon_local->client_connections==1)
1192 if (daemon_local->flags.vflag)
1194 dlt_log(LOG_INFO, "Send ring-buffer to client\n");
1196 dlt_daemon_change_state(daemon, DLT_DAEMON_STATE_SEND_BUFFER);
1197 if (dlt_daemon_send_ringbuffer_to_client(daemon, daemon_local, verbose)==-1)
1199 dlt_log(LOG_ERR,"Can't send contents of ringbuffer to clients\n");
1203 /* send new log state to all applications */
1204 daemon->connectionState = 1;
1205 dlt_daemon_user_send_all_log_state(daemon,verbose);
1211 int dlt_daemon_process_client_messages(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1213 int bytes_to_be_removed=0;
1215 PRINT_FUNCTION_VERBOSE(verbose);
1217 if ((daemon==0) || (daemon_local==0))
1219 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_client_messages()\n");
1223 if (dlt_receiver_receive_socket(&(daemon_local->receiverSock))<=0)
1225 dlt_daemon_close_socket(daemon_local->receiverSock.fd, daemon, daemon_local, verbose);
1226 daemon_local->receiverSock.fd = -1;
1227 /* check: return 0; */
1230 /* Process all received messages */
1231 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)
1233 /* Check for control message */
1234 if ( 0 < daemon_local->receiverSock.fd && DLT_MSG_IS_CONTROL_REQUEST(&(daemon_local->msg)) )
1236 dlt_daemon_client_process_control(daemon_local->receiverSock.fd, daemon,daemon_local, &(daemon_local->msg), daemon_local->flags.vflag);
1239 bytes_to_be_removed = daemon_local->msg.headersize+daemon_local->msg.datasize-sizeof(DltStorageHeader);
1240 if (daemon_local->msg.found_serialheader)
1242 bytes_to_be_removed += sizeof(dltSerialHeader);
1244 if (daemon_local->msg.resync_offset)
1246 bytes_to_be_removed += daemon_local->msg.resync_offset;
1249 if (dlt_receiver_remove(&(daemon_local->receiverSock),bytes_to_be_removed)==-1)
1251 dlt_log(LOG_ERR,"Can't remove bytes from receiver for sockets\n");
1258 if (dlt_receiver_move_to_begin(&(daemon_local->receiverSock))==-1)
1260 dlt_log(LOG_ERR,"Can't move bytes to beginning of receiver buffer for sockets\n");
1267 int dlt_daemon_process_client_messages_serial(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1269 int bytes_to_be_removed=0;
1271 PRINT_FUNCTION_VERBOSE(verbose);
1273 if ((daemon==0) || (daemon_local==0))
1275 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_client_messages_serial()\n");
1279 if (dlt_receiver_receive_fd(&(daemon_local->receiverSerial))<=0)
1281 dlt_log(LOG_ERR, "dlt_receiver_receive_fd() for messages from serial interface failed!\n");
1285 /* Process all received messages */
1286 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)
1288 /* Check for control message */
1289 if (DLT_MSG_IS_CONTROL_REQUEST(&(daemon_local->msg)))
1291 if (dlt_daemon_client_process_control(daemon_local->receiverSerial.fd, daemon,daemon_local, &(daemon_local->msg), daemon_local->flags.vflag)==-1)
1293 dlt_log(LOG_ERR,"Can't process control messages\n");
1298 bytes_to_be_removed = daemon_local->msg.headersize+daemon_local->msg.datasize-sizeof(DltStorageHeader);
1299 if (daemon_local->msg.found_serialheader)
1301 bytes_to_be_removed += sizeof(dltSerialHeader);
1303 if (daemon_local->msg.resync_offset)
1305 bytes_to_be_removed += daemon_local->msg.resync_offset;
1308 if (dlt_receiver_remove(&(daemon_local->receiverSerial),bytes_to_be_removed)==-1)
1310 dlt_log(LOG_ERR,"Can't remove bytes from receiver for serial connection\n");
1317 if (dlt_receiver_move_to_begin(&(daemon_local->receiverSerial))==-1)
1319 dlt_log(LOG_ERR,"Can't move bytes to beginning of receiver buffer for serial connection\n");
1326 int dlt_daemon_process_user_messages(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1330 DltUserHeader *userheader;
1332 PRINT_FUNCTION_VERBOSE(verbose);
1334 if ((daemon==0) || (daemon_local==0))
1336 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_messages()\n");
1340 /* read data from FIFO */
1341 if (dlt_receiver_receive_fd(&(daemon_local->receiver))<0)
1343 dlt_log(LOG_ERR, "dlt_receiver_receive_fd() for user messages failed!\n");
1347 /* look through buffer as long as data is in there */
1350 if (daemon_local->receiver.bytesRcvd < (int32_t)sizeof(DltUserHeader))
1355 /* resync if necessary */
1359 userheader = (DltUserHeader*) (daemon_local->receiver.buf+offset);
1361 /* Check for user header pattern */
1362 if (dlt_user_check_userheader(userheader))
1370 while ((int32_t)(sizeof(DltUserHeader)+offset)<=daemon_local->receiver.bytesRcvd);
1372 /* Check for user header pattern */
1373 if (dlt_user_check_userheader(userheader)==0)
1378 /* Set new start offset */
1381 daemon_local->receiver.buf+=offset;
1382 daemon_local->receiver.bytesRcvd-=offset;
1385 switch (userheader->message)
1387 case DLT_USER_MESSAGE_OVERFLOW:
1389 if (dlt_daemon_process_user_message_overflow(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1395 case DLT_USER_MESSAGE_REGISTER_CONTEXT:
1397 if (dlt_daemon_process_user_message_register_context(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1403 case DLT_USER_MESSAGE_UNREGISTER_CONTEXT:
1405 if (dlt_daemon_process_user_message_unregister_context(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1411 case DLT_USER_MESSAGE_LOG:
1413 if (dlt_daemon_process_user_message_log(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1419 #ifdef DLT_SHM_ENABLE
1420 case DLT_USER_MESSAGE_LOG_SHM:
1422 if (dlt_daemon_process_user_message_log_shm(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1429 case DLT_USER_MESSAGE_REGISTER_APPLICATION:
1431 if (dlt_daemon_process_user_message_register_application(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1437 case DLT_USER_MESSAGE_UNREGISTER_APPLICATION:
1439 if (dlt_daemon_process_user_message_unregister_application(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1445 case DLT_USER_MESSAGE_APP_LL_TS:
1447 if (dlt_daemon_process_user_message_set_app_ll_ts(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1453 case DLT_USER_MESSAGE_LOG_MODE:
1455 if (dlt_daemon_process_user_message_log_mode(daemon, daemon_local, daemon_local->flags.vflag)==-1)
1463 dlt_log(LOG_ERR,"(Internal) Invalid user message type received!\n");
1465 /* remove user header */
1466 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader))==-1)
1468 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user messages\n");
1472 /* In next invocation of do-while loop, a resync will be triggered if additional data was received */
1482 /* keep not read data in buffer */
1483 if (dlt_receiver_move_to_begin(&(daemon_local->receiver))==-1)
1485 dlt_log(LOG_ERR,"Can't move bytes to beginning of receiver buffer for user messages\n");
1492 int dlt_daemon_process_user_message_overflow(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1495 DltUserControlMsgBufferOverflow *userpayload;
1497 PRINT_FUNCTION_VERBOSE(verbose);
1499 if ((daemon==0) || (daemon_local==0))
1501 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_overflow()\n");
1505 if (daemon_local->receiver.bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgBufferOverflow)))
1507 /* Not enough bytes received */
1511 /* get the payload of the user message */
1512 userpayload = (DltUserControlMsgBufferOverflow*) (daemon_local->receiver.buf+sizeof(DltUserHeader));
1514 /* Store in daemon, that a message buffer overflow has occured */
1515 /* look if TCP connection to client is available or it least message can be put into buffer */
1516 if((ret=dlt_daemon_control_message_buffer_overflow(DLT_DAEMON_SEND_TO_ALL, daemon,daemon_local, userpayload->overflow_counter,userpayload->apid,verbose)))
1518 /* there was an error when storing message */
1519 /* add the counter of lost messages to the daemon counter */
1520 daemon->overflow_counter+=userpayload->overflow_counter;
1523 /* keep not read data in buffer */
1524 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgBufferOverflow))==-1)
1526 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message overflow\n");
1533 int dlt_daemon_send_message_overflow(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1536 PRINT_FUNCTION_VERBOSE(verbose);
1538 if ((daemon==0) || (daemon_local==0))
1540 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_overflow()\n");
1541 return DLT_DAEMON_ERROR_UNKNOWN;
1544 /* Store in daemon, that a message buffer overflow has occured */
1545 if((ret=dlt_daemon_control_message_buffer_overflow(DLT_DAEMON_SEND_TO_ALL, daemon,daemon_local,daemon->overflow_counter,"", verbose)))
1550 return DLT_DAEMON_ERROR_OK;
1553 int dlt_daemon_process_user_message_register_application(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1556 DltDaemonApplication *application;
1557 char description[DLT_DAEMON_DESCSIZE+1];
1558 DltUserControlMsgRegisterApplication *usercontext;
1560 PRINT_FUNCTION_VERBOSE(verbose);
1562 if ((daemon==0) || (daemon_local==0))
1564 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_register_application()\n");
1568 if (daemon_local->receiver.bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterApplication)))
1570 /* Not enough bytes received */
1574 usercontext = (DltUserControlMsgRegisterApplication*) (daemon_local->receiver.buf+sizeof(DltUserHeader));
1576 memset(description,0,sizeof(description));
1578 len=usercontext->description_length;
1579 if ((len>0) && (len<=DLT_DAEMON_DESCSIZE))
1581 /* Read and store application description */
1582 strncpy(description, (daemon_local->receiver.buf+sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterApplication)), len);
1583 description[sizeof(description)-1]=0;
1587 application=dlt_daemon_application_add(daemon,usercontext->apid,usercontext->pid,description,verbose);
1589 /* send log state to new application */
1590 dlt_daemon_user_send_log_state(daemon,application,verbose);
1592 /* keep not read data in buffer */
1593 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterApplication)+len)==-1)
1595 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register application\n");
1601 dlt_log(LOG_CRIT,"Can't add application");
1608 int dlt_daemon_process_user_message_register_context(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1611 int8_t loglevel, tracestatus;
1612 DltUserControlMsgRegisterContext *usercontext;
1613 char description[DLT_DAEMON_DESCSIZE+1];
1614 DltDaemonApplication *application;
1615 DltDaemonContext *context;
1616 DltServiceGetLogInfoRequest *req;
1620 PRINT_FUNCTION_VERBOSE(verbose);
1622 if ((daemon==0) || (daemon_local==0))
1624 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_register_context()\n");
1628 if (daemon_local->receiver.bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)))
1630 /* Not enough bytes received */
1634 usercontext = (DltUserControlMsgRegisterContext*) (daemon_local->receiver.buf+sizeof(DltUserHeader));
1636 memset(description,0,sizeof(description));
1638 len=usercontext->description_length;
1639 if ((len>0) && (len<=DLT_DAEMON_DESCSIZE))
1641 /* Read and store context description */
1642 strncpy(description, (daemon_local->receiver.buf+sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)), len);
1643 description[sizeof(description)-1]=0;
1646 application = dlt_daemon_application_find(daemon,usercontext->apid,verbose);
1650 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)+len)==-1)
1652 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register context\n");
1655 dlt_log(LOG_ERR, "Application not found in dlt_daemon_process_user_message_register_context()\n");
1659 /* Pre-set loglevel */
1660 if (usercontext->log_level == DLT_USER_LOG_LEVEL_NOT_SET)
1662 loglevel=DLT_LOG_DEFAULT;
1666 loglevel=usercontext->log_level;
1667 /* Plausibility check */
1668 if ((loglevel<DLT_LOG_DEFAULT) || (loglevel>DLT_LOG_VERBOSE))
1670 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)+len)==-1)
1672 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register context\n");
1678 /* Pre-set tracestatus */
1679 if (usercontext->trace_status == DLT_USER_TRACE_STATUS_NOT_SET)
1681 tracestatus=DLT_TRACE_STATUS_DEFAULT;
1685 tracestatus=usercontext->trace_status;
1687 /* Plausibility check */
1688 if ((tracestatus<DLT_TRACE_STATUS_DEFAULT) || (tracestatus>DLT_TRACE_STATUS_ON))
1690 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)+len)==-1)
1692 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register context\n");
1698 context = dlt_daemon_context_add(daemon,usercontext->apid,usercontext->ctid, loglevel, tracestatus, usercontext->log_level_pos,application->user_handle,description,verbose);
1702 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)+len)==-1)
1704 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register context\n");
1707 dlt_log(LOG_CRIT,"Can't add context");
1710 /* Create automatic get log info response for registered context */
1711 if (daemon_local->flags.rflag)
1713 /* Prepare request for get log info with one application and one context */
1714 if (dlt_message_init(&msg, verbose)==-1)
1716 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)+len)==-1)
1718 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register context\n");
1721 dlt_log(LOG_ERR,"Can't initialize message");
1725 msg.datasize = sizeof(DltServiceGetLogInfoRequest);
1726 if (msg.databuffer && (msg.databuffersize < msg.datasize))
1728 free(msg.databuffer);
1731 if (msg.databuffer == 0){
1732 msg.databuffer = (uint8_t *) malloc(msg.datasize);
1733 msg.databuffersize = msg.datasize;
1735 if (msg.databuffer==0)
1737 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)+len)==-1)
1739 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register context\n");
1742 dlt_log(LOG_ERR,"Can't allocate buffer for get log info message\n");
1746 req = (DltServiceGetLogInfoRequest*) msg.databuffer;
1748 req->service_id = DLT_SERVICE_ID_GET_LOG_INFO;
1750 dlt_set_id(req->apid, usercontext->apid);
1751 dlt_set_id(req->ctid, usercontext->ctid);
1752 dlt_set_id(req->com,"remo");
1754 dlt_daemon_control_get_log_info(DLT_DAEMON_SEND_TO_ALL , daemon,daemon_local, &msg, verbose);
1756 dlt_message_free(&msg, verbose);
1759 if (context->user_handle >= DLT_FD_MINIMUM)
1761 /* This call also replaces the default values with the values defined for default */
1762 if (dlt_daemon_user_send_log_level(daemon, context, verbose)==-1)
1764 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)+len)==-1)
1766 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register context\n");
1769 dlt_log(LOG_ERR,"Can't send current log level as response to user message register context\n");
1774 /* keep not read data in buffer */
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");
1784 int dlt_daemon_process_user_message_unregister_application(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1786 DltUserControlMsgUnregisterApplication *usercontext;
1787 DltDaemonApplication *application;
1788 DltDaemonContext *context;
1791 PRINT_FUNCTION_VERBOSE(verbose);
1793 if ((daemon==0) || (daemon_local==0))
1795 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_unregister_application()\n");
1799 if (daemon_local->receiver.bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgUnregisterApplication)))
1801 /* Not enough bytes received */
1805 if (daemon->num_applications>0)
1807 usercontext = (DltUserControlMsgUnregisterApplication*) (daemon_local->receiver.buf+sizeof(DltUserHeader));
1809 /* Delete this application and all corresponding contexts for this application from internal table */
1810 application = dlt_daemon_application_find(daemon,usercontext->apid, verbose);
1814 /* Calculate start offset within contexts[] */
1816 for (i=0; i<(application-(daemon->applications)); i++)
1818 offset_base+=daemon->applications[i].num_contexts;
1821 for (i=application->num_contexts-1; i>=0; i--)
1823 context = &(daemon->contexts[offset_base+i]);
1826 /* Delete context */
1827 if (dlt_daemon_context_del(daemon, context, verbose)==-1)
1829 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgUnregisterApplication))==-1)
1831 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message unregister application\n");
1834 dlt_log(LOG_ERR,"Can't delete context for user message unregister application\n");
1840 /* Delete this application entry from internal table*/
1841 if (dlt_daemon_application_del(daemon, application, verbose)==-1)
1843 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgUnregisterApplication))==-1)
1845 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message unregister application\n");
1848 dlt_log(LOG_ERR,"Can't delete application for user message unregister application\n");
1854 /* keep not read data in buffer */
1855 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgUnregisterApplication))==-1)
1857 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message unregister application\n");
1864 int dlt_daemon_process_user_message_unregister_context(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1866 DltUserControlMsgUnregisterContext *usercontext;
1867 DltDaemonContext *context;
1869 PRINT_FUNCTION_VERBOSE(verbose);
1871 if ((daemon==0) || (daemon_local==0))
1873 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_unregister_context()\n");
1877 if (daemon_local->receiver.bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgUnregisterContext)))
1879 /* Not enough bytes received */
1883 usercontext = (DltUserControlMsgUnregisterContext*) (daemon_local->receiver.buf+sizeof(DltUserHeader));
1884 context = dlt_daemon_context_find(daemon,usercontext->apid, usercontext->ctid, verbose);
1888 /* Delete this connection entry from internal table*/
1889 if (dlt_daemon_context_del(daemon, context, verbose)==-1)
1891 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgUnregisterContext))==-1)
1893 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message unregister context\n");
1896 dlt_log(LOG_ERR,"Can't delete context for user message unregister context\n");
1901 /* Create automatic unregister context response for unregistered context */
1902 if (daemon_local->flags.rflag)
1904 dlt_daemon_control_message_unregister_context(DLT_DAEMON_SEND_TO_ALL,daemon,daemon_local,usercontext->apid, usercontext->ctid, "remo",verbose);
1907 /* keep not read data in buffer */
1908 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgUnregisterContext))==-1)
1910 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message unregister context\n");
1917 int dlt_daemon_process_user_message_log(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
1920 int bytes_to_be_removed;
1922 static char text[DLT_DAEMON_TEXTSIZE];
1924 PRINT_FUNCTION_VERBOSE(verbose);
1926 if ((daemon==0) || (daemon_local==0))
1928 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_log()\n");
1929 return DLT_DAEMON_ERROR_UNKNOWN;
1932 ret=dlt_message_read(&(daemon_local->msg),(unsigned char*)daemon_local->receiver.buf+sizeof(DltUserHeader),daemon_local->receiver.bytesRcvd-sizeof(DltUserHeader),0,verbose);
1933 if(ret!=DLT_MESSAGE_ERROR_OK)
1935 if(ret!=DLT_MESSAGE_ERROR_SIZE)
1937 dlt_log(LOG_ERR,"Can't read messages from receiver\n");
1939 return DLT_DAEMON_ERROR_UNKNOWN;
1942 /* set overwrite ecu id */
1943 if (daemon_local->flags.evalue!=0)
1945 /* Set header extra parameters */
1946 dlt_set_id(daemon_local->msg.headerextra.ecu, daemon->ecuid );
1947 //msg.headerextra.seid = 0;
1948 if (dlt_message_set_extraparameters(&(daemon_local->msg),0)==-1)
1950 dlt_log(LOG_ERR,"Can't set message extra parameters in process user message log\n");
1951 return DLT_DAEMON_ERROR_UNKNOWN;
1954 /* Correct value of timestamp, this was changed by dlt_message_set_extraparameters() */
1955 daemon_local->msg.headerextra.tmsp = DLT_BETOH_32(daemon_local->msg.headerextra.tmsp);
1958 /* prepare storage header */
1959 if (DLT_IS_HTYP_WEID(daemon_local->msg.standardheader->htyp))
1961 if (dlt_set_storageheader(daemon_local->msg.storageheader,daemon_local->msg.headerextra.ecu)==-1)
1963 dlt_log(LOG_ERR,"Can't set storage header in process user message log\n");
1964 return DLT_DAEMON_ERROR_UNKNOWN;
1969 if (dlt_set_storageheader(daemon_local->msg.storageheader,daemon->ecuid)==-1)
1971 dlt_log(LOG_ERR,"Can't set storage header in process user message log\n");
1972 return DLT_DAEMON_ERROR_UNKNOWN;
1977 /* if no filter set or filter is matching display message */
1978 if (daemon_local->flags.xflag)
1980 if (dlt_message_print_hex(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1)
1982 dlt_log(LOG_ERR,"dlt_message_print_hex() failed!\n");
1985 else if (daemon_local->flags.aflag)
1987 if (dlt_message_print_ascii(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1)
1989 dlt_log(LOG_ERR,"dlt_message_print_ascii() failed!\n");
1992 else if (daemon_local->flags.sflag)
1994 if (dlt_message_print_header(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1)
1996 dlt_log(LOG_ERR,"dlt_message_print_header() failed!\n");
1998 /* print message header only */
2002 /* check if overflow occurred */
2003 if(daemon->overflow_counter)
2005 if(dlt_daemon_send_message_overflow(daemon,daemon_local,verbose)==0)
2007 snprintf(str,DLT_DAEMON_TEXTBUFSIZE,"%u messages discarded!\n",daemon->overflow_counter);
2008 dlt_log(LOG_ERR, str);
2009 daemon->overflow_counter=0;
2013 /* send message to client or write to log file */
2014 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),
2015 daemon_local->msg.databuffer,daemon_local->msg.datasize,verbose)))
2017 if(ret == DLT_DAEMON_ERROR_BUFFER_FULL)
2019 daemon->overflow_counter++;
2024 /* keep not read data in buffer */
2025 bytes_to_be_removed = daemon_local->msg.headersize+daemon_local->msg.datasize-sizeof(DltStorageHeader)+sizeof(DltUserHeader);
2026 if (daemon_local->msg.found_serialheader)
2028 bytes_to_be_removed += sizeof(dltSerialHeader);
2031 if (dlt_receiver_remove(&(daemon_local->receiver),bytes_to_be_removed)==-1)
2033 dlt_log(LOG_ERR,"Can't remove bytes from receiver\n");
2034 return DLT_DAEMON_ERROR_UNKNOWN;
2037 return DLT_DAEMON_ERROR_OK;
2040 #ifdef DLT_SHM_ENABLE
2041 int dlt_daemon_process_user_message_log_shm(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
2043 int bytes_to_be_removed=0;
2044 int j,sent,third_value;
2046 uint8_t rcv_buffer[10000];
2048 DltUserHeader *userheader;
2050 static char text[DLT_DAEMON_TEXTSIZE];
2052 PRINT_FUNCTION_VERBOSE(verbose);
2054 if ((daemon==0) || (daemon_local==0))
2056 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_log()\n");
2060 userheader = (DltUserHeader*) (daemon_local->receiver.buf);
2062 //dlt_shm_status(&(daemon_local->dlt_shm));
2065 /* log message in SHM */
2066 if((size = dlt_shm_copy(&(daemon_local->dlt_shm),rcv_buffer,10000)) <= 0)
2068 if (dlt_message_read(&(daemon_local->msg),rcv_buffer,size,0,verbose)!=0) {
2070 dlt_log(LOG_ERR,"Can't read messages from shm\n");
2073 bytes_to_be_removed = daemon_local->msg.headersize+daemon_local->msg.datasize-sizeof(DltStorageHeader)+sizeof(DltUserHeader);
2074 if (daemon_local->msg.found_serialheader)
2076 bytes_to_be_removed += sizeof(dltSerialHeader);
2079 /* set overwrite ecu id */
2080 if (daemon_local->flags.evalue[0])
2082 /* Set header extra parameters */
2083 dlt_set_id(daemon_local->msg.headerextra.ecu, daemon->ecuid );
2084 //msg.headerextra.seid = 0;
2085 if (dlt_message_set_extraparameters(&(daemon_local->msg),0)==-1)
2087 dlt_log(LOG_ERR,"Can't set message extra parameters in process user message log\n");
2088 dlt_shm_remove(&(daemon_local->dlt_shm));
2092 /* Correct value of timestamp, this was changed by dlt_message_set_extraparameters() */
2093 daemon_local->msg.headerextra.tmsp = DLT_BETOH_32(daemon_local->msg.headerextra.tmsp);
2096 /* prepare storage header */
2097 if (DLT_IS_HTYP_WEID(daemon_local->msg.standardheader->htyp))
2099 if (dlt_set_storageheader(daemon_local->msg.storageheader,daemon_local->msg.headerextra.ecu)==-1)
2101 dlt_log(LOG_ERR,"Can't set storage header in process user message log\n");
2102 dlt_shm_remove(&(daemon_local->dlt_shm));
2108 if (dlt_set_storageheader(daemon_local->msg.storageheader,daemon->ecuid)==-1)
2110 dlt_log(LOG_ERR,"Can't set storage header in process user message log\n");
2111 dlt_shm_remove(&(daemon_local->dlt_shm));
2116 /* display message */
2117 if (daemon_local->flags.xflag)
2119 if (dlt_message_print_hex(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1)
2121 dlt_log(LOG_ERR,"dlt_message_print_hex() failed!\n");
2124 else if (daemon_local->flags.aflag)
2126 if (dlt_message_print_ascii(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1)
2128 dlt_log(LOG_ERR,"dlt_message_print_ascii() failed!\n");
2131 else if (daemon_local->flags.sflag)
2133 if (dlt_message_print_header(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1)
2135 dlt_log(LOG_ERR,"dlt_message_print_header() failed!\n");
2137 /* print message header only */
2142 /* write message to offline trace */
2143 if(((daemon->mode == DLT_USER_MODE_INTERNAL) || (daemon->mode == DLT_USER_MODE_BOTH)) && daemon_local->flags.offlineTraceDirectory[0])
2145 dlt_offline_trace_write(&(daemon_local->offlineTrace),daemon_local->msg.headerbuffer,daemon_local->msg.headersize,
2146 daemon_local->msg.databuffer,daemon_local->msg.datasize,0,0);
2150 /* look if TCP connection to client is available */
2151 for (j = 0;((daemon->mode == DLT_USER_MODE_EXTERNAL) || (daemon->mode == DLT_USER_MODE_BOTH)) && (j <= daemon_local->fdmax); j++)
2153 /* send to everyone! */
2154 if (FD_ISSET(j, &(daemon_local->master)))
2156 /* except the listener and ourselves */
2157 if (daemon_local->flags.yvalue[0])
2159 third_value = daemon_local->fdserial;
2163 third_value = daemon_local->sock;
2166 if ((j != daemon_local->fp) && (j != daemon_local->sock) && (j != third_value))
2168 DLT_DAEMON_SEM_LOCK();
2170 if (daemon_local->flags.lflag)
2172 send(j,dltSerialHeader,sizeof(dltSerialHeader),0);
2175 send(j,daemon_local->msg.headerbuffer+sizeof(DltStorageHeader),daemon_local->msg.headersize-sizeof(DltStorageHeader),0);
2176 send(j,daemon_local->msg.databuffer,daemon_local->msg.datasize,0);
2178 DLT_DAEMON_SEM_FREE();
2182 else if ((j == daemon_local->fdserial) && (daemon_local->flags.yvalue[0]))
2184 DLT_DAEMON_SEM_LOCK();
2186 if (daemon_local->flags.lflag)
2188 ret=write(j,dltSerialHeader,sizeof(dltSerialHeader));
2191 ret=write(j,daemon_local->msg.headerbuffer+sizeof(DltStorageHeader),daemon_local->msg.headersize-sizeof(DltStorageHeader));
2192 ret=write(j,daemon_local->msg.databuffer,daemon_local->msg.datasize);
2194 DLT_DAEMON_SEM_FREE();
2201 /* Message was not sent to client, so store it in client ringbuffer */
2202 if (sent==1 || (daemon->mode == DLT_USER_MODE_OFF))
2204 if(userheader->message == DLT_USER_MESSAGE_LOG_SHM) {
2205 /* dlt message was sent, remove from buffer if log message from shm */
2206 dlt_shm_remove(&(daemon_local->dlt_shm));
2211 /* dlt message was not sent, keep in buffer */
2217 /* keep not read data in buffer */
2218 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader))==-1)
2220 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message overflow\n");
2228 int dlt_daemon_process_user_message_set_app_ll_ts(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
2230 DltUserControlMsgAppLogLevelTraceStatus *usercontext;
2231 DltDaemonApplication *application;
2232 DltDaemonContext *context;
2234 int8_t old_log_level, old_trace_status;
2236 PRINT_FUNCTION_VERBOSE(verbose);
2238 if ((daemon==0) || (daemon_local==0))
2240 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_set_app_ll_ts()\n");
2244 if (daemon_local->receiver.bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgAppLogLevelTraceStatus )))
2246 /* Not enough bytes receeived */
2250 if (daemon->num_applications>0)
2252 usercontext = (DltUserControlMsgAppLogLevelTraceStatus*) (daemon_local->receiver.buf+sizeof(DltUserHeader));
2254 /* Get all contexts with application id matching the received application id */
2255 application = dlt_daemon_application_find(daemon, usercontext->apid, verbose);
2258 /* Calculate start offset within contexts[] */
2260 for (i=0; i<(application-(daemon->applications)); i++)
2262 offset_base+=daemon->applications[i].num_contexts;
2265 for (i=0; i < application->num_contexts; i++)
2267 context = &(daemon->contexts[offset_base+i]);
2270 old_log_level = context->log_level;
2271 context->log_level = usercontext->log_level; /* No endianess conversion necessary*/
2273 old_trace_status = context->trace_status;
2274 context->trace_status = usercontext->trace_status; /* No endianess conversion necessary */
2276 /* The folowing function sends also the trace status */
2277 if (context->user_handle >= DLT_FD_MINIMUM && dlt_daemon_user_send_log_level(daemon, context, verbose)!=0)
2279 context->log_level = old_log_level;
2280 context->trace_status = old_trace_status;
2287 /* keep not read data in buffer */
2288 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgAppLogLevelTraceStatus))==-1)
2290 dlt_log(LOG_ERR,"Can't remove bytes from receiver\n");
2297 int dlt_daemon_process_user_message_log_mode(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
2299 DltUserControlMsgLogMode *logmode;
2301 PRINT_FUNCTION_VERBOSE(verbose);
2303 if ((daemon==0) || (daemon_local==0))
2305 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_log_mode()\n");
2309 if (daemon_local->receiver.bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogMode)))
2311 /* Not enough bytes received */
2315 logmode = (DltUserControlMsgLogMode*) (daemon_local->receiver.buf+sizeof(DltUserHeader));
2317 /* set the new log mode */
2318 daemon->mode = logmode->log_mode;
2320 /* write configuration persistantly */
2321 dlt_daemon_configuration_save(daemon, daemon->runtime_configuration, verbose);
2323 /* keep not read data in buffer */
2324 if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogMode))==-1)
2326 dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message log mode\n");
2333 int dlt_daemon_send_ringbuffer_to_client(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
2336 static uint8_t data[DLT_DAEMON_RCVBUFSIZE];
2339 PRINT_FUNCTION_VERBOSE(verbose);
2341 if ((daemon==0) || (daemon_local==0))
2343 dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_send_ringbuffer_to_client()\n");
2344 return DLT_DAEMON_ERROR_UNKNOWN;
2347 if(dlt_buffer_get_message_count(&(daemon->client_ringbuffer)) <= 0)
2349 dlt_daemon_change_state(daemon, DLT_DAEMON_STATE_SEND_DIRECT);
2350 return DLT_DAEMON_ERROR_OK;
2353 while ( (length = dlt_buffer_copy(&(daemon->client_ringbuffer), data, sizeof(data)) ) > 0)
2355 if((ret = dlt_daemon_client_send(DLT_DAEMON_SEND_FORCE,daemon,daemon_local,data,length,0,0,verbose)))
2359 dlt_buffer_remove(&(daemon->client_ringbuffer));
2360 if(daemon->state != DLT_DAEMON_STATE_SEND_BUFFER)
2361 dlt_daemon_change_state(daemon,DLT_DAEMON_STATE_SEND_BUFFER);
2363 if(dlt_buffer_get_message_count(&(daemon->client_ringbuffer)) <= 0)
2365 dlt_daemon_change_state(daemon,DLT_DAEMON_STATE_SEND_DIRECT);
2366 return DLT_DAEMON_ERROR_OK;
2370 return DLT_DAEMON_ERROR_OK;
2373 int create_timer_fd(DltDaemonLocal *daemon_local, int period_sec, int starts_in, int* fd, const char* timer_name)
2376 struct itimerspec l_timer_spec;
2378 if(timer_name == NULL)
2380 timer_name = "timer_not_named";
2385 snprintf(str, sizeof(str), "<%s> fd is NULL pointer\n", timer_name );
2386 dlt_log(DLT_LOG_ERROR, str);
2390 if( period_sec > 0 ) {
2392 local_fd = timerfd_create(CLOCK_MONOTONIC, 0);
2395 snprintf(str, sizeof(str), "<%s> timerfd_create failed: %s\n", timer_name, strerror(errno));
2396 dlt_log(DLT_LOG_ERROR, str);
2399 l_timer_spec.it_interval.tv_sec = period_sec;
2400 l_timer_spec.it_interval.tv_nsec = 0;
2401 l_timer_spec.it_value.tv_sec = starts_in;
2402 l_timer_spec.it_value.tv_nsec = 0;
2404 if( timerfd_settime( local_fd, 0, &l_timer_spec, NULL) < 0)
2406 snprintf(str, sizeof(str), "<%s> timerfd_settime failed: %s\n", timer_name, strerror(errno));
2407 dlt_log(DLT_LOG_ERROR, str);
2413 // timer not activated via the service file
2414 snprintf(str, sizeof(str), "<%s> not set: period=0\n", timer_name);
2415 dlt_log(DLT_LOG_INFO, str);
2419 // If fd is fully initialized, let's add it to the fd sets
2422 snprintf(str, sizeof(str), "<%s> initialized with %ds timer\n", timer_name, period_sec);
2423 dlt_log(DLT_LOG_INFO, str);
2425 FD_SET(local_fd, &(daemon_local->master));
2426 //FD_SET(local_fd, &(daemon_local->timer_fds));
2427 if (local_fd > daemon_local->fdmax)
2429 daemon_local->fdmax = local_fd;
2438 /* Close connection function */
2439 int dlt_daemon_close_socket(int sock, DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
2441 dlt_daemon_socket_close(sock);
2443 FD_CLR(sock, &(daemon_local->master));
2445 if (daemon_local->client_connections)
2447 daemon_local->client_connections--;
2450 if(daemon_local->client_connections==0)
2452 /* send new log state to all applications */
2453 daemon->connectionState = 0;
2454 dlt_daemon_user_send_all_log_state(daemon,verbose);
2455 dlt_daemon_change_state(daemon,DLT_DAEMON_STATE_BUFFER);
2458 if (daemon_local->flags.vflag)
2460 snprintf(str,DLT_DAEMON_TEXTBUFSIZE, "Connection to client lost, #connections: %d\n",daemon_local->client_connections);
2461 dlt_log(LOG_INFO, str);
2464 dlt_daemon_control_message_connection_info(DLT_DAEMON_SEND_TO_ALL,daemon,daemon_local,DLT_CONNECTION_STATUS_DISCONNECTED,"",verbose);