summaryrefslogtreecommitdiff
path: root/src/daemon/dlt_daemon_common.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/daemon/dlt_daemon_common.c')
-rwxr-xr-xsrc/daemon/dlt_daemon_common.c2196
1 files changed, 2196 insertions, 0 deletions
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);
+}
+