summaryrefslogtreecommitdiff
path: root/src/daemon
diff options
context:
space:
mode:
authorChristian Muck <christian.muck@bmw.de>2011-04-11 15:41:05 +0200
committerChristian Muck <christian.muck@bmw.de>2011-04-11 15:41:05 +0200
commit760fb8a4daba3e403376099ce38aca8f88d695d3 (patch)
tree36b6f428cee8ba0af0fd50b3e44a3d4da9083a44 /src/daemon
parent5394c6fa5bf40d9bc8619026cbc4c306211a8499 (diff)
downloadDLT-daemon-760fb8a4daba3e403376099ce38aca8f88d695d3.tar.gz
Init of dlt daemon
Diffstat (limited to 'src/daemon')
-rwxr-xr-xsrc/daemon/CMakeLists.txt48
-rwxr-xr-xsrc/daemon/dlt-daemon.c2022
-rwxr-xr-xsrc/daemon/dlt-daemon.h173
-rwxr-xr-xsrc/daemon/dlt-daemon_cfg.h125
-rwxr-xr-xsrc/daemon/dlt_daemon_common.c2196
-rwxr-xr-xsrc/daemon/dlt_daemon_common.h420
-rwxr-xr-xsrc/daemon/dlt_daemon_common_cfg.h129
7 files changed, 5113 insertions, 0 deletions
diff --git a/src/daemon/CMakeLists.txt b/src/daemon/CMakeLists.txt
new file mode 100755
index 0000000..863036b
--- /dev/null
+++ b/src/daemon/CMakeLists.txt
@@ -0,0 +1,48 @@
+#######
+# Dlt - Diagnostic Log and Trace
+# @licence make begin@
+ #
+ # Copyright (C) 2011, BMW AG - Alexander Wenzel <alexander.wenzel@bmw.de>
+ #
+ # This program is free software; you can redistribute it and/or modify it under the terms of the
+ # GNU Lesser General Public License, version 2.1, as published by the Free Software Foundation.
+ # This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ # the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
+ # Public License, version 2.1, for more details.
+ #
+ # You should have received a copy of the GNU Lesser General Public License, version 2.1, along
+ # with this program; if not, see <http://www.gnu.org/licenses/lgpl-2.1.html>.
+ #
+ # Note that the copyright holders assume that the GNU Lesser General Public License, version 2.1, may
+ # also be applicable to programs even in cases in which the program is not a library in the technical sense.
+ #
+ # Linking DLT statically or dynamically with other modules is making a combined work based on DLT. You may
+ # license such other modules under the GNU Lesser General Public License, version 2.1. If you do not want to
+ # license your linked modules under the GNU Lesser General Public License, version 2.1, you
+ # may use the program under the following exception.
+ #
+ # As a special exception, the copyright holders of DLT give you permission to combine DLT
+ # with software programs or libraries that are released under any license unless such a combination is not
+ # permitted by the license of such a software program or library. You may copy and distribute such a
+ # system following the terms of the GNU Lesser General Public License, version 2.1, including this
+ # special exception, for DLT and the licenses of the other code concerned.
+ #
+ # Note that people who make modified versions of DLT are not obligated to grant this special exception
+ # for their modified versions; it is their choice whether to do so. The GNU Lesser General Public License,
+ # version 2.1, gives permission to release a modified version without this exception; this exception
+ # also makes it possible to release a modified version which carries forward this exception.
+ #
+ # @licence end@
+########
+
+set(dlt_daemon_SRCS dlt-daemon dlt_daemon_common ${CMAKE_SOURCE_DIR}/src/shared/dlt_user_shared.c ${CMAKE_SOURCE_DIR}/src/shared/dlt_common.c)
+add_executable(dlt-daemon ${dlt_daemon_SRCS})
+target_link_libraries(dlt-daemon rt ${CMAKE_THREAD_LIBS_INIT})
+
+install(TARGETS dlt-daemon
+ RUNTIME DESTINATION bin
+ PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ
+ GROUP_EXECUTE GROUP_READ
+ WORLD_EXECUTE WORLD_READ
+ COMPONENT base)
+
diff --git a/src/daemon/dlt-daemon.c b/src/daemon/dlt-daemon.c
new file mode 100755
index 0000000..ad2aa9d
--- /dev/null
+++ b/src/daemon/dlt-daemon.c
@@ -0,0 +1,2022 @@
+/*
+ * Dlt Daemon - Diagnostic Log and Trace
+ * @licence app begin@
+ *
+ * Copyright (C) 2011, BMW AG - Alexander Wenzel <alexander.wenzel@bmw.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under the terms of the
+ * GNU Lesser General Public License, version 2.1, as published by the Free Software Foundation.
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
+ * Public License, version 2.1, for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License, version 2.1, along
+ * with this program; if not, see <http://www.gnu.org/licenses/lgpl-2.1.html>.
+ *
+ * Note that the copyright holders assume that the GNU Lesser General Public License, version 2.1, may
+ * also be applicable to programs even in cases in which the program is not a library in the technical sense.
+ *
+ * Linking DLT statically or dynamically with other modules is making a combined work based on DLT. You may
+ * license such other modules under the GNU Lesser General Public License, version 2.1. If you do not want to
+ * license your linked modules under the GNU Lesser General Public License, version 2.1, you
+ * may use the program under the following exception.
+ *
+ * As a special exception, the copyright holders of DLT give you permission to combine DLT
+ * with software programs or libraries that are released under any license unless such a combination is not
+ * permitted by the license of such a software program or library. You may copy and distribute such a
+ * system following the terms of the GNU Lesser General Public License, version 2.1, including this
+ * special exception, for DLT and the licenses of the other code concerned.
+ *
+ * Note that people who make modified versions of DLT are not obligated to grant this special exception
+ * for their modified versions; it is their choice whether to do so. The GNU Lesser General Public License,
+ * version 2.1, gives permission to release a modified version without this exception; this exception
+ * also makes it possible to release a modified version which carries forward this exception.
+ *
+ * @licence end@
+ */
+
+
+/*******************************************************************************
+** **
+** SRC-MODULE: dlt-daemon.c **
+** **
+** TARGET : linux **
+** **
+** PROJECT : DLT **
+** **
+** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de **
+** Markus Klein **
+** **
+** PURPOSE : **
+** **
+** REMARKS : **
+** **
+** PLATFORM DEPENDANT [yes/no]: yes **
+** **
+** TO BE CHANGED BY USER [yes/no]: no **
+** **
+*******************************************************************************/
+
+/*******************************************************************************
+** Author Identity **
+********************************************************************************
+** **
+** Initials Name Company **
+** -------- ------------------------- ---------------------------------- **
+** aw Alexander Wenzel BMW **
+** mk Markus Klein Fraunhofer ESK **
+*******************************************************************************/
+
+/*******************************************************************************
+** Revision Control History **
+*******************************************************************************/
+
+/*
+ * $LastChangedRevision: 1670 $
+ * $LastChangedDate: 2011-04-08 15:12:06 +0200 (Fr, 08. Apr 2011) $
+ * $LastChangedBy$
+ Initials Date Comment
+ aw 13.01.2010 initial
+ */
+
+#include <netdb.h>
+#include <ctype.h>
+#include <stdio.h> /* for printf() and fprintf() */
+#include <sys/socket.h> /* for socket(), connect(), (), and recv() */
+#include <arpa/inet.h> /* for sockaddr_in and inet_addr() */
+#include <stdlib.h> /* for atoi() and exit() */
+#include <string.h> /* for memset() */
+#include <unistd.h> /* for close() */
+#include <fcntl.h>
+#include <signal.h>
+#include <syslog.h>
+#include <errno.h>
+#include <pthread.h>
+
+#include <sys/timerfd.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <linux/stat.h>
+
+#include "version.h"
+#include "svnversion.h"
+
+#include "dlt_types.h"
+#include "dlt-daemon.h"
+#include "dlt-daemon_cfg.h"
+
+/** \page Contents
+ * The package automotive-dlt includes the following items:
+ * - dlt daemon (dlt-daemon)
+ * - adptors to to interface the daemon (dlt-adaptor-stdin, dlt-adaptor-udp)
+ * - dlt client gui (dlt-viewer)
+ * - dlt console tools (dlt-receive, dlt-convert)
+ * - examples (dlt-example-user, dlt-example-user-func, dlt-example-ringbuffer)
+ * - a library including user-application, client and common functions
+ */
+
+/**
+ \defgroup daemon DLT Daemon
+ \addtogroup daemon
+ \{
+*/
+
+/** Global text output buffer, mainly used for creation of error/warning strings */
+static char str[DLT_DAEMON_TEXTBUFSIZE];
+
+static DltDaemonTimingPacketThreadData dlt_daemon_timingpacket_thread_data;
+
+static pthread_t dlt_daemon_timingpacket_thread_handle;
+static pthread_attr_t dlt_daemon_timingpacket_thread_attr;
+
+/**
+ * Print usage information of tool.
+ */
+void usage()
+{
+ printf("Usage: dlt-daemon [options]\n");
+ printf("DLT logging daemon\n");
+ printf("Options:\n");
+ printf(" -a Print DLT messages; payload as ASCII\n");
+ printf(" -x Print DLT messages; payload as hex\n");
+ printf(" -s Print DLT messages; only headers\n");
+ printf(" -d Daemonize\n");
+ printf(" -v Verbose mode\n");
+ printf(" -h Usage\n");
+ printf(" -l Send DLT messages with serial header\n");
+ printf(" -r Send automatic get log info response during\n");
+ printf(" context registration\n");
+ printf(" -m Sync to serial header on serial connection\n");
+ printf(" -n Sync to serial header on all TCP connections\n");
+ printf(" -y devname Additional support for serial device\n");
+ printf(" -b baudrate Serial device baudrate (Default: 115200)\n");
+ printf(" -e ecuid Set ECU ID (Default: ECU1)\n");
+ printf(" -o filename Store DLT messages to local log file\n");
+ printf(" -f filename Enable filtering of messages\n");
+ printf(" -u size Size of the ringbuffer in bytes (Default: 10024)\n");
+} /* usage() */
+
+/**
+ * Option handling
+ */
+int option_handling(DltDaemonLocal *daemon_local,int argc, char* argv[])
+ {
+ int c;
+
+ if (daemon_local==0)
+ {
+ fprintf (stderr, "Invalid parameter passed to option_handling()\n");
+ return -1;
+ }
+
+ /* Initialize flags */
+ memset(daemon_local,0,sizeof(DltDaemonLocal));
+
+ opterr = 0;
+
+ while ((c = getopt (argc, argv, "hvasxdlrmnf:o:e:b:y:u:")) != -1)
+ {
+ switch (c)
+ {
+ case 'v':
+ {
+ daemon_local->flags.vflag = 1;
+ break;
+ }
+ case 'a':
+ {
+ daemon_local->flags.aflag = 1;
+ break;
+ }
+ case 's':
+ {
+ daemon_local->flags.sflag = 1;
+ break;
+ }
+ case 'x':
+ {
+ daemon_local->flags.xflag = 1;
+ break;
+ }
+ case 'd':
+ {
+ daemon_local->flags.dflag = 1;
+ break;
+ }
+ case 'l':
+ {
+ daemon_local->flags.lflag = 1;
+ break;
+ }
+ case 'r':
+ {
+ daemon_local->flags.rflag = 1;
+ break;
+ }
+ case 'm':
+ {
+ daemon_local->flags.mflag = 1;
+ break;
+ }
+ case 'n':
+ {
+ daemon_local->flags.nflag = 1;
+ break;
+ }
+ case 'f':
+ {
+ daemon_local->flags.fvalue = optarg;
+ break;
+ }
+ case 'o':
+ {
+ daemon_local->flags.ovalue = optarg;
+ break;
+ }
+ case 'e':
+ {
+ daemon_local->flags.evalue = optarg;
+ break;
+ }
+ case 'b':
+ {
+ daemon_local->flags.bvalue = optarg;
+ break;
+ }
+ case 'y':
+ {
+ daemon_local->flags.yvalue = optarg;
+ break;
+ }
+ case 'u':
+ {
+ daemon_local->flags.uvalue = optarg;
+ break;
+ }
+ case 'h':
+ {
+ usage();
+ return -2; /* return no error */
+ }
+ case '?':
+ {
+ if (optopt == 'f' || optopt == 'o' || optopt == 'e' || optopt == 'b' || optopt == 'y' || optopt == 'u')
+ {
+ fprintf (stderr, "Option -%c requires an argument.\n", optopt);
+ }
+ else if (isprint (optopt))
+ {
+ fprintf (stderr, "Unknown option `-%c'.\n", optopt);
+ }
+ else
+ {
+ fprintf (stderr, "Unknown option character `\\x%x'.\n",optopt);
+ }
+ /* unknown or wrong option used, show usage information and terminate */
+ usage();
+ return -1;
+ }
+ default:
+ {
+ fprintf (stderr, "Invalid option, this should never occur!\n");
+ return -1;
+ }
+ } /* switch() */
+ }
+
+ return 0;
+
+ } /* option_handling() */
+
+/**
+ * Main function of tool.
+ */
+int main(int argc, char* argv[])
+{
+ char version[DLT_DAEMON_TEXTBUFSIZE];
+ DltDaemonLocal daemon_local;
+ DltDaemon daemon;
+
+ int i,back;
+
+ /* Command line option handling */
+ if ((back = option_handling(&daemon_local,argc,argv))<0)
+ {
+ if(back!=-2) {
+ fprintf (stderr, "option_handling() failed!\n");
+ }
+ return -1;
+ }
+
+ /* Initialize logging facility */
+ dlt_log_init(daemon_local.flags.dflag);
+
+ /* Print version information */
+ dlt_get_version(version);
+
+ sprintf(str,"Starting DLT Daemon; %s\n", version );
+ dlt_log(LOG_NOTICE, str);
+
+ PRINT_FUNCTION_VERBOSE(daemon_local.flags.vflag);
+
+ /* --- Daemon init phase 1 begin --- */
+ if (dlt_daemon_local_init_p1(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
+ {
+ dlt_log(LOG_CRIT,"Initialization of phase 1 failed!\n");
+ return -1;
+ }
+ /* --- Daemon init phase 1 end --- */
+
+ /* --- Daemon connection init begin */
+ if (dlt_daemon_local_connection_init(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
+ {
+ dlt_log(LOG_CRIT,"Initialization of local connections failed!\n");
+ return -1;
+ }
+ /* --- Daemon connection init end */
+
+ /* --- Daemon init phase 2 begin --- */
+ if (dlt_daemon_local_init_p2(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
+ {
+ dlt_log(LOG_CRIT,"Initialization of phase 2 failed!\n");
+ return -1;
+ }
+ /* --- Daemon init phase 2 end --- */
+
+ while (1)
+ {
+ /* wait for events form all FIFO and sockets */
+ daemon_local.read_fds = daemon_local.master;
+ if (select(daemon_local.fdmax+1, &(daemon_local.read_fds), NULL, NULL, NULL) == -1)
+ {
+ dlt_log(LOG_CRIT, "select() failed!\n");
+ return -1 ;
+ } /* if */
+
+ /* run through the existing FIFO and sockets to check for events */
+ for (i = 0; i <= daemon_local.fdmax; i++)
+ {
+ if (FD_ISSET(i, &(daemon_local.read_fds)))
+ {
+ if (i == daemon_local.sock)
+ {
+ /* event from TCP server socket, new connection */
+ if (dlt_daemon_process_client_connect(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
+ {
+ dlt_log(LOG_CRIT,"Connect to dlt client failed!\n");
+ return -1;
+ }
+ }
+ else if (i == daemon_local.fp)
+ {
+ /* event from the FIFO happened */
+ if (dlt_daemon_process_user_messages(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
+ {
+ dlt_log(LOG_CRIT,"Processing of messages from user connection failed!\n");
+ return -1;
+ }
+ }
+ else if ((i == daemon_local.fdserial) && (daemon_local.flags.yvalue!=0))
+ {
+ /* event from serial connection to client received */
+ if (dlt_daemon_process_client_messages_serial(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
+ {
+ dlt_log(LOG_CRIT,"Processing of messages from serial connection failed!\n");
+ return -1;
+ }
+ }
+ else
+ {
+ /* event from tcp connection to client received */
+ daemon_local.receiverSock.fd = i;
+ if (dlt_daemon_process_client_messages(&daemon, &daemon_local, daemon_local.flags.vflag)==-1)
+ {
+ dlt_log(LOG_CRIT,"Processing of messages from client connection failed!\n");
+ return -1;
+ }
+ } /* else */
+ } /* if */
+ } /* for */
+ } /* while */
+
+ dlt_daemon_local_cleanup(&daemon, &daemon_local, daemon_local.flags.vflag);
+
+ dlt_log(LOG_NOTICE, "Leaving DLT daemon\n");
+
+ return 0;
+
+} /* main() */
+
+int dlt_daemon_local_init_p1(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
+{
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ if ((daemon==0) || (daemon_local==0))
+ {
+ dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_local_init_p1()\n");
+ return -1;
+ }
+
+ /* Check for daemon mode */
+ if (daemon_local->flags.dflag)
+ {
+ dlt_daemon_daemonize(daemon_local->flags.vflag);
+ }
+
+ /* initialise structure to use DLT file */
+ if (dlt_file_init(&(daemon_local->file),daemon_local->flags.vflag)==-1)
+ {
+ dlt_log(LOG_ERR,"Could not initialize file structure\n");
+ /* Return value ignored, dlt daemon will exit */
+ dlt_file_free(&(daemon_local->file),daemon_local->flags.vflag);
+ return -1;
+ }
+
+ /* first parse filter file if filter parameter is used */
+ if (daemon_local->flags.fvalue)
+ {
+ if (dlt_filter_load(&(daemon_local->filter),daemon_local->flags.fvalue,daemon_local->flags.vflag)<0)
+ {
+ dlt_log(LOG_ERR,"Could not load filters\n");
+ /* Return value ignored, dlt daemon will exit */
+ dlt_file_free(&(daemon_local->file),daemon_local->flags.vflag);
+ return -1;
+ } /* if */
+
+ if (dlt_file_set_filter(&(daemon_local->file),&(daemon_local->filter),daemon_local->flags.vflag)==-1)
+ {
+ dlt_log(LOG_ERR,"Could not apply filters\n");
+ /* Return value ignored, dlt daemon will exit */
+ dlt_file_free(&(daemon_local->file),daemon_local->flags.vflag);
+ return -1;
+ }
+ } /* if */
+
+ signal(SIGPIPE,SIG_IGN);
+
+ signal(SIGTERM, dlt_daemon_signal_handler); /* software termination signal from kill */
+ signal(SIGHUP, dlt_daemon_signal_handler); /* hangup signal */
+ signal(SIGQUIT, dlt_daemon_signal_handler);
+ signal(SIGINT, dlt_daemon_signal_handler);
+
+ /* open DLT output file */
+ daemon_local->ohandle=-1;
+ if (daemon_local->flags.ovalue)
+ {
+ daemon_local->ohandle = open(daemon_local->flags.ovalue,O_WRONLY|O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); /* mode: wb */
+ if (daemon_local->ohandle == -1)
+ {
+ /* Return value ignored, dlt daemon will exit */
+ dlt_file_free(&(daemon_local->file),daemon_local->flags.vflag);
+ sprintf(str,"Output file %s cannot be opened!\n",daemon_local->flags.ovalue);
+ dlt_log(LOG_ERR, str);
+ return -1;
+ } /* if */
+ } /* if */
+
+ return 0;
+}
+
+int dlt_daemon_local_init_p2(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
+{
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ if ((daemon==0) || (daemon_local==0))
+ {
+ dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_local_init_p2()\n");
+ return -1;
+ }
+
+ /* Daemon data */
+ if (dlt_daemon_init(daemon,daemon_local->flags.vflag)==-1)
+ {
+ dlt_log(LOG_ERR,"Could not initialize daemon data\n");
+ return -1;
+ }
+
+ /* Set ECU id of daemon */
+ if (daemon_local->flags.evalue!=0)
+ {
+ dlt_set_id(daemon->ecuid,daemon_local->flags.evalue);
+ }
+ else
+ {
+ dlt_set_id(daemon->ecuid,DLT_DAEMON_ECU_ID);
+ }
+
+ /* Set flag for optional sending of serial header */
+ daemon->sendserialheader = daemon_local->flags.lflag;
+
+ /* prepare ringbuffer size */
+ if (daemon_local->flags.uvalue!=0)
+ {
+ daemon_local->ringbufferSize = atoi(daemon_local->flags.uvalue);
+ }
+ else
+ {
+ daemon_local->ringbufferSize = DLT_DAEMON_RCVBUFSIZE;
+ }
+ sprintf(str,"Ringbuffer size: %d bytes\n",daemon_local->ringbufferSize);
+ dlt_log(LOG_NOTICE, str);
+
+ /* prepare main loop */
+ if (dlt_message_init(&(daemon_local->msg),daemon_local->flags.vflag)==-1)
+ {
+ dlt_log(LOG_ERR,"Could not initialize message\n");
+ return -1;
+ }
+
+ if (dlt_receiver_init(&(daemon_local->receiver),daemon_local->fp,daemon_local->ringbufferSize)==-1)
+ {
+ dlt_log(LOG_ERR,"Could not initialize receiver\n");
+ return -1;
+ }
+ if (dlt_receiver_init(&(daemon_local->receiverSock),daemon_local->sock,DLT_DAEMON_RCVBUFSIZESOCK)==-1)
+ {
+ dlt_log(LOG_ERR,"Could not initialize receiver for socket\n");
+ return -1;
+ }
+
+ if (daemon_local->flags.yvalue!=0)
+ {
+ if (dlt_receiver_init(&(daemon_local->receiverSerial),daemon_local->fdserial,DLT_DAEMON_RCVBUFSIZESERIAL)==-1)
+ {
+ dlt_log(LOG_ERR,"Could not initialize receiver for serial connection\n");
+ return -1;
+ }
+ }
+
+ /* setup period thread for timing packets */
+ if (pthread_attr_init(&dlt_daemon_timingpacket_thread_attr)<0)
+ {
+ dlt_log(LOG_WARNING, "Initialization of default thread stack size failed!\n");
+ }
+ else
+ {
+ if (pthread_attr_setstacksize(&dlt_daemon_timingpacket_thread_attr,DLT_DAEMON_TIMINGPACKET_THREAD_STACKSIZE)<0)
+ {
+ dlt_log(LOG_WARNING, "Setting of default thread stack size failed!\n");
+ }
+ }
+
+ /* Binary semaphore for thread */
+ if (sem_init(&dlt_daemon_mutex, 0, 1)==-1)
+ {
+ dlt_log(LOG_ERR,"Could not initialize binary semaphore\n");
+ return -1;
+ }
+
+ /* start thread */
+ dlt_daemon_timingpacket_thread_data.daemon = daemon;
+ dlt_daemon_timingpacket_thread_data.daemon_local = daemon_local;
+
+ if (pthread_create(&(dlt_daemon_timingpacket_thread_handle),
+ &dlt_daemon_timingpacket_thread_attr,
+ (void *) &dlt_daemon_timingpacket_thread,
+ (void *)&dlt_daemon_timingpacket_thread_data)!=0)
+ {
+ dlt_log(LOG_ERR,"Could not initialize timing packet thread\n");
+ pthread_attr_destroy(&dlt_daemon_timingpacket_thread_attr);
+ return -1;
+ }
+
+ pthread_attr_destroy(&dlt_daemon_timingpacket_thread_attr);
+
+ return 0;
+}
+
+int dlt_daemon_local_connection_init(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
+{
+ int ret;
+ int yes = 1;
+
+ struct sockaddr_in servAddr;
+ unsigned int servPort = DLT_DAEMON_TCP_PORT;
+
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ if ((daemon==0) || (daemon_local==0))
+ {
+ dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_local_connection_init()\n");
+ return -1;
+ }
+
+ /* open named pipe(FIFO) to receive DLT messages from users */
+ umask(0);
+
+ /* Try to delete existing pipe, ignore result of unlink */
+ unlink(DLT_USER_FIFO);
+
+ ret=mkfifo(DLT_USER_FIFO, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH );
+ if (ret==-1)
+ {
+ sprintf(str,"FIFO user %s cannot be created!\n",DLT_USER_FIFO);
+ dlt_log(LOG_ERR, str);
+ return -1;
+ } /* if */
+
+ daemon_local->fp = open(DLT_USER_FIFO, O_RDWR);
+ if (daemon_local->fp==-1)
+ {
+ sprintf(str,"FIFO user %s cannot be opened!\n",DLT_USER_FIFO);
+ dlt_log(LOG_ERR, str);
+ return -1;
+ } /* if */
+
+ /* create and open socket to receive incoming connections from client */
+ if ((daemon_local->sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
+ {
+ dlt_log(LOG_ERR, "socket() failed!\n");
+ return -1;
+ } /* if */
+
+ setsockopt(daemon_local->sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
+ memset(&servAddr, 0, sizeof(servAddr));
+ servAddr.sin_family = AF_INET;
+ servAddr.sin_addr.s_addr = INADDR_ANY;
+ servAddr.sin_port = htons(servPort);
+
+ if (bind(daemon_local->sock, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0)
+ {
+ dlt_log(LOG_ERR, "bind() failed!\n");
+ return -1;
+ } /* if */
+
+ if (daemon_local->flags.vflag)
+ {
+ dlt_log(LOG_INFO, "Bind succesfull\n");
+ }
+
+ if (listen(daemon_local->sock, 3) < 0)
+ {
+ dlt_log(LOG_ERR, "listen() failed!\n");
+ return -1;
+ } /* if */
+
+ if (daemon_local->flags.vflag)
+ {
+ dlt_log(LOG_INFO, "Listen succesfull\n");
+ }
+
+ /* prepare usage of select(), add FIFO and receiving socket */
+ FD_ZERO(&(daemon_local->master));
+ FD_ZERO(&(daemon_local->read_fds));
+ FD_SET(daemon_local->sock, &(daemon_local->master));
+
+ daemon_local->fdmax = daemon_local->sock;
+
+ FD_SET(daemon_local->fp, &(daemon_local->master));
+
+ if (daemon_local->fp > daemon_local->fdmax)
+ {
+ daemon_local->fdmax = daemon_local->fp;
+ }
+
+ if (daemon_local->flags.yvalue!=0)
+ {
+ /* create and open serial connection from/to client */
+ /* open serial connection */
+ daemon_local->fdserial=open(daemon_local->flags.yvalue,O_RDWR);
+ if (daemon_local->fdserial<0)
+ {
+ daemon_local->flags.yvalue = 0;
+ sprintf(str,"Failed to open serial device %s\n", daemon_local->flags.yvalue);
+ dlt_log(LOG_ERR, str);
+ return -1;
+ }
+
+ if (isatty(daemon_local->fdserial))
+ {
+ if (daemon_local->flags.bvalue!=0)
+ {
+ daemon_local->baudrate = dlt_convert_serial_speed(atoi(daemon_local->flags.bvalue));
+ }
+ else
+ {
+ daemon_local->baudrate = dlt_convert_serial_speed(DLT_DAEMON_SERIAL_DEFAULT_BAUDRATE);
+ }
+
+ if (dlt_setup_serial(daemon_local->fdserial,daemon_local->baudrate)<0)
+ {
+ close(daemon_local->fdserial);
+ daemon_local->flags.yvalue = 0;
+ sprintf(str,"Failed to configure serial device %s (%s) \n", daemon_local->flags.yvalue, strerror(errno));
+ dlt_log(LOG_ERR, str);
+ return -1;
+ }
+
+ FD_SET(daemon_local->fdserial, &(daemon_local->master));
+
+ if (daemon_local->fdserial > daemon_local->fdmax)
+ {
+ daemon_local->fdmax = daemon_local->fdserial;
+ }
+
+ if (daemon_local->flags.vflag)
+ {
+ dlt_log(LOG_INFO, "Serial init done\n");
+ }
+ }
+ else
+ {
+ close(daemon_local->fdserial);
+ daemon_local->flags.yvalue = 0;
+ fprintf(stderr,"Device is not a serial device, device = %s (%s) \n", daemon_local->flags.yvalue, strerror(errno));
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+
+void dlt_daemon_local_cleanup(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
+{
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ if ((daemon==0) || (daemon_local==0))
+ {
+ dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_local_cleanup()\n");
+ return;
+ }
+
+ /* Ignore result */
+ dlt_receiver_free(&(daemon_local->receiver));
+ /* Ignore result */
+ dlt_receiver_free(&(daemon_local->receiverSock));
+
+ /* Ignore result */
+ dlt_message_free(&(daemon_local->msg),daemon_local->flags.vflag);
+ close(daemon_local->fp);
+
+ if (daemon_local->flags.ovalue)
+ {
+ close(daemon_local->ohandle);
+ } /* if */
+
+ /* Ignore result */
+ dlt_file_free(&(daemon_local->file),daemon_local->flags.vflag);
+
+ /* Try to delete existing pipe, ignore result of unlink() */
+ unlink(DLT_USER_FIFO);
+
+ /* Try to delete lock file, ignore result of unlink() */
+ unlink(DLT_DAEMON_LOCK_FILE);
+}
+
+void dlt_daemon_signal_handler(int sig)
+{
+ switch (sig)
+ {
+ case SIGHUP:
+ case SIGTERM:
+ case SIGINT:
+ case SIGQUIT:
+ {
+ /* finalize the server */
+ //dlt_log("terminate signal catched");
+ dlt_log(LOG_NOTICE, "Exiting DLT daemon\n");
+
+ /* Try to delete existing pipe, ignore result of unlink() */
+ unlink(DLT_USER_FIFO);
+
+ /* Try to delete lock file, ignore result of unlink() */
+ unlink(DLT_DAEMON_LOCK_FILE);
+
+ /* Terminate program */
+ exit(0);
+ break;
+ }
+ default:
+ {
+ /* This case should never occur */
+ break;
+ }
+ } /* switch */
+} /* dlt_daemon_signal_handler() */
+
+void dlt_daemon_daemonize(int verbose)
+{
+ int i,lfp,bytes_written,ret;
+
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ dlt_log(LOG_NOTICE, "Daemon mode\n");
+
+ /* Daemonize */
+ i=fork();
+ if (i<0)
+ {
+ dlt_log(LOG_CRIT, "Unable to fork(), exiting DLT daemon\n");
+ exit(-1); /* fork error */
+ }
+
+ if (i>0)
+ {
+ exit(0); /* parent exits */
+ }
+ /* child (daemon) continues */
+
+ /* Process independency */
+
+ /* obtain a new process group */
+ if (setsid()==-1)
+ {
+ dlt_log(LOG_CRIT, "setsid() failed, exiting DLT daemon\n");
+ exit(-1); /* fork error */
+ }
+
+ /* Close descriptors */
+ for (i=getdtablesize();i>=0;--i)
+ {
+ close(i); /* close all descriptors */
+ }
+
+ /* Open standard descriptors stdin, stdout, stderr */
+ i=open("/dev/null",O_RDWR); /* open stdin */
+ ret=dup(i); /* stdout */
+ ret=dup(i); /* stderr */
+
+ /* Set umask */
+ umask(DLT_DAEMON_UMASK);
+
+ /* Change to known directory */
+ ret=chdir(DLT_USER_DIR);
+
+ /* Ensure single copy of daemon;
+ run only one instance at a time */
+ lfp=open(DLT_DAEMON_LOCK_FILE,O_RDWR|O_CREAT,DLT_DAEMON_LOCK_FILE_PERM);
+ if (lfp<0)
+ {
+ dlt_log(LOG_CRIT, "can't open lock file, exiting DLT daemon\n");
+ exit(-1); /* can not open */
+ }
+ if (lockf(lfp,F_TLOCK,0)<0)
+ {
+ dlt_log(LOG_CRIT, "can't lock lock file, exiting DLT daemon\n");
+ exit(-1); /* can not lock */
+ }
+ /* only first instance continues */
+
+ sprintf(str,"%d\n",getpid());
+ bytes_written=write(lfp,str,strlen(str)); /* record pid to lockfile */
+
+ /* Catch signals */
+ signal(SIGCHLD,SIG_IGN); /* ignore child */
+ signal(SIGTSTP,SIG_IGN); /* ignore tty signals */
+ signal(SIGTTOU,SIG_IGN);
+ signal(SIGTTIN,SIG_IGN);
+
+} /* dlt_daemon_daemonize() */
+
+int dlt_daemon_process_client_connect(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
+{
+ socklen_t cli_size;
+ struct sockaddr cli;
+
+ int in_sock = -1;
+
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ if ((daemon==0) || (daemon_local==0))
+ {
+ dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_client_connect()\n");
+ return -1;
+ }
+
+ /* event from TCP server socket, new connection */
+ cli_size = sizeof(cli);
+ if ((in_sock = accept(daemon_local->sock,&cli, &cli_size)) < 0)
+ {
+ dlt_log(LOG_ERR, "accept() failed!\n");
+ return -1 ;
+ }
+ //sprintf("str,"Client Connection from %s\n", inet_ntoa(cli.sin_addr));
+ //dlt_log(str);
+ FD_SET(in_sock, &(daemon_local->master)); /* add to master set */
+ if (in_sock > daemon_local->fdmax)
+ {
+ /* keep track of the maximum */
+ daemon_local->fdmax = in_sock;
+ } /* if */
+
+ daemon_local->client_connections++;
+ if (daemon_local->flags.vflag)
+ {
+ sprintf(str, "New connection to client established, #connections: %d\n",daemon_local->client_connections);
+ dlt_log(LOG_INFO, str);
+ }
+
+ if (daemon_local->client_connections==1)
+ {
+ if (daemon_local->flags.vflag)
+ {
+ dlt_log(LOG_INFO, "Send ring-buffer to client\n");
+ }
+ if (dlt_daemon_send_ringbuffer_to_client(daemon, daemon_local, verbose)==-1)
+ {
+ dlt_log(LOG_ERR,"Can't send contents of ringbuffer to clients\n");
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+int dlt_daemon_process_client_messages(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
+{
+ int bytes_to_be_removed=0;
+
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ if ((daemon==0) || (daemon_local==0))
+ {
+ dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_client_messages()\n");
+ return -1;
+ }
+
+ if (dlt_receiver_receive_socket(&(daemon_local->receiverSock))<=0)
+ {
+ close(daemon_local->receiverSock.fd);
+ FD_CLR(daemon_local->receiverSock.fd, &(daemon_local->master));
+
+ if (daemon_local->client_connections)
+ {
+ daemon_local->client_connections--;
+ }
+
+ if (daemon_local->flags.vflag)
+ {
+ sprintf(str, "Connection to client lost, #connections: %d\n",daemon_local->client_connections);
+ dlt_log(LOG_INFO, str);
+ }
+
+ /* check: return 0; */
+ }
+
+ /* Process all received messages */
+ while (dlt_message_read(&(daemon_local->msg),(uint8_t*)daemon_local->receiverSock.buf,daemon_local->receiverSock.bytesRcvd,daemon_local->flags.nflag,daemon_local->flags.vflag)==0)
+ {
+ /* Check for control message */
+ if (DLT_MSG_IS_CONTROL_REQUEST(&(daemon_local->msg)))
+ {
+ dlt_daemon_control_process_control(daemon_local->receiverSock.fd, daemon, &(daemon_local->msg), daemon_local->flags.vflag);
+ }
+
+ bytes_to_be_removed = daemon_local->msg.headersize+daemon_local->msg.datasize-sizeof(DltStorageHeader);
+ if (daemon_local->msg.found_serialheader)
+ {
+ bytes_to_be_removed += sizeof(dltSerialHeader);
+ }
+ if (daemon_local->msg.resync_offset)
+ {
+ bytes_to_be_removed += daemon_local->msg.resync_offset;
+ }
+
+ if (dlt_receiver_remove(&(daemon_local->receiverSock),bytes_to_be_removed)==-1)
+ {
+ dlt_log(LOG_ERR,"Can't remove bytes from receiver for sockets\n");
+ return -1;
+ }
+
+ } /* while */
+
+
+ if (dlt_receiver_move_to_begin(&(daemon_local->receiverSock))==-1)
+ {
+ dlt_log(LOG_ERR,"Can't move bytes to beginning of receiver buffer for sockets\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+int dlt_daemon_process_client_messages_serial(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
+{
+ int bytes_to_be_removed=0;
+
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ if ((daemon==0) || (daemon_local==0))
+ {
+ dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_client_messages_serial()\n");
+ return -1;
+ }
+
+ if (dlt_receiver_receive_fd(&(daemon_local->receiverSerial))<=0)
+ {
+ dlt_log(LOG_ERR, "dlt_receiver_receive_fd() for messages from serial interface failed!\n");
+ return -1;
+ }
+
+ /* Process all received messages */
+ while (dlt_message_read(&(daemon_local->msg),(uint8_t*)daemon_local->receiverSerial.buf,daemon_local->receiverSerial.bytesRcvd,daemon_local->flags.mflag,daemon_local->flags.vflag)==0)
+ {
+ /* Check for control message */
+ if (DLT_MSG_IS_CONTROL_REQUEST(&(daemon_local->msg)))
+ {
+ if (dlt_daemon_control_process_control(daemon_local->receiverSerial.fd, daemon, &(daemon_local->msg), daemon_local->flags.vflag)==-1)
+ {
+ dlt_log(LOG_ERR,"Can't process control messages\n");
+ return -1;
+ }
+ }
+
+ bytes_to_be_removed = daemon_local->msg.headersize+daemon_local->msg.datasize-sizeof(DltStorageHeader);
+ if (daemon_local->msg.found_serialheader)
+ {
+ bytes_to_be_removed += sizeof(dltSerialHeader);
+ }
+ if (daemon_local->msg.resync_offset)
+ {
+ bytes_to_be_removed += daemon_local->msg.resync_offset;
+ }
+
+ if (dlt_receiver_remove(&(daemon_local->receiverSerial),bytes_to_be_removed)==-1)
+ {
+ dlt_log(LOG_ERR,"Can't remove bytes from receiver for serial connection\n");
+ return -1;
+ }
+
+ } /* while */
+
+
+ if (dlt_receiver_move_to_begin(&(daemon_local->receiverSerial))==-1)
+ {
+ dlt_log(LOG_ERR,"Can't move bytes to beginning of receiver buffer for serial connection\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+int dlt_daemon_process_user_messages(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
+{
+ int offset=0;
+ int run_loop=1;
+ DltUserHeader *userheader;
+
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ if ((daemon==0) || (daemon_local==0))
+ {
+ dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_messages()\n");
+ return -1;
+ }
+
+ /* read data from FIFO */
+ if (dlt_receiver_receive_fd(&(daemon_local->receiver))<=0)
+ {
+ dlt_log(LOG_ERR, "dlt_receiver_receive_fd() for user messages failed!\n");
+ return -1;
+ }
+
+ /* look through buffer as long as data is in there */
+ do
+ {
+ if (daemon_local->receiver.bytesRcvd < sizeof(DltUserHeader))
+ {
+ break;
+ }
+
+ /* resync if necessary */
+ offset=0;
+ do
+ {
+ userheader = (DltUserHeader*) (daemon_local->receiver.buf+offset);
+
+ /* Check for user header pattern */
+ if (dlt_user_check_userheader(userheader))
+ {
+ break;
+ }
+
+ offset++;
+
+ }
+ while ((sizeof(DltUserHeader)+offset)<=daemon_local->receiver.bytesRcvd);
+
+ /* Check for user header pattern */
+ if (dlt_user_check_userheader(userheader)==0)
+ {
+ break;
+ }
+
+ /* Set new start offset */
+ if (offset>0)
+ {
+ daemon_local->receiver.buf+=offset;
+ daemon_local->receiver.bytesRcvd-=offset;
+ }
+
+ switch (userheader->message)
+ {
+ case DLT_USER_MESSAGE_OVERFLOW:
+ {
+ if (dlt_daemon_process_user_message_overflow(daemon, daemon_local, daemon_local->flags.vflag)==-1)
+ {
+ run_loop=0;
+ }
+ break;
+ }
+ case DLT_USER_MESSAGE_REGISTER_CONTEXT:
+ {
+ if (dlt_daemon_process_user_message_register_context(daemon, daemon_local, daemon_local->flags.vflag)==-1)
+ {
+ run_loop=0;
+ }
+ break;
+ }
+ case DLT_USER_MESSAGE_UNREGISTER_CONTEXT:
+ {
+ if (dlt_daemon_process_user_message_unregister_context(daemon, daemon_local, daemon_local->flags.vflag)==-1)
+ {
+ run_loop=0;
+ }
+ break;
+ }
+ case DLT_USER_MESSAGE_LOG:
+ {
+ if (dlt_daemon_process_user_message_log(daemon, daemon_local, daemon_local->flags.vflag)==-1)
+ {
+ run_loop=0;
+ }
+ break;
+ }
+ case DLT_USER_MESSAGE_REGISTER_APPLICATION:
+ {
+ if (dlt_daemon_process_user_message_register_application(daemon, daemon_local, daemon_local->flags.vflag)==-1)
+ {
+ run_loop=0;
+ }
+ break;
+ }
+ case DLT_USER_MESSAGE_UNREGISTER_APPLICATION:
+ {
+ if (dlt_daemon_process_user_message_unregister_application(daemon, daemon_local, daemon_local->flags.vflag)==-1)
+ {
+ run_loop=0;
+ }
+ break;
+ }
+ case DLT_USER_MESSAGE_APP_LL_TS:
+ {
+ if (dlt_daemon_process_user_message_set_app_ll_ts(daemon, daemon_local, daemon_local->flags.vflag)==-1)
+ {
+ run_loop=0;
+ }
+ break;
+ }
+ default:
+ {
+ dlt_log(LOG_ERR,"(Internal) Invalid user message type received!\n");
+
+ /* remove user header */
+ if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader))==-1)
+ {
+ dlt_log(LOG_ERR,"Can't remove bytes from receiver for user messages\n");
+ return -1;
+ }
+
+ /* In next invocation of do-while loop, a resync will be triggered if additional data was received */
+ run_loop=0;
+
+ break;
+ }
+ }
+
+ }
+ while (run_loop);
+
+ /* keep not read data in buffer */
+ if (dlt_receiver_move_to_begin(&(daemon_local->receiver))==-1)
+ {
+ dlt_log(LOG_ERR,"Can't move bytes to beginning of receiver buffer for user messages\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+int dlt_daemon_process_user_message_overflow(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
+{
+ int j, sent;
+
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ if ((daemon==0) || (daemon_local==0))
+ {
+ dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_overflow()\n");
+ return -1;
+ }
+
+ /* Store in daemon, that a message buffer overflow has occured */
+ daemon->message_buffer_overflow = DLT_MESSAGE_BUFFER_OVERFLOW;
+
+ /* look if TCP connection to client is available */
+ sent = 0;
+
+ for (j = 0; j <= daemon_local->fdmax; j++)
+ {
+ /* send to everyone! */
+ if (FD_ISSET(j, &(daemon_local->master)))
+ {
+ /* except the listener and ourselves */
+ if ((j != daemon_local->fp) && (j != daemon_local->sock))
+ {
+ dlt_daemon_control_message_buffer_overflow(j, daemon, verbose);
+ sent=1;
+ /* Reset overflow state */
+ daemon->message_buffer_overflow = DLT_MESSAGE_BUFFER_NO_OVERFLOW;
+ } /* if */
+ } /* if */
+ } /* for */
+
+ /* message was not sent, so store it in ringbuffer */
+ if (sent==0)
+ {
+ dlt_daemon_control_message_buffer_overflow(DLT_DAEMON_STORE_TO_BUFFER, daemon, verbose);
+ }
+
+ /* keep not read data in buffer */
+ if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader))==-1)
+ {
+ dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message overflow\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+int dlt_daemon_process_user_message_register_application(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
+{
+ uint32_t len=0;
+ DltDaemonApplication *application;
+ char description[DLT_DAEMON_DESCSIZE];
+ DltUserControlMsgRegisterApplication *usercontext;
+
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ if ((daemon==0) || (daemon_local==0))
+ {
+ dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_register_application()\n");
+ return -1;
+ }
+
+ if (daemon_local->receiver.bytesRcvd < (sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterApplication)))
+ {
+ /* Not enough bytes received */
+ return -1;
+ }
+
+ usercontext = (DltUserControlMsgRegisterApplication*) (daemon_local->receiver.buf+sizeof(DltUserHeader));
+
+ memset(description,0,sizeof(description));
+
+ len=usercontext->description_length;
+ if ((len>0) && (len<=DLT_DAEMON_DESCSIZE))
+ {
+ /* Read and store application description */
+ strncpy(description, (daemon_local->receiver.buf+sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterApplication)), len);
+ }
+
+ application=dlt_daemon_application_add(daemon,usercontext->apid,usercontext->pid,description,verbose);
+
+ /* keep not read data in buffer */
+ if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterApplication)+len)==-1)
+ {
+ dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register application\n");
+ return -1;
+ }
+
+ if (application==0)
+ {
+ dlt_log(LOG_CRIT,"Can't add application");
+ return -1;
+ }
+
+ return 0;
+}
+
+int dlt_daemon_process_user_message_register_context(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
+{
+ uint32_t len=0;
+ int8_t loglevel, tracestatus;
+ DltUserControlMsgRegisterContext *usercontext;
+ char description[DLT_DAEMON_DESCSIZE];
+ DltDaemonApplication *application;
+ DltDaemonContext *context;
+ DltServiceGetLogInfoRequest *req;
+
+ DltMessage msg;
+ int j;
+ int sent;
+
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ if ((daemon==0) || (daemon_local==0))
+ {
+ dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_register_context()\n");
+ return -1;
+ }
+
+ if (daemon_local->receiver.bytesRcvd < (sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)))
+ {
+ /* Not enough bytes received */
+ return -1;
+ }
+
+ usercontext = (DltUserControlMsgRegisterContext*) (daemon_local->receiver.buf+sizeof(DltUserHeader));
+
+ memset(description,0,sizeof(description));
+
+ len=usercontext->description_length;
+ if ((len>0) && (len<=DLT_DAEMON_DESCSIZE))
+ {
+ /* Read and store context description */
+ strncpy(description, (daemon_local->receiver.buf+sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)), len);
+ }
+
+ application = dlt_daemon_application_find(daemon,usercontext->apid,verbose);
+
+ if (application==0)
+ {
+ dlt_log(LOG_ERR, "Application not found in dlt_daemon_process_user_message_register_context()\n");
+ if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)+len)==-1)
+ {
+ dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register context\n");
+ return -1;
+ }
+ return 0;
+ }
+
+ /* Pre-set loglevel */
+ if (usercontext->log_level == DLT_USER_LOG_LEVEL_NOT_SET)
+ {
+ loglevel=DLT_LOG_DEFAULT;
+ }
+ else
+ {
+ loglevel=usercontext->log_level;
+ /* Plausibility check */
+ if ((loglevel<DLT_LOG_DEFAULT) || (loglevel>DLT_LOG_VERBOSE))
+ {
+ if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)+len)==-1)
+ {
+ dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register context\n");
+ }
+ return -1;
+ }
+ }
+
+ /* Pre-set tracestatus */
+ if (usercontext->trace_status == DLT_USER_TRACE_STATUS_NOT_SET)
+ {
+ tracestatus=DLT_TRACE_STATUS_DEFAULT;
+ }
+ else
+ {
+ tracestatus=usercontext->trace_status;
+
+ /* Plausibility check */
+ if ((tracestatus<DLT_TRACE_STATUS_DEFAULT) || (tracestatus>DLT_TRACE_STATUS_ON))
+ {
+ if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)+len)==-1)
+ {
+ dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register context\n");
+ }
+ return -1;
+ }
+ }
+
+ context = dlt_daemon_context_add(daemon,usercontext->apid,usercontext->ctid, loglevel, tracestatus, usercontext->log_level_pos,application->user_handle,description,verbose);
+
+ if (context==0)
+ {
+ if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)+len)==-1)
+ {
+ dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register context\n");
+ }
+
+ dlt_log(LOG_CRIT,"Can't add context");
+ return -1;
+ }
+ /* Create automatic get log info response for registered context */
+ if (daemon_local->flags.rflag)
+ {
+ /* Prepare request for get log info with one application and one context */
+ if (dlt_message_init(&msg, verbose)==-1)
+ {
+ dlt_log(LOG_ERR,"Can't initialize message");
+ return -1;
+ }
+
+ msg.datasize = sizeof(DltServiceGetLogInfoRequest);
+ if (msg.databuffer)
+ {
+ free(msg.databuffer);
+ }
+ msg.databuffer = (uint8_t *) malloc(msg.datasize);
+ if (msg.databuffer==0)
+ {
+ dlt_log(LOG_ERR,"Can't allocate buffer for get log info message\n");
+ return -1;
+ }
+
+ req = (DltServiceGetLogInfoRequest*) msg.databuffer;
+
+ req->service_id = DLT_SERVICE_ID_GET_LOG_INFO;
+ req->options = 7;
+ dlt_set_id(req->apid, usercontext->apid);
+ dlt_set_id(req->ctid, usercontext->ctid);
+ dlt_set_id(req->com,"remo");
+
+ sent=0;
+
+ /* Send response to get log info request to DLT clients */
+ for (j = 0; j <= daemon_local->fdmax; j++)
+ {
+ /* send to everyone! */
+ if (FD_ISSET(j, &(daemon_local->master)))
+ {
+ /* except the listener and ourselves */
+ if ((j != daemon_local->fp) && (j != daemon_local->sock))
+ {
+ dlt_daemon_control_get_log_info(j , daemon, &msg, verbose);
+ sent=1;
+ }
+ }
+ }
+
+ if (sent==0)
+ {
+ /* Store to buffer */
+ dlt_daemon_control_get_log_info(DLT_DAEMON_STORE_TO_BUFFER , daemon, &msg, verbose);
+ }
+
+ dlt_message_free(&msg, verbose);
+ }
+
+ if (context->user_handle!=0)
+ {
+ /* This call also replaces the default values with the values defined for default */
+ if (dlt_daemon_user_send_log_level(daemon, context, verbose)==-1)
+ {
+ dlt_log(LOG_ERR,"Can't send current log level as response to user message register context\n");
+ return -1;
+ }
+ }
+
+ /* keep not read data in buffer */
+ if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)+len)==-1)
+ {
+ dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register context\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+int dlt_daemon_process_user_message_unregister_application(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
+{
+ DltUserControlMsgUnregisterApplication *usercontext;
+ DltDaemonApplication *application;
+ DltDaemonContext *context;
+ int i, offset_base;
+
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ if ((daemon==0) || (daemon_local==0))
+ {
+ dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_unregister_application()\n");
+ return -1;
+ }
+
+ if (daemon_local->receiver.bytesRcvd < (sizeof(DltUserHeader)+sizeof(DltUserControlMsgUnregisterApplication)))
+ {
+ /* Not enough bytes received */
+ return -1;
+ }
+
+ if (daemon->num_applications>0)
+ {
+ usercontext = (DltUserControlMsgUnregisterApplication*) (daemon_local->receiver.buf+sizeof(DltUserHeader));
+
+ /* Delete this application and all corresponding contexts for this application from internal table */
+ application = dlt_daemon_application_find(daemon,usercontext->apid, verbose);
+
+ if (application)
+ {
+ /* Calculate start offset within contexts[] */
+ offset_base=0;
+ for (i=0; i<(application-(daemon->applications)); i++)
+ {
+ offset_base+=daemon->applications[i].num_contexts;
+ }
+
+ for (i=application->num_contexts-1; i>=0; i--)
+ {
+ context = &(daemon->contexts[offset_base+i]);
+ if (context)
+ {
+ /* Delete context */
+ if (dlt_daemon_context_del(daemon, context, verbose)==-1)
+ {
+ dlt_log(LOG_ERR,"Can't delete context for user message unregister application\n");
+ return -1;
+ }
+ }
+ }
+
+ /* Delete this application entry from internal table*/
+ if (dlt_daemon_application_del(daemon, application, verbose)==-1)
+ {
+ dlt_log(LOG_ERR,"Can't delete application for user message unregister application\n");
+ return -1;
+ }
+ }
+ }
+
+ /* keep not read data in buffer */
+ if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgUnregisterApplication))==-1)
+ {
+ dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message unregister application\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+int dlt_daemon_process_user_message_unregister_context(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
+{
+ DltUserControlMsgUnregisterContext *usercontext;
+ DltDaemonContext *context;
+
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ if ((daemon==0) || (daemon_local==0))
+ {
+ dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_unregister_context()\n");
+ return -1;
+ }
+
+ if (daemon_local->receiver.bytesRcvd < (sizeof(DltUserHeader)+sizeof(DltUserControlMsgUnregisterContext)))
+ {
+ /* Not enough bytes received */
+ return -1;
+ }
+
+ usercontext = (DltUserControlMsgUnregisterContext*) (daemon_local->receiver.buf+sizeof(DltUserHeader));
+ context = dlt_daemon_context_find(daemon,usercontext->apid, usercontext->ctid, verbose);
+
+ if (context)
+ {
+ /* Delete this connection entry from internal table*/
+ if (dlt_daemon_context_del(daemon, context, verbose)==-1)
+ {
+ dlt_log(LOG_ERR,"Can't delete context for user message unregister context\n");
+ return -1;
+ }
+ }
+
+ /* keep not read data in buffer */
+ if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgUnregisterContext))==-1)
+ {
+ dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message unregister context\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+int dlt_daemon_process_user_message_log(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
+{
+ int bytes_to_be_removed;
+ int j,sent,third_value;
+ ssize_t ret;
+
+ static char text[DLT_DAEMON_TEXTSIZE];
+
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ if ((daemon==0) || (daemon_local==0))
+ {
+ dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_log()\n");
+ return -1;
+ }
+
+ if (dlt_message_read(&(daemon_local->msg),(unsigned char*)daemon_local->receiver.buf+sizeof(DltUserHeader),daemon_local->receiver.bytesRcvd-sizeof(DltUserHeader),0,verbose)==0)
+ {
+ /* set overwrite ecu id */
+ if (daemon_local->flags.evalue!=0)
+ {
+ /* Set header extra parameters */
+ dlt_set_id(daemon_local->msg.headerextra.ecu, daemon->ecuid );
+ //msg.headerextra.seid = 0;
+ if (dlt_message_set_extraparameters(&(daemon_local->msg),0)==-1)
+ {
+ dlt_log(LOG_ERR,"Can't set message extra parameters in process user message log\n");
+ return -1;
+ }
+
+ /* Correct value of timestamp, this was changed by dlt_message_set_extraparameters() */
+ daemon_local->msg.headerextra.tmsp = DLT_BETOH_32(daemon_local->msg.headerextra.tmsp);
+ }
+
+ /* prepare storage header */
+ if (DLT_IS_HTYP_WEID(daemon_local->msg.standardheader->htyp))
+ {
+ if (dlt_set_storageheader(daemon_local->msg.storageheader,daemon_local->msg.headerextra.ecu)==-1)
+ {
+ dlt_log(LOG_ERR,"Can't set storage header in process user message log\n");
+ return -1;
+ }
+ }
+ else
+ {
+ if (dlt_set_storageheader(daemon_local->msg.storageheader,daemon->ecuid)==-1)
+ {
+ dlt_log(LOG_ERR,"Can't set storage header in process user message log\n");
+ return -1;
+ }
+ }
+
+ if ((daemon_local->flags.fvalue==0) ||
+ (daemon_local->flags.fvalue && (dlt_message_filter_check(&(daemon_local->msg),&(daemon_local->filter),verbose)==1)))
+ {
+ /* if no filter set or filter is matching display message */
+ if (daemon_local->flags.xflag)
+ {
+ if (dlt_message_print_hex(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1)
+ {
+ dlt_log(LOG_ERR,"dlt_message_print_hex() failed!\n");
+ }
+ } /* if */
+ else if (daemon_local->flags.aflag)
+ {
+ if (dlt_message_print_ascii(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1)
+ {
+ dlt_log(LOG_ERR,"dlt_message_print_ascii() failed!\n");
+ }
+ } /* if */
+ else if (daemon_local->flags.sflag)
+ {
+ if (dlt_message_print_header(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1)
+ {
+ dlt_log(LOG_ERR,"dlt_message_print_header() failed!\n");
+ }
+ /* print message header only */
+ } /* if */
+
+ /* if file output enabled write message */
+ if (daemon_local->flags.ovalue)
+ {
+ /* write message to output buffer */
+ if (dlt_user_log_out2(daemon_local->ohandle,
+ daemon_local->msg.headerbuffer,
+ daemon_local->msg.headersize,
+ daemon_local->msg.databuffer,
+ daemon_local->msg.datasize) !=DLT_RETURN_OK)
+ {
+ dlt_log(LOG_ERR,"Writing to output file failed!\n");
+ }
+ } /* if */
+
+ sent=0;
+
+ /* look if TCP connection to client is available */
+ for (j = 0; j <= daemon_local->fdmax; j++)
+ {
+ /* send to everyone! */
+ if (FD_ISSET(j, &(daemon_local->master)))
+ {
+ /* except the listener and ourselves */
+ if (daemon_local->flags.yvalue!=0)
+ {
+ third_value = daemon_local->fdserial;
+ }
+ else
+ {
+ third_value = daemon_local->sock;
+ }
+
+ if ((j != daemon_local->fp) && (j != daemon_local->sock) && (j != third_value))
+ {
+ DLT_DAEMON_SEM_LOCK();
+
+ if (daemon_local->flags.lflag)
+ {
+ send(j,dltSerialHeader,sizeof(dltSerialHeader),0);
+ }
+
+ send(j,daemon_local->msg.headerbuffer+sizeof(DltStorageHeader),daemon_local->msg.headersize-sizeof(DltStorageHeader),0);
+ send(j,daemon_local->msg.databuffer,daemon_local->msg.datasize,0);
+
+ DLT_DAEMON_SEM_FREE();
+
+ sent=1;
+ } /* if */
+ else if ((j == daemon_local->fdserial) && (daemon_local->flags.yvalue!=0))
+ {
+ DLT_DAEMON_SEM_LOCK();
+
+ if (daemon_local->flags.lflag)
+ {
+ ret=write(j,dltSerialHeader,sizeof(dltSerialHeader));
+ }
+
+ ret=write(j,daemon_local->msg.headerbuffer+sizeof(DltStorageHeader),daemon_local->msg.headersize-sizeof(DltStorageHeader));
+ ret=write(j,daemon_local->msg.databuffer,daemon_local->msg.datasize);
+
+ DLT_DAEMON_SEM_FREE();
+
+ sent=1;
+ }
+ } /* if */
+ } /* for */
+
+ /* Message was not sent to client, so store it in client ringbuffer */
+ if (sent==0)
+ {
+ if (dlt_ringbuffer_put3(&(daemon->client_ringbuffer),
+ daemon_local->msg.headerbuffer+sizeof(DltStorageHeader),daemon_local->msg.headersize-sizeof(DltStorageHeader),
+ daemon_local->msg.databuffer,daemon_local->msg.datasize,
+ 0, 0
+ )<0)
+ {
+ dlt_log(LOG_ERR,"Storage of message in history buffer failed! Message discarded.\n");
+ }
+ }
+
+ }
+ /* keep not read data in buffer */
+ bytes_to_be_removed = daemon_local->msg.headersize+daemon_local->msg.datasize-sizeof(DltStorageHeader)+sizeof(DltUserHeader);
+ if (daemon_local->msg.found_serialheader)
+ {
+ bytes_to_be_removed += sizeof(dltSerialHeader);
+ }
+
+ if (dlt_receiver_remove(&(daemon_local->receiver),bytes_to_be_removed)==-1)
+ {
+ dlt_log(LOG_ERR,"Can't remove bytes from receiver\n");
+ return -1;
+ }
+ }
+ else
+ {
+ dlt_log(LOG_ERR,"Can't read messages from receiver\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+int dlt_daemon_process_user_message_set_app_ll_ts(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
+{
+ DltUserControlMsgAppLogLevelTraceStatus *usercontext;
+ DltDaemonApplication *application;
+ DltDaemonContext *context;
+ int i, offset_base;
+ int8_t old_log_level, old_trace_status;
+
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ if ((daemon==0) || (daemon_local==0))
+ {
+ dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_set_app_ll_ts()\n");
+ return -1;
+ }
+
+ if (daemon_local->receiver.bytesRcvd < (sizeof(DltUserHeader)+sizeof(DltUserControlMsgAppLogLevelTraceStatus )))
+ {
+ /* Not enough bytes receeived */
+ return -1;
+ }
+
+ if (daemon->num_applications>0)
+ {
+ usercontext = (DltUserControlMsgAppLogLevelTraceStatus*) (daemon_local->receiver.buf+sizeof(DltUserHeader));
+
+ /* Get all contexts with application id matching the received application id */
+ application = dlt_daemon_application_find(daemon, usercontext->apid, verbose);
+ if (application)
+ {
+ /* Calculate start offset within contexts[] */
+ offset_base=0;
+ for (i=0; i<(application-(daemon->applications)); i++)
+ {
+ offset_base+=daemon->applications[i].num_contexts;
+ }
+
+ for (i=0; i < application->num_contexts; i++)
+ {
+ context = &(daemon->contexts[offset_base+i]);
+ if (context)
+ {
+ old_log_level = context->log_level;
+ context->log_level = usercontext->log_level; /* No endianess conversion necessary*/
+
+ old_trace_status = context->trace_status;
+ context->trace_status = usercontext->trace_status; /* No endianess conversion necessary */
+
+ /* The folowing function sends also the trace status */
+ if ((context->user_handle==0) ||
+ (dlt_daemon_user_send_log_level(daemon, context, verbose)!=0))
+ {
+ context->log_level = old_log_level;
+ context->trace_status = old_trace_status;
+ }
+ }
+ }
+ }
+ }
+
+ /* keep not read data in buffer */
+ if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgAppLogLevelTraceStatus))==-1)
+ {
+ dlt_log(LOG_ERR,"Can't remove bytes from receiver\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+int dlt_daemon_send_ringbuffer_to_client(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose)
+{
+ static uint8_t data[DLT_DAEMON_RINGBUFFER_SIZE];
+ size_t length=0;
+ int j, third_value;
+ ssize_t ret;
+
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ if ((daemon==0) || (daemon_local==0))
+ {
+ dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_send_ringbuffer_to_client()\n");
+ return -1;
+ }
+
+ /* Attention: If the message can't be send at this time, it will be silently discarded. */
+ while ((dlt_ringbuffer_get(&(daemon->client_ringbuffer), data, &length ))!=-1)
+ {
+ /* look if TCP connection to client is available */
+ for (j = 0; j <= daemon_local->fdmax; j++)
+ {
+ /* send to everyone! */
+ if (FD_ISSET(j, &(daemon_local->master)))
+ {
+ /* except the listener and ourselves */
+ if (daemon_local->flags.yvalue!=0)
+ {
+ third_value = daemon_local->fdserial;
+ }
+ else
+ {
+ third_value = daemon_local->sock;
+ }
+
+ if ((j != daemon_local->fp) && (j != daemon_local->sock) && (j != third_value))
+ {
+ DLT_DAEMON_SEM_LOCK();
+
+ if (daemon_local->flags.lflag)
+ {
+ send(j,dltSerialHeader,sizeof(dltSerialHeader),0);
+ }
+ send(j,data,length,0);
+
+ DLT_DAEMON_SEM_FREE();
+
+ } /* if */
+ else if ((j == daemon_local->fdserial) && (daemon_local->flags.yvalue!=0))
+ {
+ DLT_DAEMON_SEM_LOCK();
+
+ if (daemon_local->flags.lflag)
+ {
+ ret=write(j,dltSerialHeader,sizeof(dltSerialHeader));
+ }
+ ret=write(j,data,length);
+
+ DLT_DAEMON_SEM_LOCK();
+ }
+ } /* if */
+ } /* for */
+ }
+
+ return 0;
+}
+
+void dlt_daemon_timingpacket_thread(void *ptr)
+{
+ DltDaemonPeriodicData info;
+ int j;
+
+ DltDaemonTimingPacketThreadData *data;
+ DltDaemon *daemon;
+ DltDaemonLocal *daemon_local;
+
+ if (ptr==0)
+ {
+ dlt_log(LOG_ERR, "No data pointer passed to timingpacket thread\n");
+ return;
+ }
+
+ data = (DltDaemonTimingPacketThreadData*)ptr;
+ daemon = data->daemon;
+ daemon_local = data->daemon_local;
+
+ if ((daemon==0) || (daemon_local==0))
+ {
+ dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_timingpacket_thread()");
+ return;
+ }
+
+ if (dlt_daemon_make_periodic (1000000, &info, daemon_local->flags.vflag)<0)
+ {
+ dlt_log(LOG_CRIT,"Can't initialize thread timer!\n");
+ return;
+ }
+
+ while (1)
+ {
+ /* If enabled, send timing packets to all clients */
+ if (daemon->timingpackets)
+ {
+ for (j = 0; j <= daemon_local->fdmax; j++)
+ {
+ /* send to everyone! */
+ if (FD_ISSET(j, &(daemon_local->master)))
+ {
+ /* except the listener and ourselves */
+ if ((j != daemon_local->fp) && (j != daemon_local->sock))
+ {
+ dlt_daemon_control_message_time(j, daemon, daemon_local->flags.vflag);
+ }
+ }
+ }
+ }
+ /* Wait for next period */
+ dlt_daemon_wait_period (&info, daemon_local->flags.vflag);
+ }
+}
+
+int dlt_daemon_make_periodic (unsigned int period, DltDaemonPeriodicData *info, int verbose)
+{
+ int ret;
+ unsigned int ns;
+ unsigned int sec;
+ int fd;
+ struct itimerspec itval;
+
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ if (info==0)
+ {
+ dlt_log(LOG_ERR,"No data pointer passed!\n");
+ return -1;
+ }
+
+ /* Create the timer */
+ fd = timerfd_create (CLOCK_MONOTONIC, 0);
+
+ info->wakeups_missed = 0;
+ info->timer_fd = fd;
+
+ if (fd == -1)
+ {
+ dlt_log(LOG_ERR,"Can't create timer filedescriptor");
+ return -1;
+ }
+
+ /* Make the timer periodic */
+ sec = period/1000000;
+ ns = (period - (sec * 1000000)) * 1000;
+ itval.it_interval.tv_sec = sec;
+ itval.it_interval.tv_nsec = ns;
+ itval.it_value.tv_sec = sec;
+ itval.it_value.tv_nsec = ns;
+
+ ret = timerfd_settime (fd, 0, &itval, NULL);
+
+ return ret;
+}
+
+void dlt_daemon_wait_period (DltDaemonPeriodicData *info, int verbose)
+{
+ unsigned long long missed;
+ int ret;
+
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ ret = read (info->timer_fd, &missed, sizeof (missed));
+
+ if (missed > 0)
+ {
+ info->wakeups_missed += (missed - 1);
+ }
+}
+
+/**
+ \}
+*/
diff --git a/src/daemon/dlt-daemon.h b/src/daemon/dlt-daemon.h
new file mode 100755
index 0000000..e229df5
--- /dev/null
+++ b/src/daemon/dlt-daemon.h
@@ -0,0 +1,173 @@
+/*
+ * Dlt- Diagnostic Log and Trace daemon
+ * @licence app begin@
+ *
+ * Copyright (C) 2011, BMW AG - Alexander Wenzel <alexander.wenzel@bmw.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under the terms of the
+ * GNU Lesser General Public License, version 2.1, as published by the Free Software Foundation.
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
+ * Public License, version 2.1, for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License, version 2.1, along
+ * with this program; if not, see <http://www.gnu.org/licenses/lgpl-2.1.html>.
+ *
+ * Note that the copyright holders assume that the GNU Lesser General Public License, version 2.1, may
+ * also be applicable to programs even in cases in which the program is not a library in the technical sense.
+ *
+ * Linking DLT statically or dynamically with other modules is making a combined work based on DLT. You may
+ * license such other modules under the GNU Lesser General Public License, version 2.1. If you do not want to
+ * license your linked modules under the GNU Lesser General Public License, version 2.1, you
+ * may use the program under the following exception.
+ *
+ * As a special exception, the copyright holders of DLT give you permission to combine DLT
+ * with software programs or libraries that are released under any license unless such a combination is not
+ * permitted by the license of such a software program or library. You may copy and distribute such a
+ * system following the terms of the GNU Lesser General Public License, version 2.1, including this
+ * special exception, for DLT and the licenses of the other code concerned.
+ *
+ * Note that people who make modified versions of DLT are not obligated to grant this special exception
+ * for their modified versions; it is their choice whether to do so. The GNU Lesser General Public License,
+ * version 2.1, gives permission to release a modified version without this exception; this exception
+ * also makes it possible to release a modified version which carries forward this exception.
+ *
+ * @licence end@
+ */
+
+
+/*******************************************************************************
+** **
+** SRC-MODULE: dlt-daemon.h **
+** **
+** TARGET : linux **
+** **
+** PROJECT : DLT **
+** **
+** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de **
+** Markus Klein **
+** **
+** PURPOSE : **
+** **
+** REMARKS : **
+** **
+** PLATFORM DEPENDANT [yes/no]: yes **
+** **
+** TO BE CHANGED BY USER [yes/no]: no **
+** **
+*******************************************************************************/
+
+/*******************************************************************************
+** Author Identity **
+********************************************************************************
+** **
+** Initials Name Company **
+** -------- ------------------------- ---------------------------------- **
+** aw Alexander Wenzel BMW **
+** mk Markus Klein Fraunhofer ESK **
+*******************************************************************************/
+
+/*******************************************************************************
+** Author Identity **
+********************************************************************************
+** **
+** Initials Name Company **
+** -------- ------------------------- ---------------------------------- **
+** aw Alexander Wenzel BMW **
+** mk Markus Klein Fraunhofer ESK **
+*******************************************************************************/
+
+#ifndef DLT_DAEMON_H
+#define DLT_DAEMON_H
+
+#include "dlt_daemon_common.h"
+#include "dlt_user_shared.h"
+#include "dlt_user_shared_cfg.h"
+
+/**
+ * The flags of a dlt daemon.
+ */
+typedef struct
+{
+ int aflag; /**< (Boolean) Print DLT messages; payload as ASCII */
+ int sflag; /**< (Boolean) Print DLT messages; payload as hex */
+ int xflag; /**< (Boolean) Print DLT messages; only headers */
+ int vflag; /**< (Boolean) Verbose mode */
+ int dflag; /**< (Boolean) Daemonize */
+ int lflag; /**< (Boolean) Send DLT messages with serial header */
+ int rflag; /**< (Boolean) Send automatic get log info response during context registration */
+ int mflag; /**< (Boolean) Sync to serial header on serial connection */
+ int nflag; /**< (Boolean) Sync to serial header on all TCP connections */
+ char *ovalue; /**< (String: Filename) Store DLT messages to local log file */
+ char *fvalue; /**< (String: Filename) Enable filtering of messages */
+ char *evalue; /**< (String: ECU ID) Set ECU ID (Default: ECU1) */
+ char *bvalue; /**< (String: Baudrate) Serial device baudrate (Default: 115200) */
+ char *yvalue; /**< (String: Devicename) Additional support for serial device */
+ char *uvalue; /**< (String: Ringbuffer) Size of the ringbuffer in bytes (Default: 10024) */
+} DltDaemonFlags;
+
+/**
+ * The global parameters of a dlt daemon.
+ */
+typedef struct
+{
+ DltDaemonFlags flags; /**< flags of the daemon */
+ int fp; /**< handle for own fifo */
+ int sock; /**< handle for tcp connection to client */
+ int fdserial; /**< handle for serial connection */
+ int fdmax; /**< highest number of used handles */
+ fd_set master; /**< master set of handles */
+ fd_set read_fds; /**< read set of handles */
+ DltFile file; /**< struct for file access */
+ DltFilter filter; /**< struct for filter access */
+ int ohandle; /**< handle to output file */
+ DltMessage msg; /**< one dlt message */
+ DltReceiver receiver; /**< receiver for fifo connection */
+ DltReceiver receiverSock; /**< receiver for socket connection */
+ DltReceiver receiverSerial; /**< receiver for serial connection */
+ int client_connections; /**< counter for nr. of client connections */
+ size_t baudrate; /**< Baudrate of serial connection */
+ size_t ringbufferSize; /**< Size of the ringbuffer */
+} DltDaemonLocal;
+
+typedef struct
+{
+ int timer_fd;
+ unsigned long long wakeups_missed;
+} DltDaemonPeriodicData;
+
+typedef struct
+{
+ DltDaemon *daemon;
+ DltDaemonLocal *daemon_local;
+} DltDaemonTimingPacketThreadData;
+
+/* Function prototypes */
+void dlt_daemon_local_cleanup(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose);
+int dlt_daemon_local_init_p1(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose);
+int dlt_daemon_local_init_p2(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose);
+int dlt_daemon_local_connection_init(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose);
+
+void dlt_daemon_daemonize(int verbose);
+void dlt_daemon_signal_handler(int sig);
+
+int dlt_daemon_process_client_connect(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose);
+int dlt_daemon_process_client_messages(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose);
+int dlt_daemon_process_client_messages_serial(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose);
+int dlt_daemon_process_user_messages(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose);
+
+int dlt_daemon_process_user_message_overflow(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose);
+int dlt_daemon_process_user_message_register_application(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose);
+int dlt_daemon_process_user_message_unregister_application(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose);
+int dlt_daemon_process_user_message_register_context(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose);
+int dlt_daemon_process_user_message_unregister_context(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose);
+int dlt_daemon_process_user_message_log(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose);
+int dlt_daemon_process_user_message_set_app_ll_ts(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose);
+int dlt_daemon_send_ringbuffer_to_client(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose);
+
+void dlt_daemon_timingpacket_thread(void *ptr);
+int dlt_daemon_make_periodic (unsigned int period, DltDaemonPeriodicData *info, int verbose);
+void dlt_daemon_wait_period(DltDaemonPeriodicData *info, int verbose);
+
+#endif /* DLT_DAEMON_H */
+
diff --git a/src/daemon/dlt-daemon_cfg.h b/src/daemon/dlt-daemon_cfg.h
new file mode 100755
index 0000000..c69c1a1
--- /dev/null
+++ b/src/daemon/dlt-daemon_cfg.h
@@ -0,0 +1,125 @@
+/*
+ * Dlt- Diagnostic Log and Trace daemon
+ * @licence app begin@
+ *
+ * Copyright (C) 2011, BMW AG - Alexander Wenzel <alexander.wenzel@bmw.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under the terms of the
+ * GNU Lesser General Public License, version 2.1, as published by the Free Software Foundation.
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
+ * Public License, version 2.1, for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License, version 2.1, along
+ * with this program; if not, see <http://www.gnu.org/licenses/lgpl-2.1.html>.
+ *
+ * Note that the copyright holders assume that the GNU Lesser General Public License, version 2.1, may
+ * also be applicable to programs even in cases in which the program is not a library in the technical sense.
+ *
+ * Linking DLT statically or dynamically with other modules is making a combined work based on DLT. You may
+ * license such other modules under the GNU Lesser General Public License, version 2.1. If you do not want to
+ * license your linked modules under the GNU Lesser General Public License, version 2.1, you
+ * may use the program under the following exception.
+ *
+ * As a special exception, the copyright holders of DLT give you permission to combine DLT
+ * with software programs or libraries that are released under any license unless such a combination is not
+ * permitted by the license of such a software program or library. You may copy and distribute such a
+ * system following the terms of the GNU Lesser General Public License, version 2.1, including this
+ * special exception, for DLT and the licenses of the other code concerned.
+ *
+ * Note that people who make modified versions of DLT are not obligated to grant this special exception
+ * for their modified versions; it is their choice whether to do so. The GNU Lesser General Public License,
+ * version 2.1, gives permission to release a modified version without this exception; this exception
+ * also makes it possible to release a modified version which carries forward this exception.
+ *
+ * @licence end@
+ */
+
+
+/*******************************************************************************
+** **
+** SRC-MODULE: dlt-daemon-cfg.h **
+** **
+** TARGET : linux **
+** **
+** PROJECT : DLT **
+** **
+** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de **
+** Markus Klein **
+** **
+** PURPOSE : **
+** **
+** REMARKS : **
+** **
+** PLATFORM DEPENDANT [yes/no]: yes **
+** **
+** TO BE CHANGED BY USER [yes/no]: no **
+** **
+*******************************************************************************/
+
+/*******************************************************************************
+** Author Identity **
+********************************************************************************
+** **
+** Initials Name Company **
+** -------- ------------------------- ---------------------------------- **
+** aw Alexander Wenzel BMW **
+** mk Markus Klein Fraunhofer ESK **
+*******************************************************************************/
+
+/*******************************************************************************
+** Author Identity **
+********************************************************************************
+** **
+** Initials Name Company **
+** -------- ------------------------- ---------------------------------- **
+** aw Alexander Wenzel BMW **
+** mk Markus Klein Fraunhofer ESK **
+*******************************************************************************/
+
+#ifndef DLT_DAEMON_CFG_H
+#define DLT_DAEMON_CFG_H
+
+/*************/
+/* Changable */
+/*************/
+
+/* Stack size of timing packet thread */
+#define DLT_DAEMON_TIMINGPACKET_THREAD_STACKSIZE 100000
+
+/* Size of receive buffer for fifo connection (from user application) */
+#define DLT_DAEMON_RCVBUFSIZE 10024
+/* Size of receive buffer for socket connection (from dlt client) */
+#define DLT_DAEMON_RCVBUFSIZESOCK 10024
+/* Size of receive buffer for serial connection (from dlt client) */
+#define DLT_DAEMON_RCVBUFSIZESERIAL 10024
+
+/* Size of buffer for text output */
+#define DLT_DAEMON_TEXTSIZE 10024
+
+/* Size of buffer */
+#define DLT_DAEMON_TEXTBUFSIZE 512
+
+/* Maximum length of a description */
+#define DLT_DAEMON_DESCSIZE 256
+
+/* Name of daemon lock file, contain process id of dlt daemon instance */
+#define DLT_DAEMON_LOCK_FILE "dltd.lock"
+
+/* Umask of daemon, creates files with permission 750 */
+#define DLT_DAEMON_UMASK 027
+/* Permissions of daemon lock file */
+#define DLT_DAEMON_LOCK_FILE_PERM 0640
+
+/* Default ECU ID, used in storage header and transmitted to client*/
+#define DLT_DAEMON_ECU_ID "ECU1"
+
+/* Default baudrate for serial interface */
+#define DLT_DAEMON_SERIAL_DEFAULT_BAUDRATE 115200
+
+/************************/
+/* Don't change please! */
+/************************/
+
+#endif /* DLT_DAEMON_CFG_H */
+
diff --git a/src/daemon/dlt_daemon_common.c b/src/daemon/dlt_daemon_common.c
new file mode 100755
index 0000000..4fbfd31
--- /dev/null
+++ b/src/daemon/dlt_daemon_common.c
@@ -0,0 +1,2196 @@
+/*
+ * Dlt Daemon - Diagnostic Log and Trace
+ * @licence app begin@
+ *
+ * Copyright (C) 2011, BMW AG - Alexander Wenzel <alexander.wenzel@bmw.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under the terms of the
+ * GNU Lesser General Public License, version 2.1, as published by the Free Software Foundation.
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
+ * Public License, version 2.1, for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License, version 2.1, along
+ * with this program; if not, see <http://www.gnu.org/licenses/lgpl-2.1.html>.
+ *
+ * Note that the copyright holders assume that the GNU Lesser General Public License, version 2.1, may
+ * also be applicable to programs even in cases in which the program is not a library in the technical sense.
+ *
+ * Linking DLT statically or dynamically with other modules is making a combined work based on DLT. You may
+ * license such other modules under the GNU Lesser General Public License, version 2.1. If you do not want to
+ * license your linked modules under the GNU Lesser General Public License, version 2.1, you
+ * may use the program under the following exception.
+ *
+ * As a special exception, the copyright holders of DLT give you permission to combine DLT
+ * with software programs or libraries that are released under any license unless such a combination is not
+ * permitted by the license of such a software program or library. You may copy and distribute such a
+ * system following the terms of the GNU Lesser General Public License, version 2.1, including this
+ * special exception, for DLT and the licenses of the other code concerned.
+ *
+ * Note that people who make modified versions of DLT are not obligated to grant this special exception
+ * for their modified versions; it is their choice whether to do so. The GNU Lesser General Public License,
+ * version 2.1, gives permission to release a modified version without this exception; this exception
+ * also makes it possible to release a modified version which carries forward this exception.
+ *
+ * @licence end@
+ */
+
+/*******************************************************************************
+** **
+** SRC-MODULE: dlt_daemon_common.c **
+** **
+** TARGET : linux **
+** **
+** PROJECT : DLT **
+** **
+** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de **
+** Markus Klein **
+** **
+** PURPOSE : **
+** **
+** REMARKS : **
+** **
+** PLATFORM DEPENDANT [yes/no]: yes **
+** **
+** TO BE CHANGED BY USER [yes/no]: no **
+** **
+*******************************************************************************/
+
+/*******************************************************************************
+** Author Identity **
+********************************************************************************
+** **
+** Initials Name Company **
+** -------- ------------------------- ---------------------------------- **
+** aw Alexander Wenzel BMW **
+** mk Markus Klein Fraunhofer ESK **
+*******************************************************************************/
+
+/*******************************************************************************
+** Revision Control History **
+*******************************************************************************/
+
+/*
+ * $LastChangedRevision: 1670 $
+ * $LastChangedDate: 2011-04-08 15:12:06 +0200 (Fr, 08. Apr 2011) $
+ * $LastChangedBy$
+ Initials Date Comment
+ aw 13.01.2010 initial
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include <sys/types.h> /* send() */
+#include <sys/socket.h> /* send() */
+
+#include "dlt_types.h"
+#include "dlt_daemon_common.h"
+#include "dlt_daemon_common_cfg.h"
+#include "dlt_user_shared.h"
+#include "dlt_user_shared_cfg.h"
+
+static char str[DLT_DAEMON_TEXTBUFSIZE];
+
+sem_t dlt_daemon_mutex;
+
+static int dlt_daemon_cmp_apid(const void *m1, const void *m2)
+{
+ DltDaemonApplication *mi1 = (DltDaemonApplication *) m1;
+ DltDaemonApplication *mi2 = (DltDaemonApplication *) m2;
+
+ return memcmp(mi1->apid, mi2->apid, DLT_ID_SIZE);
+}
+
+static int dlt_daemon_cmp_apid_ctid(const void *m1, const void *m2)
+{
+
+ int ret, cmp;
+ DltDaemonContext *mi1 = (DltDaemonContext *) m1;
+ DltDaemonContext *mi2 = (DltDaemonContext *) m2;
+
+ cmp=memcmp(mi1->apid, mi2->apid, DLT_ID_SIZE);
+ if (cmp<0)
+ {
+ ret=-1;
+ }
+ else if (cmp==0)
+ {
+ ret=memcmp(mi1->ctid, mi2->ctid, DLT_ID_SIZE);
+ }
+ else
+ {
+ ret=1;
+ }
+
+ return ret;
+}
+
+int dlt_daemon_init(DltDaemon *daemon,int verbose)
+{
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ if (daemon==0)
+ {
+ return -1;
+ }
+
+ daemon->num_contexts = 0;
+ daemon->contexts = 0;
+
+ daemon->num_applications = 0;
+ daemon->applications = 0;
+
+ daemon->default_log_level = DLT_DAEMON_INITIAL_LOG_LEVEL ;
+ daemon->default_trace_status = DLT_DAEMON_INITIAL_TRACE_STATUS ;
+
+ daemon->message_buffer_overflow = DLT_MESSAGE_BUFFER_NO_OVERFLOW;
+
+ daemon->runtime_context_cfg_loaded = 0;
+
+ /* Check for runtime cfg, if it is loadable, load it! */
+ if ((dlt_daemon_applications_load(daemon,DLT_RUNTIME_APPLICATION_CFG, verbose)==0) &&
+ (dlt_daemon_contexts_load(daemon,DLT_RUNTIME_CONTEXT_CFG, verbose)==0))
+ {
+ daemon->runtime_context_cfg_loaded = 1;
+ }
+
+ daemon->sendserialheader = 0;
+ daemon->timingpackets = 0;
+
+ dlt_set_id(daemon->ecuid,"");
+
+ /* initialize ring buffer for client connection */
+ if (dlt_ringbuffer_init(&(daemon->client_ringbuffer), DLT_DAEMON_RINGBUFFER_SIZE)==-1)
+ {
+ return -1;
+ }
+
+ return 0;
+}
+
+int dlt_daemon_free(DltDaemon *daemon,int verbose)
+{
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ if (daemon==0)
+ {
+ return -1;
+ }
+
+ /* Free contexts */
+ if (dlt_daemon_contexts_clear(daemon, verbose)==-1)
+ {
+ return -1;
+ }
+
+ /* Free applications */
+ if (dlt_daemon_applications_clear(daemon, verbose)==-1)
+ {
+ return -1;
+ }
+
+ return 0;
+}
+
+int dlt_daemon_applications_clear(DltDaemon *daemon,int verbose)
+{
+ uint32_t i;
+
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ if (daemon==0)
+ {
+ return -1;
+ }
+
+ for (i=0; i<daemon->num_applications; i++)
+ {
+ if (daemon->applications[i].application_description!=0)
+ {
+ free(daemon->applications[i].application_description);
+ daemon->applications[i].application_description = 0;
+ }
+ }
+
+ if (daemon->applications)
+ {
+ free(daemon->applications);
+ }
+
+ daemon->applications = 0;
+ daemon->num_applications = 0;
+
+ return 0;
+}
+
+DltDaemonApplication* dlt_daemon_application_add(DltDaemon *daemon,char *apid,pid_t pid,char *description, int verbose)
+{
+ DltDaemonApplication *application;
+ DltDaemonApplication *old;
+ int new_application;
+ int dlt_user_handle;
+ char filename[DLT_DAEMON_TEXTBUFSIZE];
+
+ if ((daemon==0) || (apid==0) || (apid[0]=='\0'))
+ {
+ return (DltDaemonApplication*) 0;
+ }
+
+ if (daemon->applications == 0)
+ {
+ daemon->applications = (DltDaemonApplication*) malloc(sizeof(DltDaemonApplication)*DLT_DAEMON_APPL_ALLOC_SIZE);
+ if (daemon->applications==0)
+ {
+ return (DltDaemonApplication*) 0;
+ }
+ }
+
+ new_application=0;
+
+ /* Check if application [apid] is already available */
+ application = dlt_daemon_application_find(daemon, apid, verbose);
+ if (application==0)
+ {
+ daemon->num_applications += 1;
+
+ if (daemon->num_applications!=0)
+ {
+ if ((daemon->num_applications%DLT_DAEMON_APPL_ALLOC_SIZE)==0)
+ {
+ /* allocate memory in steps of DLT_DAEMON_APPL_ALLOC_SIZE, e.g. 100 */
+ old = daemon->applications;
+ daemon->applications = (DltDaemonApplication*) malloc(sizeof(DltDaemonApplication)*
+ ((daemon->num_applications/DLT_DAEMON_APPL_ALLOC_SIZE)+1)*DLT_DAEMON_APPL_ALLOC_SIZE);
+ if (daemon->applications==0)
+ {
+ daemon->applications = old;
+ return (DltDaemonApplication*) 0;
+ }
+ memcpy(daemon->applications,old,sizeof(DltDaemonApplication)*daemon->num_applications);
+ free(old);
+ }
+ }
+
+ application = &(daemon->applications[daemon->num_applications-1]);
+
+ dlt_set_id(application->apid,apid);
+ application->application_description = 0;
+ application->num_contexts = 0;
+
+ new_application = 1;
+ }
+
+ /* Store application description and pid of application */
+ if (application->application_description)
+ {
+ free(application->application_description);
+ }
+
+ application->application_description=0;
+
+ if (description)
+ {
+ application->application_description = malloc(strlen(description)+1);
+ if (application->application_description)
+ {
+ strncpy(application->application_description,description,strlen(description)+1);
+ application->application_description[strlen(description)]='\0';
+ }
+ }
+
+ application->pid = pid;
+
+ application->user_handle = -1;
+
+ if (pid)
+ {
+ sprintf(filename,"%s/dlt%d",DLT_USER_DIR,application->pid);
+
+ dlt_user_handle = open(filename, O_WRONLY|O_NONBLOCK);
+ if (dlt_user_handle <0)
+ {
+ sprintf(str,"open() failed to %s, errno=%d (%s)!\n",filename,errno,strerror(errno)); /* errno 2: ENOENT - No such file or directory */
+ dlt_log(LOG_ERR, str);
+ } /* if */
+
+ application->user_handle = dlt_user_handle;
+ }
+
+ /* Sort */
+ if (new_application)
+ {
+ qsort(daemon->applications,daemon->num_applications,sizeof(DltDaemonApplication),dlt_daemon_cmp_apid);
+
+ /* Find new position of application with apid*/
+ application = dlt_daemon_application_find(daemon, apid, verbose);
+ }
+
+ return application;
+}
+
+int dlt_daemon_application_del(DltDaemon *daemon, DltDaemonApplication *application, int verbose)
+{
+ int pos;
+
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ if ((daemon==0) || (application==0))
+ {
+ return -1;
+ }
+
+ if (daemon->num_applications>0)
+ {
+ /* Check if user handle is open; if yes, close it */
+ if (application->user_handle!=-1)
+ {
+ close(application->user_handle);
+ application->user_handle=-1;
+ }
+
+ /* Free description of application to be deleted */
+ if (application->application_description)
+ {
+ free(application->application_description);
+ application->application_description = 0;
+ }
+
+ pos = application-(daemon->applications);
+
+ /* move all applications above pos to pos */
+ memmove(&(daemon->applications[pos]),&(daemon->applications[pos+1]), sizeof(DltDaemonApplication)*((daemon->num_applications-1)-pos));
+
+ /* Clear last application */
+ memset(&(daemon->applications[daemon->num_applications-1]),0,sizeof(DltDaemonApplication));
+
+ daemon->num_applications--;
+
+ }
+
+ return 0;
+}
+
+DltDaemonApplication* dlt_daemon_application_find(DltDaemon *daemon,char *apid,int verbose)
+{
+ DltDaemonApplication application;
+
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ if ((daemon==0) || (apid==0) || (apid[0]=='\0') || (daemon->num_applications==0))
+ {
+ return (DltDaemonApplication*) 0;
+ }
+
+ /* Check, if apid is smaller than smallest apid or greater than greatest apid */
+ if ((memcmp(apid,daemon->applications[0].apid,DLT_ID_SIZE)<0) ||
+ (memcmp(apid,daemon->applications[daemon->num_applications-1].apid,DLT_ID_SIZE)>0))
+ {
+ return (DltDaemonApplication*) 0;
+ }
+
+ dlt_set_id(application.apid,apid);
+ return (DltDaemonApplication*)bsearch(&application,daemon->applications,daemon->num_applications,sizeof(DltDaemonApplication),dlt_daemon_cmp_apid);
+}
+
+int dlt_daemon_applications_load(DltDaemon *daemon,const char *filename, int verbose)
+{
+ FILE *fd;
+ ID4 apid;
+ char buf[DLT_DAEMON_TEXTBUFSIZE];
+ char *ret;
+ char *pb;
+
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ if ((daemon==0) || (filename==0) || (filename[0]=='\0'))
+ {
+ return -1;
+ }
+
+ fd=fopen(filename, "r");
+
+ if (fd==0)
+ {
+ return -1;
+ }
+
+ while (!feof(fd))
+ {
+ /* Clear buf */
+ memset(buf, 0, sizeof(buf));
+
+ /* Get line */
+ ret=fgets(buf,sizeof(buf),fd);
+
+ if (strcmp(buf,"")!=0)
+ {
+ /* Split line */
+ pb=strtok(buf,":");
+ dlt_set_id(apid,pb);
+ pb=strtok(NULL,":");
+ /* pb contains now the description */
+
+ /* pid is unknown at loading time */
+ if (dlt_daemon_application_add(daemon,apid,0,pb,verbose)==0)
+ {
+ fclose(fd);
+ return -1;
+ }
+ }
+ }
+ fclose(fd);
+
+ return 0;
+}
+
+int dlt_daemon_applications_save(DltDaemon *daemon,const char *filename, int verbose)
+{
+ FILE *fd;
+ uint32_t i;
+
+ char apid[DLT_ID_SIZE+1]; /* DLT_ID_SIZE+1, because the 0-termination is required here */
+
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ if ((daemon==0) || (filename==0) || (filename[0]=='\0'))
+ {
+ return -1;
+ }
+
+ memset(apid,0, sizeof(apid));
+
+ if ((daemon->applications) && (daemon->num_applications>0))
+ {
+ fd=fopen(filename, "w");
+ if (fd!=0)
+ {
+ for (i=0; i<daemon->num_applications; i++)
+ {
+ dlt_set_id(apid,daemon->applications[i].apid);
+
+ if ((daemon->applications[i].application_description) &&
+ (daemon->applications[i].application_description!='\0'))
+ {
+ fprintf(fd,"%s:%s:\n",apid, daemon->applications[i].application_description);
+ }
+ else
+ {
+ fprintf(fd,"%s::\n",apid);
+ }
+ }
+ fclose(fd);
+ }
+ }
+
+ return 0;
+}
+
+DltDaemonContext* dlt_daemon_context_add(DltDaemon *daemon,char *apid,char *ctid,int8_t log_level,int8_t trace_status,int log_level_pos, int user_handle,char *description,int verbose)
+{
+ DltDaemonApplication *application;
+ DltDaemonContext *context;
+ DltDaemonContext *old;
+ int new_context=0;
+
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ if ((daemon==0) || (apid==0) || (apid[0]=='\0') || (ctid==0) || (ctid[0]=='\0'))
+ {
+ return (DltDaemonContext*) 0;
+ }
+
+ if ((log_level<DLT_LOG_DEFAULT) || (log_level>DLT_LOG_VERBOSE))
+ {
+ return (DltDaemonContext*) 0;
+ }
+
+ if ((trace_status<DLT_TRACE_STATUS_DEFAULT) || (trace_status>DLT_TRACE_STATUS_ON))
+ {
+ return (DltDaemonContext*) 0;
+ }
+
+ if (daemon->contexts == 0)
+ {
+ daemon->contexts = (DltDaemonContext*) malloc(sizeof(DltDaemonContext)*DLT_DAEMON_CONTEXT_ALLOC_SIZE);
+ if (daemon->contexts==0)
+ {
+ return (DltDaemonContext*) 0;
+ }
+ }
+
+ /* Check if application [apid] is available */
+ application = dlt_daemon_application_find(daemon, apid, verbose);
+ if (application==0)
+ {
+ return (DltDaemonContext*) 0;
+ }
+
+ /* Check if context [apid, ctid] is already available */
+ context = dlt_daemon_context_find(daemon, apid, ctid, verbose);
+ if (context==0)
+ {
+ daemon->num_contexts += 1;
+
+ if (daemon->num_contexts!=0)
+ {
+ if ((daemon->num_contexts%DLT_DAEMON_CONTEXT_ALLOC_SIZE)==0)
+ {
+ /* allocate memory for context in steps of DLT_DAEMON_CONTEXT_ALLOC_SIZE, e.g 100 */
+ old = daemon->contexts;
+ daemon->contexts = (DltDaemonContext*) malloc(sizeof(DltDaemonContext)*
+ ((daemon->num_contexts/DLT_DAEMON_CONTEXT_ALLOC_SIZE)+1)*DLT_DAEMON_CONTEXT_ALLOC_SIZE);
+ if (daemon->contexts==0)
+ {
+ daemon->contexts = old;
+ return (DltDaemonContext*) 0;
+ }
+ memcpy(daemon->contexts,old,sizeof(DltDaemonContext)*daemon->num_contexts);
+ free(old);
+ }
+ }
+
+ context = &(daemon->contexts[daemon->num_contexts-1]);
+
+ dlt_set_id(context->apid,apid);
+ dlt_set_id(context->ctid,ctid);
+ context->context_description = 0;
+
+ application->num_contexts++;
+ new_context =1;
+ }
+
+ /* Set context description */
+ if (context->context_description)
+ {
+ free(context->context_description);
+ }
+
+ context->context_description=0;
+
+ if (description)
+ {
+ context->context_description = malloc(strlen(description)+1);
+
+ if (context->context_description)
+ {
+ strncpy(context->context_description,description,strlen(description)+1);
+ context->context_description[strlen(description)]='\0';
+ }
+ }
+
+ /* Store log level and trace status,
+ if this is a new context, or
+ if this is an old context and the runtime cfg was not loaded */
+
+ if ((new_context==1) ||
+ ((new_context==0) && (daemon->runtime_context_cfg_loaded==0)))
+ {
+ context->log_level = log_level;
+ context->trace_status = trace_status;
+ }
+
+ context->log_level_pos = log_level_pos;
+ context->user_handle = user_handle;
+
+ /* Sort */
+ if (new_context)
+ {
+ qsort(daemon->contexts,daemon->num_contexts, sizeof(DltDaemonContext),dlt_daemon_cmp_apid_ctid);
+
+ /* Find new position of context with apid, ctid */
+ context = dlt_daemon_context_find(daemon, apid, ctid, verbose);
+ }
+
+ return context;
+}
+
+int dlt_daemon_context_del(DltDaemon *daemon, DltDaemonContext* context, int verbose)
+{
+ int pos;
+ DltDaemonApplication *application;
+
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ if ((daemon==0) || (context==0))
+ {
+ return -1;
+ }
+
+ if (daemon->num_contexts>0)
+ {
+ application = dlt_daemon_application_find(daemon, context->apid, verbose);
+
+ /* Free description of context to be deleted */
+ if (context->context_description)
+ {
+ free(context->context_description);
+ context->context_description = 0;
+ }
+
+ pos = context-(daemon->contexts);
+
+ /* move all contexts above pos to pos */
+ memmove(&(daemon->contexts[pos]),&(daemon->contexts[pos+1]), sizeof(DltDaemonContext)*((daemon->num_contexts-1)-pos));
+
+ /* Clear last context */
+ memset(&(daemon->contexts[daemon->num_contexts-1]),0,sizeof(DltDaemonContext));
+
+ daemon->num_contexts--;
+
+ /* Check if application [apid] is available */
+ if (application)
+ {
+ application->num_contexts--;
+ }
+ }
+
+ return 0;
+}
+
+DltDaemonContext* dlt_daemon_context_find(DltDaemon *daemon,char *apid,char *ctid,int verbose)
+{
+ DltDaemonContext context;
+
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ if ((daemon==0) || (apid==0) || (apid[0]=='\0') || (ctid==0) || (ctid[0]=='\0') || (daemon->num_contexts==0))
+ {
+ return (DltDaemonContext*) 0;
+ }
+
+ /* Check, if apid is smaller than smallest apid or greater than greatest apid */
+ if ((memcmp(apid,daemon->contexts[0].apid,DLT_ID_SIZE)<0) ||
+ (memcmp(apid,daemon->contexts[daemon->num_contexts-1].apid,DLT_ID_SIZE)>0))
+ {
+ return (DltDaemonContext*) 0;
+ }
+
+ dlt_set_id(context.apid,apid);
+ dlt_set_id(context.ctid,ctid);
+
+ return (DltDaemonContext*)bsearch(&context,daemon->contexts,daemon->num_contexts,sizeof(DltDaemonContext),dlt_daemon_cmp_apid_ctid);
+}
+
+int dlt_daemon_contexts_clear(DltDaemon *daemon,int verbose)
+{
+ int i;
+
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ if (daemon==0)
+ {
+ return -1;
+ }
+
+ for (i=0; i<daemon->num_contexts; i++)
+ {
+ if (daemon->contexts[i].context_description!=0)
+ {
+ free(daemon->contexts[i].context_description);
+ daemon->contexts[i].context_description = 0;
+ }
+ }
+
+ if (daemon->contexts)
+ {
+ free(daemon->contexts);
+ }
+
+ daemon->contexts = 0;
+
+ for (i=0; i<daemon->num_applications; i++)
+ {
+ daemon->applications[i].num_contexts = 0;
+ }
+
+ daemon->num_contexts = 0;
+
+ return 0;
+}
+
+int dlt_daemon_contexts_load(DltDaemon *daemon,const char *filename, int verbose)
+{
+ FILE *fd;
+ ID4 apid, ctid;
+ char buf[DLT_DAEMON_TEXTBUFSIZE];
+ char *ret;
+ char *pb;
+ int ll, ts;
+
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ if ((daemon==0) || (filename==0) ||( filename[0]=='\0'))
+ {
+ return -1;
+ }
+
+ fd=fopen(filename, "r");
+
+ if (fd==0)
+ {
+ return -1;
+ }
+
+ while (!feof(fd))
+ {
+ /* Clear buf */
+ memset(buf, 0, sizeof(buf));
+
+ /* Get line */
+ ret=fgets(buf,sizeof(buf),fd);
+
+ if (strcmp(buf,"")!=0)
+ {
+ /* Split line */
+ pb=strtok(buf,":");
+ dlt_set_id(apid,pb);
+ pb=strtok(NULL,":");
+ dlt_set_id(ctid,pb);
+ pb=strtok(NULL,":");
+ sscanf(pb,"%d",&ll);
+ pb=strtok(NULL,":");
+ sscanf(pb,"%d",&ts);
+ pb=strtok(NULL,":");
+ /* pb contains now the description */
+
+ /* log_level_pos, and user_handle are unknown at loading time */
+ if (dlt_daemon_context_add(daemon,apid,ctid,(int8_t)ll,(int8_t)ts,0,0,pb,verbose)==0)
+ {
+ fclose(fd);
+ return -1;
+ }
+ }
+ }
+ fclose(fd);
+
+ return 0;
+}
+
+int dlt_daemon_contexts_save(DltDaemon *daemon,const char *filename, int verbose)
+{
+ FILE *fd;
+ uint32_t i;
+
+ char apid[DLT_ID_SIZE+1], ctid[DLT_ID_SIZE+1]; /* DLT_ID_SIZE+1, because the 0-termination is required here */
+
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ if ((daemon==0) || (filename==0) ||( filename[0]=='\0'))
+ {
+ return -1;
+ }
+
+ memset(apid,0, sizeof(apid));
+ memset(ctid,0, sizeof(ctid));
+
+ if ((daemon->contexts) && (daemon->num_contexts>0))
+ {
+ fd=fopen(filename, "w");
+ if (fd!=0)
+ {
+ for (i=0; i<daemon->num_contexts; i++)
+ {
+ dlt_set_id(apid,daemon->contexts[i].apid);
+ dlt_set_id(ctid,daemon->contexts[i].ctid);
+
+ if ((daemon->contexts[i].context_description) &&
+ (daemon->contexts[i].context_description[0]!='\0'))
+ {
+ fprintf(fd,"%s:%s:%d:%d:%s:\n",apid,ctid,
+ (int)(daemon->contexts[i].log_level),
+ (int)(daemon->contexts[i].trace_status),
+ daemon->contexts[i].context_description);
+ }
+ else
+ {
+ fprintf(fd,"%s:%s:%d:%d::\n",apid,ctid,
+ (int)(daemon->contexts[i].log_level),
+ (int)(daemon->contexts[i].trace_status));
+ }
+ }
+ fclose(fd);
+ }
+ }
+
+ return 0;
+}
+
+int dlt_daemon_user_send_log_level(DltDaemon *daemon,DltDaemonContext *context,int verbose)
+{
+ DltUserHeader userheader;
+ DltUserControlMsgLogLevel usercontext;
+ DltReturnValue ret;
+
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ if ((daemon==0) || (context==0))
+ {
+ return -1;
+ }
+
+ if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG_LEVEL)==-1)
+ {
+ return -1;
+ }
+
+ usercontext.log_level = ((context->log_level == DLT_LOG_DEFAULT)?daemon->default_log_level:context->log_level);
+ usercontext.trace_status = ((context->trace_status == DLT_TRACE_STATUS_DEFAULT)?daemon->default_trace_status:context->trace_status);
+
+ usercontext.log_level_pos = context->log_level_pos;
+
+ /* log to FIFO */
+ ret = dlt_user_log_out2(context->user_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgLogLevel));
+
+ if (ret!=DLT_RETURN_OK)
+ {
+ if (errno==EPIPE)
+ {
+ /* Close connection */
+ close(context->user_handle);
+ context->user_handle=0;
+ }
+ }
+
+ return ((ret==DLT_RETURN_OK)?0:-1);
+}
+
+int dlt_daemon_control_process_control(int sock, DltDaemon *daemon, DltMessage *msg, int verbose)
+{
+ uint32_t id,id_tmp=0;
+
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ if ((daemon==0) || (msg==0))
+ {
+ return -1;
+ }
+
+ if (msg->datasize<sizeof(uint32_t))
+ {
+ return -1;
+ }
+
+ id_tmp = *((uint32_t*)(msg->databuffer));
+ id=DLT_ENDIAN_GET_32(msg->standardheader->htyp ,id_tmp);
+
+ if ((id > 0) && (id <= DLT_SERVICE_ID_MESSAGE_BUFFER_OVERFLOW))
+ {
+ /* Control message handling */
+ switch (id)
+ {
+ case DLT_SERVICE_ID_SET_LOG_LEVEL:
+ {
+ dlt_daemon_control_set_log_level(sock, daemon, msg, verbose);
+ break;
+ }
+ case DLT_SERVICE_ID_SET_TRACE_STATUS:
+ {
+ dlt_daemon_control_set_trace_status(sock, daemon, msg, verbose);
+ break;
+ }
+ case DLT_SERVICE_ID_GET_LOG_INFO:
+ {
+ dlt_daemon_control_get_log_info(sock, daemon, msg, verbose);
+ break;
+ }
+ case DLT_SERVICE_ID_GET_DEFAULT_LOG_LEVEL:
+ {
+ dlt_daemon_control_get_default_log_level(sock, daemon, verbose);
+ break;
+ }
+ case DLT_SERVICE_ID_STORE_CONFIG:
+ {
+ if (dlt_daemon_applications_save(daemon, DLT_RUNTIME_APPLICATION_CFG, verbose)==0)
+ {
+ if (dlt_daemon_contexts_save(daemon, DLT_RUNTIME_CONTEXT_CFG, verbose)==0)
+ {
+ dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_OK, verbose);
+ }
+ else
+ {
+ /* Delete saved files */
+ dlt_daemon_control_reset_to_factory_default(daemon, DLT_RUNTIME_APPLICATION_CFG, DLT_RUNTIME_CONTEXT_CFG, verbose);
+ dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
+ }
+ }
+ else
+ {
+ dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
+ }
+ break;
+ }
+ case DLT_SERVICE_ID_RESET_TO_FACTORY_DEFAULT:
+ {
+ dlt_daemon_control_reset_to_factory_default(daemon, DLT_RUNTIME_APPLICATION_CFG, DLT_RUNTIME_CONTEXT_CFG, verbose);
+ dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_OK, verbose);
+ break;
+ }
+ case DLT_SERVICE_ID_SET_COM_INTERFACE_STATUS:
+ {
+ dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose);
+ break;
+ }
+ case DLT_SERVICE_ID_SET_COM_INTERFACE_MAX_BANDWIDTH:
+ {
+ dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose);
+ break;
+ }
+ case DLT_SERVICE_ID_SET_VERBOSE_MODE:
+ {
+ dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose);
+ break;
+ }
+ case DLT_SERVICE_ID_SET_MESSAGE_FILTERING:
+ {
+ dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose);
+ break;
+ }
+ case DLT_SERVICE_ID_SET_TIMING_PACKETS:
+ {
+ dlt_daemon_control_set_timing_packets(sock, daemon, msg, verbose);
+ break;
+ }
+ case DLT_SERVICE_ID_GET_LOCAL_TIME:
+ {
+ /* Send response with valid timestamp (TMSP) field */
+ dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_OK, verbose);
+ break;
+ }
+ case DLT_SERVICE_ID_USE_ECU_ID:
+ {
+ dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose);
+ break;
+ }
+ case DLT_SERVICE_ID_USE_SESSION_ID:
+ {
+ dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose);
+ break;
+ }
+ case DLT_SERVICE_ID_USE_TIMESTAMP:
+ {
+ dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose);
+ break;
+ }
+ case DLT_SERVICE_ID_USE_EXTENDED_HEADER:
+ {
+ dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose);
+ break;
+ }
+ case DLT_SERVICE_ID_SET_DEFAULT_LOG_LEVEL:
+ {
+ dlt_daemon_control_set_default_log_level(sock, daemon, msg, verbose);
+ break;
+ }
+ case DLT_SERVICE_ID_SET_DEFAULT_TRACE_STATUS:
+ {
+ dlt_daemon_control_set_default_trace_status(sock, daemon, msg, verbose);
+ break;
+ }
+ case DLT_SERVICE_ID_GET_SOFTWARE_VERSION:
+ {
+ dlt_daemon_control_get_software_version(sock, daemon, verbose);
+ break;
+ }
+ case DLT_SERVICE_ID_MESSAGE_BUFFER_OVERFLOW:
+ {
+ dlt_daemon_control_message_buffer_overflow(sock, daemon, verbose);
+ break;
+ }
+ default:
+ {
+ dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose);
+ break;
+ }
+ }
+ }
+ else
+ {
+ /* Injection handling */
+ dlt_daemon_control_callsw_cinjection(sock, daemon, msg, verbose);
+ }
+
+ return 0;
+}
+
+void dlt_daemon_control_callsw_cinjection(int sock, DltDaemon *daemon, DltMessage *msg, int verbose)
+{
+ char apid[DLT_ID_SIZE],ctid[DLT_ID_SIZE];
+ uint32_t id=0,id_tmp=0;
+ uint8_t *ptr;
+ DltDaemonContext *context;
+ uint32_t data_length_inject=0,data_length_inject_tmp=0;
+
+ int32_t datalength;
+
+ DltUserHeader userheader;
+ DltUserControlMsgInjection usercontext;
+ uint8_t *userbuffer;
+
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ if ((daemon==0) || (msg==0))
+ {
+ return;
+ }
+
+ datalength = msg->datasize;
+ ptr = msg->databuffer;
+
+ if (ptr==0)
+ {
+ return;
+ }
+
+ DLT_MSG_READ_VALUE(id_tmp,ptr,datalength,uint32_t); /* Get service id */
+ id=DLT_ENDIAN_GET_32(msg->standardheader->htyp, id_tmp);
+
+ if ((id>=DLT_DAEMON_INJECTION_MIN) && (id<=DLT_DAEMON_INJECTION_MAX))
+ {
+ /* This a a real SW-C injection call */
+ data_length_inject=0;
+ data_length_inject_tmp=0;
+
+ DLT_MSG_READ_VALUE(data_length_inject_tmp,ptr,datalength,uint32_t); /* Get data length */
+ data_length_inject=DLT_ENDIAN_GET_32(msg->standardheader->htyp, data_length_inject_tmp);
+
+ /* Get context handle for apid, ctid (and seid) */
+ /* Warning: seid is ignored in this implementation! */
+ if (DLT_IS_HTYP_UEH(msg->standardheader->htyp))
+ {
+ dlt_set_id(apid, msg->extendedheader->apid);
+ dlt_set_id(ctid, msg->extendedheader->ctid);
+ }
+ else
+ {
+ /* No extended header, and therefore no apid and ctid available */
+ dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
+ return;
+ }
+
+ /* At this point, apid and ctid is available */
+ context=dlt_daemon_context_find(daemon, apid, ctid, verbose);
+
+ if (context==0)
+ {
+ // dlt_log(LOG_INFO,"No context found!\n");
+ dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
+ return;
+ }
+
+ /* Send user message to handle, specified in context */
+ if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_INJECTION)==-1)
+ {
+ dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
+ return;
+ }
+
+ usercontext.log_level_pos = context->log_level_pos;
+
+ userbuffer = malloc(data_length_inject);
+
+ if (userbuffer==0)
+ {
+ dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
+ return;
+ }
+
+ usercontext.data_length_inject = data_length_inject;
+ usercontext.service_id = id;
+
+ memcpy(userbuffer,ptr,data_length_inject); /* Copy received injection to send buffer */
+
+ /* write to FIFO */
+ if (dlt_user_log_out3(context->user_handle, &(userheader), sizeof(DltUserHeader),
+ &(usercontext), sizeof(DltUserControlMsgInjection),
+ userbuffer, data_length_inject)!=DLT_RETURN_OK)
+ {
+ if (errno==EPIPE)
+ {
+ /* Close connection */
+ close(context->user_handle);
+ context->user_handle=0;
+ }
+ dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
+ }
+ else
+ {
+ dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_OK, verbose);
+ }
+
+ free(userbuffer);
+ userbuffer=0;
+
+ }
+ else
+ {
+ /* Invalid ID */
+ dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose);
+ }
+}
+
+void dlt_daemon_control_set_log_level(int sock, DltDaemon *daemon, DltMessage *msg, int verbose)
+{
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ char apid[DLT_ID_SIZE],ctid[DLT_ID_SIZE];
+ DltServiceSetLogLevel *req;
+ DltDaemonContext *context;
+ int32_t id=DLT_SERVICE_ID_SET_LOG_LEVEL;
+
+ int8_t old_log_level;
+
+ if ((daemon==0) || (msg==0))
+ {
+ return;
+ }
+
+ req = (DltServiceSetLogLevel*) (msg->databuffer);
+
+ dlt_set_id(apid, req->apid);
+ dlt_set_id(ctid, req->ctid);
+
+ context=dlt_daemon_context_find(daemon, apid, ctid, verbose);
+
+ /* Set log level */
+ if (context!=0)
+ {
+ old_log_level = context->log_level;
+ context->log_level = req->log_level; /* No endianess conversion necessary*/
+
+ if ((context->user_handle!=0) &&
+ (dlt_daemon_user_send_log_level(daemon, context, verbose)==0))
+ {
+ dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_OK, verbose);
+ }
+ else
+ {
+ //dlt_log(LOG_ERR, "Log level could not be sent!\n");
+ context->log_level = old_log_level;
+ dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
+ }
+ }
+ else
+ {
+ //dlt_log(LOG_ERR, "Context not found!\n");
+ dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
+ }
+}
+
+void dlt_daemon_control_set_trace_status(int sock, DltDaemon *daemon, DltMessage *msg, int verbose)
+{
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ char apid[DLT_ID_SIZE],ctid[DLT_ID_SIZE];
+ DltServiceSetLogLevel *req; /* request uses same struct as set log level */
+ DltDaemonContext *context;
+ int32_t id=DLT_SERVICE_ID_SET_TRACE_STATUS;
+
+ int8_t old_trace_status;
+
+ if ((daemon==0) || (msg==0))
+ {
+ return;
+ }
+
+ req = (DltServiceSetLogLevel*) (msg->databuffer);
+
+ dlt_set_id(apid, req->apid);
+ dlt_set_id(ctid, req->ctid);
+
+ context=dlt_daemon_context_find(daemon, apid, ctid, verbose);
+
+ /* Set log level */
+ if (context!=0)
+ {
+ old_trace_status = context->trace_status;
+ context->trace_status = req->log_level; /* No endianess conversion necessary */
+
+ if ((context->user_handle!=0) &&
+ (dlt_daemon_user_send_log_level(daemon, context, verbose)==0))
+ {
+ dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_OK, verbose);
+ }
+ else
+ {
+ //dlt_log(LOG_ERR, "Trace Status could not be sent!\n");
+ context->trace_status = old_trace_status;
+ dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
+ }
+ }
+ else
+ {
+ //dlt_log(LOG_ERR, "Context not found!\n");
+ dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
+ }
+}
+
+void dlt_daemon_control_set_default_log_level(int sock, DltDaemon *daemon, DltMessage *msg, int verbose)
+{
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ DltServiceSetDefaultLogLevel *req;
+ int32_t id=DLT_SERVICE_ID_SET_DEFAULT_LOG_LEVEL;
+
+ if ((daemon==0) || (msg==0))
+ {
+ return;
+ }
+
+ req = (DltServiceSetDefaultLogLevel*) (msg->databuffer);
+
+ /* No endianess conversion necessary */
+ if ((req->log_level>=0) &&
+ (req->log_level<=DLT_LOG_VERBOSE))
+ {
+ daemon->default_log_level = req->log_level; /* No endianess conversion necessary */
+
+ /* Send Update to all contexts using the default log level */
+ dlt_daemon_user_send_default_update(daemon, verbose);
+
+ dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_OK, verbose);
+ }
+ else
+ {
+ dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
+ }
+}
+
+void dlt_daemon_control_set_default_trace_status(int sock, DltDaemon *daemon, DltMessage *msg, int verbose)
+{
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ /* Payload of request message */
+ DltServiceSetDefaultLogLevel *req;
+ int32_t id=DLT_SERVICE_ID_SET_DEFAULT_TRACE_STATUS;
+
+ if ((daemon==0) || (msg==0))
+ {
+ return;
+ }
+
+ req = (DltServiceSetDefaultLogLevel*) (msg->databuffer);
+
+ /* No endianess conversion necessary */
+ if ((req->log_level==DLT_TRACE_STATUS_OFF) ||
+ (req->log_level==DLT_TRACE_STATUS_ON))
+ {
+ daemon->default_trace_status = req->log_level; /* No endianess conversion necessary*/
+
+ /* Send Update to all contexts using the default trace status */
+ dlt_daemon_user_send_default_update(daemon, verbose);
+
+ dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_OK, verbose);
+ }
+ else
+ {
+ dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
+ }
+}
+
+void dlt_daemon_control_set_timing_packets(int sock, DltDaemon *daemon, DltMessage *msg, int verbose)
+{
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ DltServiceSetVerboseMode *req; /* request uses same struct as set verbose mode */
+ int32_t id=DLT_SERVICE_ID_SET_TIMING_PACKETS;
+
+ if ((daemon==0) || (msg==0))
+ {
+ return;
+ }
+
+ req = (DltServiceSetVerboseMode*) (msg->databuffer);
+ if ((req->new_status==0) || (req->new_status==1))
+ {
+ daemon->timingpackets = req->new_status;
+
+ dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_OK, verbose);
+ }
+ else
+ {
+ dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
+ }
+}
+
+void dlt_daemon_control_get_software_version(int sock, DltDaemon *daemon, int verbose)
+{
+ char version[DLT_DAEMON_TEXTBUFSIZE];
+ DltMessage msg;
+ uint32_t len;
+ DltServiceGetSoftwareVersionResponse *resp;
+
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ if (daemon==0)
+ {
+ return;
+ }
+
+ /* initialise new message */
+ if (dlt_message_init(&msg,0)==-1)
+ {
+ dlt_daemon_control_service_response(sock, daemon, DLT_SERVICE_ID_GET_SOFTWARE_VERSION, DLT_SERVICE_RESPONSE_ERROR, verbose);
+ return;
+ }
+
+ /* prepare payload of data */
+ dlt_get_version(version);
+ len = strlen(version);
+
+ msg.datasize = sizeof(DltServiceGetSoftwareVersionResponse) + len;
+ if (msg.databuffer)
+ {
+ free(msg.databuffer);
+ }
+ msg.databuffer = (uint8_t *) malloc(msg.datasize);
+ if (msg.databuffer==0)
+ {
+ dlt_daemon_control_service_response(sock, daemon, DLT_SERVICE_ID_GET_SOFTWARE_VERSION, DLT_SERVICE_RESPONSE_ERROR, verbose);
+ return;
+ }
+
+ resp = (DltServiceGetSoftwareVersionResponse*) msg.databuffer;
+ resp->service_id = DLT_SERVICE_ID_GET_SOFTWARE_VERSION;
+ resp->status = DLT_SERVICE_RESPONSE_OK;
+ resp->length = len;
+ memcpy(msg.databuffer+sizeof(DltServiceGetSoftwareVersionResponse),version,len);
+
+ /* send message */
+ dlt_daemon_control_send_control_message(sock, daemon, &msg,"","", verbose);
+
+ /* free message */
+ dlt_message_free(&msg,0);
+}
+
+void dlt_daemon_control_get_default_log_level(int sock, DltDaemon *daemon, int verbose)
+{
+ DltMessage msg;
+ DltServiceGetDefaultLogLevelResponse *resp;
+
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ if (daemon==0)
+ {
+ return;
+ }
+
+ /* initialise new message */
+ if (dlt_message_init(&msg,0)==-1)
+ {
+ dlt_daemon_control_service_response(sock, daemon, DLT_SERVICE_ID_GET_DEFAULT_LOG_LEVEL, DLT_SERVICE_RESPONSE_ERROR, verbose);
+ return;
+ }
+
+ msg.datasize = sizeof(DltServiceGetDefaultLogLevelResponse);
+ if (msg.databuffer)
+ {
+ free(msg.databuffer);
+ }
+ msg.databuffer = (uint8_t *) malloc(msg.datasize);
+ if (msg.databuffer==0)
+ {
+ dlt_daemon_control_service_response(sock, daemon, DLT_SERVICE_ID_GET_DEFAULT_LOG_LEVEL, DLT_SERVICE_RESPONSE_ERROR, verbose);
+ return;
+ }
+
+ resp = (DltServiceGetDefaultLogLevelResponse*) msg.databuffer;
+ resp->service_id = DLT_SERVICE_ID_GET_DEFAULT_LOG_LEVEL;
+ resp->status = DLT_SERVICE_RESPONSE_OK;
+ resp->log_level = daemon->default_log_level;
+
+ /* send message */
+ dlt_daemon_control_send_control_message(sock,daemon,&msg,"","", verbose);
+
+ /* free message */
+ dlt_message_free(&msg,0);
+}
+
+void dlt_daemon_control_get_log_info(int sock, DltDaemon *daemon, DltMessage *msg, int verbose)
+{
+ DltServiceGetLogInfoRequest *req;
+ DltMessage resp;
+ DltDaemonContext *context=0;
+ DltDaemonApplication *application=0;
+
+ int num_applications=0, num_contexts=0;
+ uint16_t count_app_ids=0, count_con_ids=0;
+
+#if (DLT_DEBUG_GETLOGINFO==1)
+ char buf[255];
+#endif
+
+ int32_t i,j,offset=0;
+ char *apid=0;
+ int8_t ll,ts;
+ uint16_t len;
+ int8_t value;
+ int32_t sizecont=0;
+ int offset_base;
+
+ uint32_t sid;
+
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ if ((daemon==0) || (msg==0))
+ {
+ return;
+ }
+
+ /* prepare pointer to message request */
+ req = (DltServiceGetLogInfoRequest*) (msg->databuffer);
+
+ /* initialise new message */
+ if (dlt_message_init(&resp,0)==-1)
+ {
+ dlt_daemon_control_service_response(sock, daemon, DLT_SERVICE_ID_GET_LOG_INFO, DLT_SERVICE_RESPONSE_ERROR, verbose);
+ return;
+ }
+
+ /* check request */
+ if ((req->options < 3 ) || (req->options>7))
+ {
+ dlt_daemon_control_service_response(sock, daemon, DLT_SERVICE_ID_GET_LOG_INFO, DLT_SERVICE_RESPONSE_ERROR, verbose);
+ return;
+ }
+
+ if (req->apid[0]!='\0')
+ {
+ application = dlt_daemon_application_find(daemon, req->apid, verbose);
+ if (application)
+ {
+ num_applications = 1;
+ if (req->ctid[0]!='\0')
+ {
+ context = dlt_daemon_context_find(daemon, req->apid, req->ctid, verbose);
+
+ num_contexts = ((context)?1:0);
+ }
+ else
+ {
+ num_contexts = application->num_contexts;
+ }
+ }
+ else
+ {
+ num_applications = 0;
+ num_contexts = 0;
+ }
+ }
+ else
+ {
+ /* Request all applications and contexts */
+ num_applications = daemon->num_applications;
+ num_contexts = daemon->num_contexts;
+ }
+
+ /* prepare payload of data */
+
+ /* Calculate maximum size for a response */
+ resp.datasize = sizeof(uint32_t) /* SID */ + sizeof(int8_t) /* status*/ + sizeof(ID4) /* DLT_DAEMON_REMO_STRING */;
+
+ sizecont = sizeof(uint32_t) /* context_id */;
+
+ /* Add additional size for response of Mode 4, 6, 7 */
+ if ((req->options==4) || (req->options==6) || (req->options==7))
+ {
+ sizecont += sizeof(int8_t); /* log level */
+ }
+
+ /* Add additional size for response of Mode 5, 6, 7 */
+ if ((req->options==5) || (req->options==6) || (req->options==7))
+ {
+ sizecont+= sizeof(int8_t); /* trace status */
+ }
+
+ resp.datasize+= (num_applications * (sizeof(uint32_t) /* app_id */ + sizeof(uint16_t) /* count_con_ids */)) +
+ (num_contexts * sizecont);
+
+ resp.datasize+= sizeof(uint16_t) /* count_app_ids */;
+
+ /* Add additional size for response of Mode 7 */
+ if (req->options==7)
+ {
+ if (req->apid[0]!='\0')
+ {
+ if (req->ctid[0]!='\0')
+ {
+ /* One application, one context */
+ // context = dlt_daemon_context_find(daemon, req->apid, req->ctid, verbose);
+ if (context)
+ {
+ resp.datasize+=sizeof(uint16_t) /* len_context_description */;
+ if (context->context_description!=0)
+ {
+ resp.datasize+=strlen(context->context_description); /* context_description */
+ }
+ }
+ }
+ else
+ {
+ /* One application, all contexts */
+ if ((daemon->applications) && (application))
+ {
+ /* Calculate start offset within contexts[] */
+ offset_base=0;
+ for (i=0; i<(application-(daemon->applications)); i++)
+ {
+ offset_base+=daemon->applications[i].num_contexts;
+ }
+
+ /* Iterate over all contexts belonging to this application */
+ for (j=0;j<application->num_contexts;j++)
+ {
+
+ context = &(daemon->contexts[offset_base+j]);
+ if (context)
+ {
+ resp.datasize+=sizeof(uint16_t) /* len_context_description */;
+ if (context->context_description!=0)
+ {
+ resp.datasize+=strlen(context->context_description); /* context_description */
+ }
+ }
+ }
+ }
+ }
+
+ /* Space for application description */
+ if (application)
+ {
+ resp.datasize+=sizeof(uint16_t) /* len_app_description */;
+ if (application->application_description!=0)
+ {
+ resp.datasize+=strlen(application->application_description); /* app_description */
+ }
+ }
+ }
+ else
+ {
+ /* All applications, all contexts */
+ for (i=0;i<daemon->num_contexts;i++)
+ {
+ resp.datasize+=sizeof(uint16_t) /* len_context_description */;
+ if (daemon->contexts[i].context_description!=0)
+ {
+ resp.datasize+=strlen(daemon->contexts[i].context_description); /* context_description */
+ }
+ }
+
+ for (i=0;i<daemon->num_applications;i++)
+ {
+ resp.datasize+=sizeof(uint16_t) /* len_app_description */;
+ if (daemon->applications[i].application_description!=0)
+ {
+ resp.datasize+=strlen(daemon->applications[i].application_description); /* app_description */
+ }
+ }
+ }
+ }
+
+ if (verbose)
+ {
+ sprintf(str,"Allocate %d bytes for response msg databuffer\n", resp.datasize);
+ dlt_log(LOG_INFO, str);
+ }
+
+ /* Allocate buffer for response message */
+ resp.databuffer = (uint8_t *) malloc(resp.datasize);
+ if (resp.databuffer==0)
+ {
+ dlt_daemon_control_service_response(sock, daemon, DLT_SERVICE_ID_GET_LOG_INFO, DLT_SERVICE_RESPONSE_ERROR, verbose);
+ return;
+ }
+ memset(resp.databuffer,0,resp.datasize);
+ /* Preparation finished */
+
+ /* Prepare response */
+ sid = DLT_SERVICE_ID_GET_LOG_INFO;
+ memcpy(resp.databuffer,&sid,sizeof(uint32_t));
+ offset+=sizeof(uint32_t);
+
+ value = (((num_applications!=0)&&(num_contexts!=0))?req->options:8); /* 8 = no matching context found */
+
+ memcpy(resp.databuffer+offset,&value,sizeof(int8_t));
+ offset+=sizeof(int8_t);
+
+ count_app_ids = num_applications;
+
+ if (count_app_ids!=0)
+ {
+ memcpy(resp.databuffer+offset,&count_app_ids,sizeof(uint16_t));
+ offset+=sizeof(uint16_t);
+
+#if (DLT_DEBUG_GETLOGINFO==1)
+ sprintf(str,"#apid: %d \n", count_app_ids);
+ dlt_log(LOG_DEBUG, str);
+#endif
+
+ for (i=0;i<count_app_ids;i++)
+ {
+ if (req->apid[0]!='\0')
+ {
+ apid = req->apid;
+ }
+ else
+ {
+ if (daemon->applications)
+ {
+ apid = daemon->applications[i].apid;
+ }
+ else
+ {
+ /* This should never occur! */
+ apid=0;
+ }
+ }
+
+ application = dlt_daemon_application_find(daemon, apid, verbose);
+
+ if (application)
+ {
+ /* Calculate start offset within contexts[] */
+ offset_base=0;
+ for (j=0; j<(application-(daemon->applications)); j++)
+ {
+ offset_base+=daemon->applications[j].num_contexts;
+ }
+
+ dlt_set_id((char*)(resp.databuffer+offset),apid);
+ offset+=sizeof(ID4);
+
+#if (DLT_DEBUG_GETLOGINFO==1)
+ dlt_print_id(buf, apid);
+ sprintf(str,"apid: %s\n",buf);
+ dlt_log(LOG_DEBUG, str);
+#endif
+
+ if (req->apid[0]!='\0')
+ {
+ count_con_ids = num_contexts;
+ }
+ else
+ {
+ count_con_ids = application->num_contexts;
+ }
+
+ memcpy(resp.databuffer+offset,&count_con_ids,sizeof(uint16_t));
+ offset+=sizeof(uint16_t);
+
+#if (DLT_DEBUG_GETLOGINFO==1)
+ sprintf(str,"#ctid: %d \n", count_con_ids);
+ dlt_log(LOG_DEBUG, str);
+#endif
+
+ for (j=0;j<count_con_ids;j++)
+ {
+#if (DLT_DEBUG_GETLOGINFO==1)
+ sprintf(str,"j: %d \n",j);
+ dlt_log(LOG_DEBUG, str);
+#endif
+ if (!((count_con_ids==1) && (req->apid[0]!='\0') && (req->ctid[0]!='\0')))
+ {
+ context = &(daemon->contexts[offset_base+j]);
+ }
+ /* else: context was already searched and found
+ (one application (found) with one context (found))*/
+
+ if ((context) &&
+ ((req->ctid[0]=='\0') ||
+ ((req->ctid[0]!='\0') && (memcmp(context->ctid,req->ctid,DLT_ID_SIZE)==0)))
+ )
+ {
+ dlt_set_id((char*)(resp.databuffer+offset),context->ctid);
+ offset+=sizeof(ID4);
+
+#if (DLT_DEBUG_GETLOGINFO==1)
+ dlt_print_id(buf, context->ctid);
+ sprintf(str,"ctid: %s \n",buf);
+ dlt_log(LOG_DEBUG, str);
+#endif
+
+ /* Mode 4, 6, 7 */
+ if ((req->options==4) || (req->options==6) || (req->options==7))
+ {
+ ll=context->log_level;
+ memcpy(resp.databuffer+offset,&ll,sizeof(int8_t));
+ offset+=sizeof(int8_t);
+ }
+
+ /* Mode 5, 6, 7 */
+ if ((req->options==5) || (req->options==6) || (req->options==7))
+ {
+ ts=context->trace_status;
+ memcpy(resp.databuffer+offset,&ts,sizeof(int8_t));
+ offset+=sizeof(int8_t);
+ }
+
+ /* Mode 7 */
+ if (req->options==7)
+ {
+ if (context->context_description)
+ {
+ len = strlen(context->context_description);
+ memcpy(resp.databuffer+offset,&len,sizeof(uint16_t));
+ offset+=sizeof(uint16_t);
+ memcpy(resp.databuffer+offset,context->context_description,strlen(context->context_description));
+ offset+=strlen(context->context_description);
+ }
+ else
+ {
+ len = 0;
+ memcpy(resp.databuffer+offset,&len,sizeof(uint16_t));
+ offset+=sizeof(uint16_t);
+ }
+ }
+
+#if (DLT_DEBUG_GETLOGINFO==1)
+ sprintf(str,"ll=%d ts=%d \n",(int32_t)ll,(int32_t)ts);
+ dlt_log(LOG_DEBUG, str);
+#endif
+ }
+
+#if (DLT_DEBUG_GETLOGINFO==1)
+ dlt_log(LOG_DEBUG,"\n");
+#endif
+ }
+
+ /* Mode 7 */
+ if (req->options==7)
+ {
+ if (application->application_description)
+ {
+ len = strlen(application->application_description);
+ memcpy(resp.databuffer+offset,&len,sizeof(uint16_t));
+ offset+=sizeof(uint16_t);
+ memcpy(resp.databuffer+offset,application->application_description,strlen(application->application_description));
+ offset+=strlen(application->application_description);
+ }
+ else
+ {
+ len = 0;
+ memcpy(resp.databuffer+offset,&len,sizeof(uint16_t));
+ offset+=sizeof(uint16_t);
+ }
+ }
+ } /* if (application) */
+ } /* for (i=0;i<count_app_ids;i++) */
+ } /* if (count_app_ids!=0) */
+
+ dlt_set_id((char*)(resp.databuffer+offset),DLT_DAEMON_REMO_STRING);
+
+ /* send message */
+ dlt_daemon_control_send_control_message(sock,daemon,&resp,"","", verbose);
+
+ /* free message */
+ dlt_message_free(&resp,0);
+}
+
+void dlt_daemon_control_message_buffer_overflow(int sock, DltDaemon *daemon, int verbose)
+{
+ DltMessage msg;
+ DltServiceMessageBufferOverflowResponse *resp;
+
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ if (daemon==0)
+ {
+ return;
+ }
+
+ /* initialise new message */
+ if (dlt_message_init(&msg,0)==-1)
+ {
+ dlt_daemon_control_service_response(sock, daemon, DLT_SERVICE_ID_MESSAGE_BUFFER_OVERFLOW, DLT_SERVICE_RESPONSE_ERROR, verbose);
+ return;
+ }
+
+ /* prepare payload of data */
+ msg.datasize = sizeof(DltServiceMessageBufferOverflowResponse);
+ if (msg.databuffer)
+ {
+ free(msg.databuffer);
+ }
+ msg.databuffer = (uint8_t *) malloc(msg.datasize);
+ if (msg.databuffer==0)
+ {
+ if (sock!=DLT_DAEMON_STORE_TO_BUFFER)
+ {
+ dlt_daemon_control_service_response(sock, daemon, DLT_SERVICE_ID_MESSAGE_BUFFER_OVERFLOW, DLT_SERVICE_RESPONSE_ERROR, verbose);
+ }
+ return;
+ }
+
+ resp = (DltServiceMessageBufferOverflowResponse*) msg.databuffer;
+ resp->service_id = DLT_SERVICE_ID_MESSAGE_BUFFER_OVERFLOW;
+ resp->status = DLT_SERVICE_RESPONSE_OK;
+ resp->overflow = daemon->message_buffer_overflow;
+
+ /* send message */
+ dlt_daemon_control_send_control_message(sock,daemon,&msg,"","", verbose);
+
+ /* free message */
+ dlt_message_free(&msg,0);
+}
+
+void dlt_daemon_control_service_response( int sock, DltDaemon *daemon, uint32_t service_id, int8_t status , int verbose)
+{
+ DltMessage msg;
+ DltServiceResponse *resp;
+
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ if (daemon==0)
+ {
+ return;
+ }
+
+ /* initialise new message */
+ if (dlt_message_init(&msg,0)==-1)
+ {
+ return;
+ }
+
+ /* prepare payload of data */
+ msg.datasize = sizeof(DltServiceResponse);
+ if (msg.databuffer)
+ {
+ free(msg.databuffer);
+ }
+ msg.databuffer = (uint8_t *) malloc(msg.datasize);
+ if (msg.databuffer==0)
+ {
+ return;
+ }
+
+ resp = (DltServiceResponse*) msg.databuffer;
+ resp->service_id = service_id;
+ resp->status = status;
+
+ /* send message */
+ dlt_daemon_control_send_control_message(sock,daemon,&msg,"","", verbose);
+
+ /* free message */
+ dlt_message_free(&msg,0);
+}
+
+void dlt_daemon_control_send_control_message( int sock, DltDaemon *daemon, DltMessage *msg, char* appid, char* ctid, int verbose)
+{
+ ssize_t ret;
+ int32_t len;
+
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ if ((daemon==0) || (msg==0) || (appid==0) || (ctid==0))
+ {
+ return;
+ }
+
+ /* prepare storage header */
+ msg->storageheader = (DltStorageHeader*)msg->headerbuffer;
+
+ if (dlt_set_storageheader(msg->storageheader,daemon->ecuid)==-1)
+ {
+ return;
+ }
+
+ /* prepare standard header */
+ msg->standardheader = (DltStandardHeader*)(msg->headerbuffer + sizeof(DltStorageHeader));
+ msg->standardheader->htyp = DLT_HTYP_WEID | DLT_HTYP_WTMS | DLT_HTYP_UEH | DLT_HTYP_PROTOCOL_VERSION1 ;
+
+#if (BYTE_ORDER==BIG_ENDIAN)
+ msg->standardheader->htyp = ( msg->standardheader->htyp | DLT_HTYP_MSBF);
+#endif
+
+ msg->standardheader->mcnt = 0;
+
+ /* Set header extra parameters */
+ dlt_set_id(msg->headerextra.ecu,daemon->ecuid);
+
+ //msg->headerextra.seid = 0;
+
+ msg->headerextra.tmsp = dlt_uptime();
+
+ dlt_message_set_extraparameters(msg, verbose);
+
+ /* prepare extended header */
+ msg->extendedheader = (DltExtendedHeader*)(msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg->standardheader->htyp));
+ msg->extendedheader->msin = DLT_MSIN_CONTROL_RESPONSE;
+
+ msg->extendedheader->noar = 1; /* number of arguments */
+ if (strcmp(appid,"")==0)
+ {
+ dlt_set_id(msg->extendedheader->apid,DLT_DAEMON_CTRL_APID); /* application id */
+ }
+ else
+ {
+ dlt_set_id(msg->extendedheader->apid, appid);
+ }
+ if (strcmp(ctid,"")==0)
+ {
+ dlt_set_id(msg->extendedheader->ctid,DLT_DAEMON_CTRL_CTID); /* context id */
+ }
+ else
+ {
+ dlt_set_id(msg->extendedheader->ctid, ctid);
+ }
+
+ /* prepare length information */
+ msg->headersize = sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + sizeof(DltExtendedHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg->standardheader->htyp);
+
+ len=msg->headersize - sizeof(DltStorageHeader) + msg->datasize;
+ if (len>UINT16_MAX)
+ {
+ dlt_log(LOG_CRIT,"Huge control message discarded!\n");
+ return;
+ }
+
+ msg->standardheader->len = DLT_HTOBE_16(((uint16_t)len));
+
+ if (sock!=DLT_DAEMON_STORE_TO_BUFFER)
+ {
+ /* Send message */
+ if (isatty(sock))
+ {
+ DLT_DAEMON_SEM_LOCK();
+
+ /* Optional: Send serial header, if requested */
+ if (daemon->sendserialheader)
+ {
+ ret=write(sock,dltSerialHeader,sizeof(dltSerialHeader));
+ }
+
+ /* Send data */
+ ret=write(sock, msg->headerbuffer+sizeof(DltStorageHeader),msg->headersize-sizeof(DltStorageHeader));
+ ret=write(sock, msg->databuffer,msg->datasize);
+
+ DLT_DAEMON_SEM_FREE();
+ }
+ else
+ {
+ DLT_DAEMON_SEM_LOCK();
+
+ /* Optional: Send serial header, if requested */
+ if (daemon->sendserialheader)
+ {
+ send(sock, dltSerialHeader,sizeof(dltSerialHeader),0);
+ }
+
+ /* Send data */
+ send(sock, msg->headerbuffer+sizeof(DltStorageHeader),msg->headersize-sizeof(DltStorageHeader),0);
+ send(sock, msg->databuffer,msg->datasize,0);
+
+ DLT_DAEMON_SEM_FREE();
+ }
+ }
+ else
+ {
+ /* Store message in history buffer */
+ if (dlt_ringbuffer_put3(&(daemon->client_ringbuffer),
+ msg->headerbuffer+sizeof(DltStorageHeader),msg->headersize-sizeof(DltStorageHeader),
+ msg->databuffer,msg->datasize,
+ 0, 0
+ )<0)
+ {
+ dlt_log(LOG_ERR,"Storage of message in history buffer failed! Message discarded.\n");
+ return;
+ }
+ }
+}
+
+void dlt_daemon_control_reset_to_factory_default(DltDaemon *daemon,const char *filename, const char *filename1, int verbose)
+{
+ FILE *fd;
+
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ if ((daemon==0) || (filename==0) || (filename1==0) || (filename[0]=='\0') || (filename1[0]=='\0'))
+ {
+ return;
+ }
+
+ /* Check for runtime cfg file and delete it, if available */
+ fd=fopen(filename, "r");
+
+ if (fd!=0)
+ {
+ /* Close and delete file */
+ fclose(fd);
+ unlink(filename);
+ }
+
+ fd=fopen(filename1, "r");
+
+ if (fd!=0)
+ {
+ /* Close and delete file */
+ fclose(fd);
+ unlink(filename1);
+ }
+
+ daemon->default_log_level = DLT_DAEMON_INITIAL_LOG_LEVEL ;
+ daemon->default_trace_status = DLT_DAEMON_INITIAL_TRACE_STATUS ;
+
+ daemon->message_buffer_overflow = DLT_MESSAGE_BUFFER_NO_OVERFLOW;
+
+ /* Reset all other things (log level, trace status, etc.
+ to default values */
+
+ /* Inform user libraries about changed default log level/trace status */
+ dlt_daemon_user_send_default_update(daemon, verbose);
+}
+
+void dlt_daemon_user_send_default_update(DltDaemon *daemon, int verbose)
+{
+ int32_t count;
+ DltDaemonContext *context;
+
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ if (daemon==0)
+ {
+ return;
+ }
+
+ for (count=0;count<daemon->num_contexts; count ++)
+ {
+ context = &(daemon->contexts[count]);
+
+ if (context)
+ {
+ if ((context->log_level == DLT_LOG_DEFAULT) ||
+ (context->trace_status == DLT_TRACE_STATUS_DEFAULT))
+ {
+ if (context->user_handle!=0)
+ {
+ if (dlt_daemon_user_send_log_level(daemon, context, verbose)==-1)
+ {
+ return;
+ }
+ }
+ }
+ }
+ }
+}
+
+void dlt_daemon_control_message_time(int sock, DltDaemon *daemon, int verbose)
+{
+ DltMessage msg;
+ ssize_t ret;
+ int32_t len;
+
+ PRINT_FUNCTION_VERBOSE(verbose);
+
+ if (daemon==0)
+ {
+ return;
+ }
+
+ if (sock==DLT_DAEMON_STORE_TO_BUFFER)
+ {
+ return;
+ }
+
+ /* initialise new message */
+ if (dlt_message_init(&msg,0)==-1)
+ {
+ return;
+ }
+
+ /* prepare payload of data */
+ msg.datasize = 0;
+ if (msg.databuffer)
+ {
+ free(msg.databuffer);
+ }
+ msg.databuffer = 0;
+
+ /* send message */
+
+ /* prepare storage header */
+ msg.storageheader = (DltStorageHeader*)msg.headerbuffer;
+ dlt_set_storageheader(msg.storageheader,daemon->ecuid);
+
+ /* prepare standard header */
+ msg.standardheader = (DltStandardHeader*)(msg.headerbuffer + sizeof(DltStorageHeader));
+ msg.standardheader->htyp = DLT_HTYP_WEID | DLT_HTYP_WTMS | DLT_HTYP_UEH | DLT_HTYP_PROTOCOL_VERSION1 ;
+
+#if (BYTE_ORDER==BIG_ENDIAN)
+ msg.standardheader->htyp = ( msg.standardheader->htyp | DLT_HTYP_MSBF);
+#endif
+
+ msg.standardheader->mcnt = 0;
+
+ /* Set header extra parameters */
+ dlt_set_id(msg.headerextra.ecu,daemon->ecuid);
+ msg.headerextra.tmsp = dlt_uptime();
+
+ dlt_message_set_extraparameters(&msg, verbose);
+
+ /* prepare extended header */
+ msg.extendedheader = (DltExtendedHeader*)(msg.headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp));
+ msg.extendedheader->msin = DLT_MSIN_CONTROL_TIME;
+
+ msg.extendedheader->noar = 0; /* number of arguments */
+ dlt_set_id(msg.extendedheader->apid,""); /* application id */
+ dlt_set_id(msg.extendedheader->ctid,""); /* context id */
+
+ /* prepare length information */
+ msg.headersize = sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + sizeof(DltExtendedHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp);
+
+ len=msg.headersize - sizeof(DltStorageHeader) + msg.datasize;
+ if (len>UINT16_MAX)
+ {
+ dlt_log(LOG_CRIT,"Huge control message discarded!\n");
+
+ /* free message */
+ dlt_message_free(&msg,0);
+
+ return;
+ }
+
+ msg.standardheader->len = DLT_HTOBE_16(((uint16_t)len));
+
+ /* Send message */
+ if (isatty(sock))
+ {
+ DLT_DAEMON_SEM_LOCK();
+
+ /* Optional: Send serial header, if requested */
+ if (daemon->sendserialheader)
+ {
+ ret=write(sock,dltSerialHeader,sizeof(dltSerialHeader));
+ }
+
+ /* Send data */
+ ret=write(sock, msg.headerbuffer+sizeof(DltStorageHeader),msg.headersize-sizeof(DltStorageHeader));
+ ret=write(sock, msg.databuffer,msg.datasize);
+
+ DLT_DAEMON_SEM_FREE();
+ }
+ else
+ {
+ DLT_DAEMON_SEM_LOCK();
+
+ /* Optional: Send serial header, if requested */
+ if (daemon->sendserialheader)
+ {
+ send(sock, dltSerialHeader,sizeof(dltSerialHeader),0);
+ }
+
+ /* Send data */
+ send(sock, msg.headerbuffer+sizeof(DltStorageHeader),msg.headersize-sizeof(DltStorageHeader),0);
+ send(sock, msg.databuffer,msg.datasize,0);
+
+ DLT_DAEMON_SEM_FREE();
+ }
+
+ /* free message */
+ dlt_message_free(&msg,0);
+}
+
diff --git a/src/daemon/dlt_daemon_common.h b/src/daemon/dlt_daemon_common.h
new file mode 100755
index 0000000..fa0fe53
--- /dev/null
+++ b/src/daemon/dlt_daemon_common.h
@@ -0,0 +1,420 @@
+/*
+ * Dlt- Diagnostic Log and Trace daemon
+ * @licence app begin@
+ *
+ * Copyright (C) 2011, BMW AG - Alexander Wenzel <alexander.wenzel@bmw.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under the terms of the
+ * GNU Lesser General Public License, version 2.1, as published by the Free Software Foundation.
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
+ * Public License, version 2.1, for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License, version 2.1, along
+ * with this program; if not, see <http://www.gnu.org/licenses/lgpl-2.1.html>.
+ *
+ * Note that the copyright holders assume that the GNU Lesser General Public License, version 2.1, may
+ * also be applicable to programs even in cases in which the program is not a library in the technical sense.
+ *
+ * Linking DLT statically or dynamically with other modules is making a combined work based on DLT. You may
+ * license such other modules under the GNU Lesser General Public License, version 2.1. If you do not want to
+ * license your linked modules under the GNU Lesser General Public License, version 2.1, you
+ * may use the program under the following exception.
+ *
+ * As a special exception, the copyright holders of DLT give you permission to combine DLT
+ * with software programs or libraries that are released under any license unless such a combination is not
+ * permitted by the license of such a software program or library. You may copy and distribute such a
+ * system following the terms of the GNU Lesser General Public License, version 2.1, including this
+ * special exception, for DLT and the licenses of the other code concerned.
+ *
+ * Note that people who make modified versions of DLT are not obligated to grant this special exception
+ * for their modified versions; it is their choice whether to do so. The GNU Lesser General Public License,
+ * version 2.1, gives permission to release a modified version without this exception; this exception
+ * also makes it possible to release a modified version which carries forward this exception.
+ *
+ * @licence end@
+ */
+
+
+/*******************************************************************************
+** **
+** SRC-MODULE: dlt_daemon_common.h **
+** **
+** TARGET : linux **
+** **
+** PROJECT : DLT **
+** **
+** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de **
+** Markus Klein **
+** **
+** PURPOSE : **
+** **
+** REMARKS : **
+** **
+** PLATFORM DEPENDANT [yes/no]: yes **
+** **
+** TO BE CHANGED BY USER [yes/no]: no **
+** **
+*******************************************************************************/
+
+/*******************************************************************************
+** Author Identity **
+********************************************************************************
+** **
+** Initials Name Company **
+** -------- ------------------------- ---------------------------------- **
+** aw Alexander Wenzel BMW **
+** mk Markus Klein Fraunhofer ESK **
+*******************************************************************************/
+
+/*******************************************************************************
+** Revision Control History **
+*******************************************************************************/
+
+/*
+ * $LastChangedRevision: 1670 $
+ * $LastChangedDate: 2011-04-08 15:12:06 +0200 (Fr, 08. Apr 2011) $
+ * $LastChangedBy$
+ Initials Date Comment
+ aw 15.02.2010 initial
+ */
+
+#ifndef DLT_DAEMON_COMMON_H
+#define DLT_DAEMON_COMMON_H
+
+/**
+ \defgroup daemonapi DLT Daemon API
+ \addtogroup daemonapi
+ \{
+*/
+
+#include <semaphore.h>
+#include "dlt_common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define DLT_DAEMON_RINGBUFFER_SIZE 100000 /**< Ring buffer size for storing log messages while no client is connected */
+
+#define DLT_DAEMON_STORE_TO_BUFFER -2 /**< Constant value to identify the command "store to buffer" */
+
+/* Use a semaphore or mutex from your OS to prevent concurrent access to the DLT buffer. */
+
+#define DLT_DAEMON_SEM_LOCK() { sem_wait(&dlt_daemon_mutex); }
+#define DLT_DAEMON_SEM_FREE() { sem_post(&dlt_daemon_mutex); }
+extern sem_t dlt_daemon_mutex;
+
+
+/**
+ * The parameters of a daemon application.
+ */
+typedef struct
+{
+ char apid[DLT_ID_SIZE]; /**< application id */
+ pid_t pid; /**< process id of user application */
+ int user_handle; /**< connection handle for connection to user application */
+ char *application_description; /**< context description */
+ int num_contexts; /**< number of contexts for this application */
+} DltDaemonApplication;
+
+/**
+ * The parameters of a daemon context.
+ */
+typedef struct
+{
+ char apid[DLT_ID_SIZE]; /**< application id */
+ char ctid[DLT_ID_SIZE]; /**< context id */
+ int8_t log_level; /**< the current log level of the context */
+ int8_t trace_status; /**< the current trace status of the context */
+ int log_level_pos; /**< offset of context in context field on user application */
+ int user_handle; /**< connection handle for connection to user application */
+ char *context_description; /**< context description */
+} DltDaemonContext;
+
+/**
+ * The parameters of a daemon.
+ */
+typedef struct
+{
+ int num_contexts; /**< Total number of all contexts in all applications */
+ DltDaemonContext *contexts; /**< Pointer to contexts */
+ int num_applications; /**< Number of available application */
+ DltDaemonApplication *applications; /**< Pointer to applications */
+ int8_t default_log_level; /**< Default log level (of daemon) */
+ int8_t default_trace_status; /**< Default trace status (of daemon) */
+ int message_buffer_overflow; /**< Set to one, if buffer overflow has occured, zero otherwise */
+ int runtime_context_cfg_loaded; /**< Set to one, if runtime context configuration has been loaded, zero otherwise */
+ char ecuid[DLT_ID_SIZE]; /**< ECU ID of daemon */
+ int sendserialheader; /**< 1: send serial header; 0 don't send serial header */
+ int timingpackets; /**< 1: send continous timing packets; 0 don't send continous timing packets */
+ DltRingBuffer client_ringbuffer; /**< Ring-buffer for storing received logs while no client connection is available */
+} DltDaemon;
+
+/**
+ * Initialise the dlt daemon structure
+ * This function must be called before using further dlt daemon structure
+ * @param daemon pointer to dlt daemon structure
+ * @param verbose if set to true verbose information is printed out.
+ * @return negative value if there was an error
+ */
+int dlt_daemon_init(DltDaemon *daemon,int verbose);
+/**
+ * De-Initialise the dlt daemon structure
+ * @param daemon pointer to dlt daemon structure
+ * @param verbose if set to true verbose information is printed out.
+ * @return negative value if there was an error
+ */
+int dlt_daemon_free(DltDaemon *daemon,int verbose);
+
+/**
+ * Add (new) application to internal application management
+ * @param daemon pointer to dlt daemon structure
+ * @param apid pointer to application id
+ * @param pid process id of user application
+ * @param description description of application
+ * @param verbose if set to true verbose information is printed out.
+ * @return Pointer to added context, null pointer on error
+ */
+DltDaemonApplication* dlt_daemon_application_add(DltDaemon *daemon,char *apid,pid_t pid,char *description, int verbose);
+/**
+ * Delete application from internal application management
+ * @param daemon pointer to dlt daemon structure
+ * @param application pointer to application to be deleted
+ * @param verbose if set to true verbose information is printed out.
+ * @return negative value if there was an error
+ */
+int dlt_daemon_application_del(DltDaemon *daemon, DltDaemonApplication *application, int verbose);
+/**
+ * Find application with specific application id
+ * @param daemon pointer to dlt daemon structure
+ * @param apid pointer to application id
+ * @param verbose if set to true verbose information is printed out.
+ * @return Pointer to application, null pointer on error or not found
+ */
+DltDaemonApplication* dlt_daemon_application_find(DltDaemon *daemon,char *apid,int verbose);
+/**
+ * Load applications from file to internal context management
+ * @param daemon pointer to dlt daemon structure
+ * @param filename name of file to be used for loading
+ * @param verbose if set to true verbose information is printed out.
+ * @return negative value if there was an error
+ */
+int dlt_daemon_applications_load(DltDaemon *daemon,const char *filename, int verbose);
+/**
+ * Save applications from internal context management to file
+ * @param daemon pointer to dlt daemon structure
+ * @param filename name of file to be used for saving
+ * @param verbose if set to true verbose information is printed out.
+ * @return negative value if there was an error
+ */
+int dlt_daemon_applications_save(DltDaemon *daemon,const char *filename, int verbose);
+/**
+ * Clear all applications in internal application management
+ * @param daemon pointer to dlt daemon structure
+ * @param verbose if set to true verbose information is printed out.
+ * @return negative value if there was an error
+ */
+int dlt_daemon_applications_clear(DltDaemon *daemon,int verbose);
+
+/**
+ * Add (new) context to internal context management
+ * @param daemon pointer to dlt daemon structure
+ * @param apid pointer to application id
+ * @param ctid pointer to context id
+ * @param log_level log level of context
+ * @param trace_status trace status of context
+ * @param log_level_pos offset of context in context field on user application
+ * @param user_handle connection handle for connection to user application
+ * @param description description of context
+ * @param verbose if set to true verbose information is printed out.
+ * @return Pointer to added context, null pointer on error
+ */
+DltDaemonContext* dlt_daemon_context_add(DltDaemon *daemon,char *apid,char *ctid,int8_t log_level,int8_t trace_status,int log_level_pos, int user_handle,char *description,int verbose);
+/**
+ * Delete context from internal context management
+ * @param daemon pointer to dlt daemon structure
+ * @param context pointer to context to be deleted
+ * @param verbose if set to true verbose information is printed out.
+ * @return negative value if there was an error
+ */
+int dlt_daemon_context_del(DltDaemon *daemon, DltDaemonContext* context, int verbose);
+/**
+ * Find context with specific application id and context id
+ * @param daemon pointer to dlt daemon structure
+ * @param apid pointer to application id
+ * @param ctid pointer to context id
+ * @param verbose if set to true verbose information is printed out.
+ * @return Pointer to context, null pointer on error or not found
+ */
+DltDaemonContext* dlt_daemon_context_find(DltDaemon *daemon,char *apid,char *ctid,int verbose);
+/**
+ * Clear all contexts in internal context management
+ * @param daemon pointer to dlt daemon structure
+ * @param verbose if set to true verbose information is printed out.
+ * @return negative value if there was an error
+ */
+int dlt_daemon_contexts_clear(DltDaemon *daemon,int verbose);
+/**
+ * Load contexts from file to internal context management
+ * @param daemon pointer to dlt daemon structure
+ * @param filename name of file to be used for loading
+ * @param verbose if set to true verbose information is printed out.
+ * @return negative value if there was an error
+ */
+int dlt_daemon_contexts_load(DltDaemon *daemon,const char *filename, int verbose);
+/**
+ * Save contexts from internal context management to file
+ * @param daemon pointer to dlt daemon structure
+ * @param filename name of file to be used for saving
+ * @param verbose if set to true verbose information is printed out.
+ * @return negative value if there was an error
+ */
+int dlt_daemon_contexts_save(DltDaemon *daemon,const char *filename, int verbose);
+
+/**
+ * Send user message DLT_USER_MESSAGE_LOG_LEVEL to user application
+ * @param daemon pointer to dlt daemon structure
+ * @param context pointer to context for response
+ * @param verbose if set to true verbose information is printed out.
+ * @return negative value if there was an error
+ */
+int dlt_daemon_user_send_log_level(DltDaemon *daemon,DltDaemonContext *context, int verbose);
+/**
+ * Send user messages to all user applications using default context, or trace status
+ * to update those values
+ * @param daemon pointer to dlt daemon structure
+ * @param verbose if set to true verbose information is printed out.
+ */
+void dlt_daemon_user_send_default_update(DltDaemon *daemon, int verbose);
+
+/**
+ * Process received control message from dlt client
+ * @param sock connection handle used for sending response
+ * @param daemon pointer to dlt daemon structure
+ * @param msg pointer to received control message
+ * @param verbose if set to true verbose information is printed out.
+ */
+int dlt_daemon_control_process_control(int sock, DltDaemon *daemon, DltMessage *msg, int verbose);
+/**
+ * Generate response to control message from dlt client
+ * @param sock connection handle used for sending response
+ * @param daemon pointer to dlt daemon structure
+ * @param service_id service id of control message
+ * @param status status of response (e.g. ok, not supported, error)
+ * @param verbose if set to true verbose information is printed out.
+ */
+void dlt_daemon_control_service_response(int sock, DltDaemon *daemon, uint32_t service_id, int8_t status, int verbose);
+/**
+ * Send out response message to dlt client
+ * @param sock connection handle used for sending response
+ * @param daemon pointer to dlt daemon structure
+ * @param msg pointer to response message
+ * @param appid pointer to application id to be used in response message
+ * @param contid pointer to context id to be used in response message
+ * @param verbose if set to true verbose information is printed out.
+ */
+void dlt_daemon_control_send_control_message(int sock, DltDaemon *daemon, DltMessage *msg, char* appid, char* contid, int verbose);
+
+/**
+ * Process and generate response to received sw injection control message
+ * @param sock connection handle used for sending response
+ * @param daemon pointer to dlt daemon structure
+ * @param msg pointer to received sw injection control message
+ * @param verbose if set to true verbose information is printed out.
+ */
+void dlt_daemon_control_callsw_cinjection(int sock, DltDaemon *daemon, DltMessage *msg, int verbose);
+/**
+ * Process and generate response to received set log level control message
+ * @param sock connection handle used for sending response
+ * @param daemon pointer to dlt daemon structure
+ * @param msg pointer to received control message
+ * @param verbose if set to true verbose information is printed out.
+ */
+void dlt_daemon_control_set_log_level(int sock, DltDaemon *daemon, DltMessage *msg, int verbose);
+/**
+ * Process and generate response to received set trace status control message
+ * @param sock connection handle used for sending response
+ * @param daemon pointer to dlt daemon structure
+ * @param msg pointer to received control message
+ * @param verbose if set to true verbose information is printed out.
+ */
+void dlt_daemon_control_set_trace_status(int sock, DltDaemon *daemon, DltMessage *msg, int verbose);
+/**
+ * Process and generate response to received set default log level control message
+ * @param sock connection handle used for sending response
+ * @param daemon pointer to dlt daemon structure
+ * @param msg pointer to received control message
+ * @param verbose if set to true verbose information is printed out.
+ */
+void dlt_daemon_control_set_default_log_level(int sock, DltDaemon *daemon, DltMessage *msg, int verbose);
+/**
+ * Process and generate response to received set default trace status control message
+ * @param sock connection handle used for sending response
+ * @param daemon pointer to dlt daemon structure
+ * @param msg pointer to received control message
+ * @param verbose if set to true verbose information is printed out.
+ */
+void dlt_daemon_control_set_default_trace_status(int sock, DltDaemon *daemon, DltMessage *msg, int verbose);
+/**
+ * Process and generate response to set timing packets control message
+ * @param sock connection handle used for sending response
+ * @param daemon pointer to dlt daemon structure
+ * @param msg pointer to received control message
+ * @param verbose if set to true verbose information is printed out.
+ */
+void dlt_daemon_control_set_timing_packets(int sock, DltDaemon *daemon, DltMessage *msg, int verbose);
+/**
+ * Process and generate response to received get software version control message
+ * @param sock connection handle used for sending response
+ * @param daemon pointer to dlt daemon structure
+ * @param verbose if set to true verbose information is printed out.
+ */
+void dlt_daemon_control_get_software_version(int sock, DltDaemon *daemon, int verbose);
+/**
+ * Process and generate response to received get default log level control message
+ * @param sock connection handle used for sending response
+ * @param daemon pointer to dlt daemon structure
+ * @param verbose if set to true verbose information is printed out.
+ */
+void dlt_daemon_control_get_default_log_level(int sock, DltDaemon *daemon, int verbose);
+/**
+ * Process and generate response to received get log info control message
+ * @param sock connection handle used for sending response
+ * @param daemon pointer to dlt daemon structure
+ * @param msg pointer to received control message
+ * @param verbose if set to true verbose information is printed out.
+ */
+void dlt_daemon_control_get_log_info(int sock, DltDaemon *daemon, DltMessage *msg, int verbose);
+/**
+ * Process and generate response to message buffer overflow control message
+ * @param sock connection handle used for sending response
+ * @param daemon pointer to dlt daemon structure
+ * @param verbose if set to true verbose information is printed out.
+ */
+void dlt_daemon_control_message_buffer_overflow(int sock, DltDaemon *daemon, int verbose);
+/**
+ * Process reset to factory default control message
+ * @param daemon pointer to dlt daemon structure
+ * @param filename name of file containing the runtime defaults for applications
+ * @param filename1 name of file containing the runtime defaults for contexts
+ * @param verbose if set to true verbose information is printed out.
+ */
+void dlt_daemon_control_reset_to_factory_default(DltDaemon *daemon,const char *filename, const char *filename1, int verbose);
+/**
+ * Send time control message
+ * @param sock connection handle used for sending response
+ * @param daemon pointer to dlt daemon structure
+ * @param verbose if set to true verbose information is printed out.
+ */
+void dlt_daemon_control_message_time(int sock, DltDaemon *daemon, int verbose);
+
+#ifdef __cplusplus
+}
+#endif
+
+/**
+ \}
+*/
+
+#endif /* DLT_DAEMON_COMMON_H */
diff --git a/src/daemon/dlt_daemon_common_cfg.h b/src/daemon/dlt_daemon_common_cfg.h
new file mode 100755
index 0000000..57db30e
--- /dev/null
+++ b/src/daemon/dlt_daemon_common_cfg.h
@@ -0,0 +1,129 @@
+/*
+ * Dlt- Diagnostic Log and Trace daemon
+ * @licence app begin@
+ *
+ * Copyright (C) 2011, BMW AG - Alexander Wenzel <alexander.wenzel@bmw.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under the terms of the
+ * GNU Lesser General Public License, version 2.1, as published by the Free Software Foundation.
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
+ * Public License, version 2.1, for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License, version 2.1, along
+ * with this program; if not, see <http://www.gnu.org/licenses/lgpl-2.1.html>.
+ *
+ * Note that the copyright holders assume that the GNU Lesser General Public License, version 2.1, may
+ * also be applicable to programs even in cases in which the program is not a library in the technical sense.
+ *
+ * Linking DLT statically or dynamically with other modules is making a combined work based on DLT. You may
+ * license such other modules under the GNU Lesser General Public License, version 2.1. If you do not want to
+ * license your linked modules under the GNU Lesser General Public License, version 2.1, you
+ * may use the program under the following exception.
+ *
+ * As a special exception, the copyright holders of DLT give you permission to combine DLT
+ * with software programs or libraries that are released under any license unless such a combination is not
+ * permitted by the license of such a software program or library. You may copy and distribute such a
+ * system following the terms of the GNU Lesser General Public License, version 2.1, including this
+ * special exception, for DLT and the licenses of the other code concerned.
+ *
+ * Note that people who make modified versions of DLT are not obligated to grant this special exception
+ * for their modified versions; it is their choice whether to do so. The GNU Lesser General Public License,
+ * version 2.1, gives permission to release a modified version without this exception; this exception
+ * also makes it possible to release a modified version which carries forward this exception.
+ *
+ * @licence end@
+ */
+
+
+/*******************************************************************************
+** **
+** SRC-MODULE: dlt_daemon_common_cfg.h **
+** **
+** TARGET : linux **
+** **
+** PROJECT : DLT **
+** **
+** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de **
+** Markus Klein **
+** **
+** PURPOSE : **
+** **
+** REMARKS : **
+** **
+** PLATFORM DEPENDANT [yes/no]: yes **
+** **
+** TO BE CHANGED BY USER [yes/no]: no **
+** **
+*******************************************************************************/
+
+/*******************************************************************************
+** Author Identity **
+********************************************************************************
+** **
+** Initials Name Company **
+** -------- ------------------------- ---------------------------------- **
+** aw Alexander Wenzel BMW **
+** mk Markus Klein Fraunhofer ESK **
+*******************************************************************************/
+
+/*******************************************************************************
+** Author Identity **
+********************************************************************************
+** **
+** Initials Name Company **
+** -------- ------------------------- ---------------------------------- **
+** aw Alexander Wenzel BMW **
+** mk Markus Klein Fraunhofer ESK **
+*******************************************************************************/
+
+#ifndef DLT_DAEMON_COMMON_CFG_H
+#define DLT_DAEMON_COMMON_CFG_H
+
+/*************/
+/* Changable */
+/*************/
+
+/* Path and filename for runtime configuration (applications) */
+#define DLT_RUNTIME_APPLICATION_CFG "/tmp/dlt-runtime-application.cfg"
+/* Path and filename for runtime configuration (contexts) */
+#define DLT_RUNTIME_CONTEXT_CFG "/tmp/dlt-runtime-context.cfg"
+
+/* Size of text buffer */
+#define DLT_DAEMON_TEXTBUFSIZE 255
+
+/* Initial log level */
+#define DLT_DAEMON_INITIAL_LOG_LEVEL DLT_LOG_INFO
+/* Initial trace status */
+#define DLT_DAEMON_INITIAL_TRACE_STATUS DLT_TRACE_STATUS_OFF
+
+/* Application ID used when the dlt daemon creates a control message */
+#define DLT_DAEMON_CTRL_APID "DA1"
+/* Context ID used when the dlt daemon creates a control message */
+#define DLT_DAEMON_CTRL_CTID "DC1"
+
+/* Number of entries to be allocated at one in application table,
+ when no more entries are available */
+#define DLT_DAEMON_APPL_ALLOC_SIZE 500
+/* Number of entries to be allocated at one in context table,
+ when no more entries are available */
+#define DLT_DAEMON_CONTEXT_ALLOC_SIZE 1000
+
+/* Debug get log info function,
+ set to 1 to enable, 0 to disable debugging */
+#define DLT_DEBUG_GETLOGINFO 0
+
+/************************/
+/* Don't change please! */
+/************************/
+
+/* Minimum ID for an injection message */
+#define DLT_DAEMON_INJECTION_MIN 0xFFF
+/* Maximum ID for an injection message */
+#define DLT_DAEMON_INJECTION_MAX 0xFFFFFFFF
+
+/* Remote interface identifier */
+#define DLT_DAEMON_REMO_STRING "remo"
+
+#endif /* DLT_DAEMON_COMMON_CFG_H */
+