3 * Copyright (C) 2012 BMW AG
5 * This file is part of GENIVI Project Dlt - Diagnostic Log and Trace console apps.
7 * Contributions are licensed to the GENIVI Alliance under one or more
8 * Contribution License Agreements.
11 * This Source Code Form is subject to the terms of the
12 * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with
13 * this file, You can obtain one at http://mozilla.org/MPL/2.0/.
16 * \author Alexander Wenzel <alexander.aw.wenzel@bmw.de> BMW 2011-2012
18 * \file dlt_daemon_common.c
19 * For further information see http://www.genivi.org/.
23 /*******************************************************************************
25 ** SRC-MODULE: dlt_daemon_common.c **
31 ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de **
38 ** PLATFORM DEPENDANT [yes/no]: yes **
40 ** TO BE CHANGED BY USER [yes/no]: no **
42 *******************************************************************************/
44 /*******************************************************************************
46 ********************************************************************************
48 ** Initials Name Company **
49 ** -------- ------------------------- ---------------------------------- **
50 ** aw Alexander Wenzel BMW **
51 ** mk Markus Klein Fraunhofer ESK **
52 *******************************************************************************/
54 /*******************************************************************************
55 ** Revision Control History **
56 *******************************************************************************/
59 * $LastChangedRevision: 1670 $
60 * $LastChangedDate: 2011-04-08 15:12:06 +0200 (Fr, 08. Apr 2011) $
74 #include <sys/types.h> /* send() */
75 #include <sys/socket.h> /* send() */
77 #include "dlt_types.h"
78 #include "dlt_daemon_common.h"
79 #include "dlt_daemon_common_cfg.h"
80 #include "dlt_user_shared.h"
81 #include "dlt_user_shared_cfg.h"
83 static char str[DLT_DAEMON_COMMON_TEXTBUFSIZE];
85 sem_t dlt_daemon_mutex;
87 static int dlt_daemon_cmp_apid(const void *m1, const void *m2)
89 DltDaemonApplication *mi1 = (DltDaemonApplication *) m1;
90 DltDaemonApplication *mi2 = (DltDaemonApplication *) m2;
92 return memcmp(mi1->apid, mi2->apid, DLT_ID_SIZE);
95 static int dlt_daemon_cmp_apid_ctid(const void *m1, const void *m2)
99 DltDaemonContext *mi1 = (DltDaemonContext *) m1;
100 DltDaemonContext *mi2 = (DltDaemonContext *) m2;
102 cmp=memcmp(mi1->apid, mi2->apid, DLT_ID_SIZE);
109 ret=memcmp(mi1->ctid, mi2->ctid, DLT_ID_SIZE);
119 int dlt_daemon_init(DltDaemon *daemon,const char *runtime_directory, int verbose)
121 PRINT_FUNCTION_VERBOSE(verbose);
128 daemon->num_contexts = 0;
129 daemon->contexts = 0;
131 daemon->num_applications = 0;
132 daemon->applications = 0;
134 daemon->default_log_level = DLT_DAEMON_INITIAL_LOG_LEVEL ;
135 daemon->default_trace_status = DLT_DAEMON_INITIAL_TRACE_STATUS ;
137 daemon->message_buffer_overflow = DLT_MESSAGE_BUFFER_NO_OVERFLOW;
139 daemon->runtime_context_cfg_loaded = 0;
141 daemon->mode = DLT_USER_MODE_EXTERNAL;
143 /* prepare filenames for configuration */
144 if(runtime_directory[0])
145 strcpy(daemon->runtime_application_cfg,runtime_directory);
147 strcpy(daemon->runtime_application_cfg,DLT_RUNTIME_DEFAULT_DIRECTORY);
148 strcat(daemon->runtime_application_cfg,DLT_RUNTIME_APPLICATION_CFG);
149 if(runtime_directory[0])
150 strcpy(daemon->runtime_context_cfg,runtime_directory);
152 strcpy(daemon->runtime_context_cfg,DLT_RUNTIME_DEFAULT_DIRECTORY);
153 strcat(daemon->runtime_context_cfg,DLT_RUNTIME_CONTEXT_CFG);
154 if(runtime_directory[0])
155 strcpy(daemon->runtime_configuration,runtime_directory);
157 strcpy(daemon->runtime_configuration,DLT_RUNTIME_DEFAULT_DIRECTORY);
158 strcat(daemon->runtime_configuration,DLT_RUNTIME_CONFIGURATION);
160 /* Check for runtime cfg, if it is loadable, load it! */
161 if ((dlt_daemon_applications_load(daemon,daemon->runtime_application_cfg, verbose)==0) &&
162 (dlt_daemon_contexts_load(daemon,daemon->runtime_context_cfg, verbose)==0))
164 daemon->runtime_context_cfg_loaded = 1;
167 /* load configuration if available */
168 dlt_daemon_configuration_load(daemon,daemon->runtime_configuration, verbose);
170 daemon->sendserialheader = 0;
171 daemon->timingpackets = 0;
173 dlt_set_id(daemon->ecuid,"");
175 /* initialize ring buffer for client connection */
176 if (dlt_buffer_init_dynamic(&(daemon->client_ringbuffer), DLT_DAEMON_RINGBUFFER_MIN_SIZE,DLT_DAEMON_RINGBUFFER_MAX_SIZE,DLT_DAEMON_RINGBUFFER_STEP_SIZE)==-1)
184 int dlt_daemon_free(DltDaemon *daemon,int verbose)
186 PRINT_FUNCTION_VERBOSE(verbose);
194 if (dlt_daemon_contexts_clear(daemon, verbose)==-1)
199 /* Free applications */
200 if (dlt_daemon_applications_clear(daemon, verbose)==-1)
205 /* free ringbuffer */
206 dlt_buffer_free_dynamic(&(daemon->client_ringbuffer));
211 int dlt_daemon_applications_invalidate_fd(DltDaemon *daemon,int fd,int verbose)
215 PRINT_FUNCTION_VERBOSE(verbose);
222 for (i=0; i<daemon->num_applications; i++)
224 if (daemon->applications[i].user_handle==fd)
226 daemon->applications[i].user_handle = DLT_FD_INIT;
233 int dlt_daemon_applications_clear(DltDaemon *daemon,int verbose)
237 PRINT_FUNCTION_VERBOSE(verbose);
244 for (i=0; i<daemon->num_applications; i++)
246 if (daemon->applications[i].application_description!=0)
248 free(daemon->applications[i].application_description);
249 daemon->applications[i].application_description = 0;
253 if (daemon->applications)
255 free(daemon->applications);
258 daemon->applications = 0;
259 daemon->num_applications = 0;
264 DltDaemonApplication* dlt_daemon_application_add(DltDaemon *daemon,char *apid,pid_t pid,char *description, int verbose)
266 DltDaemonApplication *application;
267 DltDaemonApplication *old;
270 char filename[DLT_DAEMON_COMMON_TEXTBUFSIZE];
272 if ((daemon==0) || (apid==0) || (apid[0]=='\0'))
274 return (DltDaemonApplication*) 0;
277 if (daemon->applications == 0)
279 daemon->applications = (DltDaemonApplication*) malloc(sizeof(DltDaemonApplication)*DLT_DAEMON_APPL_ALLOC_SIZE);
280 if (daemon->applications==0)
282 return (DltDaemonApplication*) 0;
288 /* Check if application [apid] is already available */
289 application = dlt_daemon_application_find(daemon, apid, verbose);
292 daemon->num_applications += 1;
294 if (daemon->num_applications!=0)
296 if ((daemon->num_applications%DLT_DAEMON_APPL_ALLOC_SIZE)==0)
298 /* allocate memory in steps of DLT_DAEMON_APPL_ALLOC_SIZE, e.g. 100 */
299 old = daemon->applications;
300 daemon->applications = (DltDaemonApplication*) malloc(sizeof(DltDaemonApplication)*
301 ((daemon->num_applications/DLT_DAEMON_APPL_ALLOC_SIZE)+1)*DLT_DAEMON_APPL_ALLOC_SIZE);
302 if (daemon->applications==0)
304 daemon->applications = old;
305 daemon->num_applications -= 1;
306 return (DltDaemonApplication*) 0;
308 memcpy(daemon->applications,old,sizeof(DltDaemonApplication)*daemon->num_applications);
313 application = &(daemon->applications[daemon->num_applications-1]);
315 dlt_set_id(application->apid,apid);
316 application->pid = pid;
317 application->application_description = 0;
318 application->num_contexts = 0;
319 application->user_handle = DLT_FD_INIT;
325 snprintf(str,DLT_DAEMON_COMMON_TEXTBUFSIZE, "Duplicate registration of AppId: %s\n",apid);
326 dlt_log(LOG_ERR, str);
330 /* Store application description and pid of application */
331 if (application->application_description)
333 free(application->application_description);
334 application->application_description=0;
339 application->application_description = malloc(strlen(description)+1);
340 if (application->application_description)
342 strncpy(application->application_description,description,strlen(description)+1);
343 application->application_description[strlen(description)]='\0';
347 if( application->user_handle != DLT_FD_INIT )
349 if( application->pid != pid )
351 if ( close(application->user_handle) < 0 )
353 snprintf(str,DLT_DAEMON_COMMON_TEXTBUFSIZE, "close() failed to %s, errno=%d (%s)!\n",filename,errno,strerror(errno)); /* errno 2: ENOENT - No such file or directory */
354 dlt_log(LOG_ERR, str);
357 application->user_handle = DLT_FD_INIT;
358 application->pid = pid;
362 /* open user pipe only if it is not yet opened */
363 if (application->user_handle==DLT_FD_INIT && pid!=0)
365 sprintf(filename,"%s/dlt%d",DLT_USER_DIR,application->pid);
367 dlt_user_handle = open(filename, O_WRONLY|O_NONBLOCK);
368 if ( dlt_user_handle < 0 )
370 snprintf(str,DLT_DAEMON_COMMON_TEXTBUFSIZE, "open() failed to %s, errno=%d (%s)!\n",filename,errno,strerror(errno)); /* errno 2: ENOENT - No such file or directory */
371 dlt_log(LOG_ERR, str);
374 /* check if file file descriptor was already used, and make it invalid if it is reused */
375 /* This prevents sending messages to wrong file descriptor */
376 dlt_daemon_applications_invalidate_fd(daemon,dlt_user_handle,verbose);
377 dlt_daemon_contexts_invalidate_fd(daemon,dlt_user_handle,verbose);
379 application->user_handle = dlt_user_handle;
385 qsort(daemon->applications,daemon->num_applications,sizeof(DltDaemonApplication),dlt_daemon_cmp_apid);
387 /* Find new position of application with apid*/
388 application = dlt_daemon_application_find(daemon, apid, verbose);
394 int dlt_daemon_application_del(DltDaemon *daemon, DltDaemonApplication *application, int verbose)
398 PRINT_FUNCTION_VERBOSE(verbose);
400 if ((daemon==0) || (application==0))
405 if (daemon->num_applications>0)
407 /* Check if user handle is open; if yes, close it */
408 if (application->user_handle >= DLT_FD_MINIMUM)
410 close(application->user_handle);
411 application->user_handle=DLT_FD_INIT;
414 /* Free description of application to be deleted */
415 if (application->application_description)
417 free(application->application_description);
418 application->application_description = 0;
421 pos = application-(daemon->applications);
423 /* move all applications above pos to pos */
424 memmove(&(daemon->applications[pos]),&(daemon->applications[pos+1]), sizeof(DltDaemonApplication)*((daemon->num_applications-1)-pos));
426 /* Clear last application */
427 memset(&(daemon->applications[daemon->num_applications-1]),0,sizeof(DltDaemonApplication));
429 daemon->num_applications--;
436 DltDaemonApplication* dlt_daemon_application_find(DltDaemon *daemon,char *apid,int verbose)
438 DltDaemonApplication application;
440 PRINT_FUNCTION_VERBOSE(verbose);
442 if ((daemon==0) || (apid==0) || (apid[0]=='\0') || (daemon->num_applications==0))
444 return (DltDaemonApplication*) 0;
447 /* Check, if apid is smaller than smallest apid or greater than greatest apid */
448 if ((memcmp(apid,daemon->applications[0].apid,DLT_ID_SIZE)<0) ||
449 (memcmp(apid,daemon->applications[daemon->num_applications-1].apid,DLT_ID_SIZE)>0))
451 return (DltDaemonApplication*) 0;
454 dlt_set_id(application.apid,apid);
455 return (DltDaemonApplication*)bsearch(&application,daemon->applications,daemon->num_applications,sizeof(DltDaemonApplication),dlt_daemon_cmp_apid);
458 int dlt_daemon_applications_load(DltDaemon *daemon,const char *filename, int verbose)
462 char buf[DLT_DAEMON_COMMON_TEXTBUFSIZE];
466 PRINT_FUNCTION_VERBOSE(verbose);
468 if ((daemon==0) || (filename==0) || (filename[0]=='\0'))
473 fd=fopen(filename, "r");
483 memset(buf, 0, sizeof(buf));
486 ret=fgets(buf,sizeof(buf),fd);
488 if (strcmp(buf,"")!=0)
494 /* pb contains now the description */
496 /* pid is unknown at loading time */
497 if (dlt_daemon_application_add(daemon,apid,0,pb,verbose)==0)
509 int dlt_daemon_applications_save(DltDaemon *daemon,const char *filename, int verbose)
514 char apid[DLT_ID_SIZE+1]; /* DLT_ID_SIZE+1, because the 0-termination is required here */
516 PRINT_FUNCTION_VERBOSE(verbose);
518 if ((daemon==0) || (filename==0) || (filename[0]=='\0'))
523 memset(apid,0, sizeof(apid));
525 if ((daemon->applications) && (daemon->num_applications>0))
527 fd=fopen(filename, "w");
530 for (i=0; i<daemon->num_applications; i++)
532 dlt_set_id(apid,daemon->applications[i].apid);
534 if ((daemon->applications[i].application_description) &&
535 (daemon->applications[i].application_description!='\0'))
537 fprintf(fd,"%s:%s:\n",apid, daemon->applications[i].application_description);
541 fprintf(fd,"%s::\n",apid);
551 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)
553 DltDaemonApplication *application;
554 DltDaemonContext *context;
555 DltDaemonContext *old;
558 PRINT_FUNCTION_VERBOSE(verbose);
560 if ((daemon==0) || (apid==0) || (apid[0]=='\0') || (ctid==0) || (ctid[0]=='\0'))
562 return (DltDaemonContext*) 0;
565 if ((log_level<DLT_LOG_DEFAULT) || (log_level>DLT_LOG_VERBOSE))
567 return (DltDaemonContext*) 0;
570 if ((trace_status<DLT_TRACE_STATUS_DEFAULT) || (trace_status>DLT_TRACE_STATUS_ON))
572 return (DltDaemonContext*) 0;
575 if (daemon->contexts == 0)
577 daemon->contexts = (DltDaemonContext*) malloc(sizeof(DltDaemonContext)*DLT_DAEMON_CONTEXT_ALLOC_SIZE);
578 if (daemon->contexts==0)
580 return (DltDaemonContext*) 0;
584 /* Check if application [apid] is available */
585 application = dlt_daemon_application_find(daemon, apid, verbose);
588 return (DltDaemonContext*) 0;
591 /* Check if context [apid, ctid] is already available */
592 context = dlt_daemon_context_find(daemon, apid, ctid, verbose);
595 daemon->num_contexts += 1;
597 if (daemon->num_contexts!=0)
599 if ((daemon->num_contexts%DLT_DAEMON_CONTEXT_ALLOC_SIZE)==0)
601 /* allocate memory for context in steps of DLT_DAEMON_CONTEXT_ALLOC_SIZE, e.g 100 */
602 old = daemon->contexts;
603 daemon->contexts = (DltDaemonContext*) malloc(sizeof(DltDaemonContext)*
604 ((daemon->num_contexts/DLT_DAEMON_CONTEXT_ALLOC_SIZE)+1)*DLT_DAEMON_CONTEXT_ALLOC_SIZE);
605 if (daemon->contexts==0)
607 daemon->contexts = old;
608 daemon->num_contexts -= 1;
609 return (DltDaemonContext*) 0;
611 memcpy(daemon->contexts,old,sizeof(DltDaemonContext)*daemon->num_contexts);
616 context = &(daemon->contexts[daemon->num_contexts-1]);
618 dlt_set_id(context->apid,apid);
619 dlt_set_id(context->ctid,ctid);
620 context->context_description = 0;
622 application->num_contexts++;
626 /* Set context description */
627 if (context->context_description)
629 free(context->context_description);
630 context->context_description=0;
635 context->context_description = malloc(strlen(description)+1);
637 if (context->context_description)
639 strncpy(context->context_description,description,strlen(description)+1);
640 context->context_description[strlen(description)]='\0';
644 /* Store log level and trace status,
645 if this is a new context, or
646 if this is an old context and the runtime cfg was not loaded */
648 if ((new_context==1) ||
649 ((new_context==0) && (daemon->runtime_context_cfg_loaded==0)))
651 context->log_level = log_level;
652 context->trace_status = trace_status;
655 context->log_level_pos = log_level_pos;
656 context->user_handle = user_handle;
661 qsort(daemon->contexts,daemon->num_contexts, sizeof(DltDaemonContext),dlt_daemon_cmp_apid_ctid);
663 /* Find new position of context with apid, ctid */
664 context = dlt_daemon_context_find(daemon, apid, ctid, verbose);
670 int dlt_daemon_context_del(DltDaemon *daemon, DltDaemonContext* context, int verbose)
673 DltDaemonApplication *application;
675 PRINT_FUNCTION_VERBOSE(verbose);
677 if ((daemon==0) || (context==0))
682 if (daemon->num_contexts>0)
684 application = dlt_daemon_application_find(daemon, context->apid, verbose);
686 /* Free description of context to be deleted */
687 if (context->context_description)
689 free(context->context_description);
690 context->context_description = 0;
693 pos = context-(daemon->contexts);
695 /* move all contexts above pos to pos */
696 memmove(&(daemon->contexts[pos]),&(daemon->contexts[pos+1]), sizeof(DltDaemonContext)*((daemon->num_contexts-1)-pos));
698 /* Clear last context */
699 memset(&(daemon->contexts[daemon->num_contexts-1]),0,sizeof(DltDaemonContext));
701 daemon->num_contexts--;
703 /* Check if application [apid] is available */
706 application->num_contexts--;
713 DltDaemonContext* dlt_daemon_context_find(DltDaemon *daemon,char *apid,char *ctid,int verbose)
715 DltDaemonContext context;
717 PRINT_FUNCTION_VERBOSE(verbose);
719 if ((daemon==0) || (apid==0) || (apid[0]=='\0') || (ctid==0) || (ctid[0]=='\0') || (daemon->num_contexts==0))
721 return (DltDaemonContext*) 0;
724 /* Check, if apid is smaller than smallest apid or greater than greatest apid */
725 if ((memcmp(apid,daemon->contexts[0].apid,DLT_ID_SIZE)<0) ||
726 (memcmp(apid,daemon->contexts[daemon->num_contexts-1].apid,DLT_ID_SIZE)>0))
728 return (DltDaemonContext*) 0;
731 dlt_set_id(context.apid,apid);
732 dlt_set_id(context.ctid,ctid);
734 return (DltDaemonContext*)bsearch(&context,daemon->contexts,daemon->num_contexts,sizeof(DltDaemonContext),dlt_daemon_cmp_apid_ctid);
737 int dlt_daemon_contexts_invalidate_fd(DltDaemon *daemon,int fd,int verbose)
741 PRINT_FUNCTION_VERBOSE(verbose);
748 for (i=0; i<daemon->num_contexts; i++)
750 if (daemon->contexts[i].user_handle==fd)
752 daemon->contexts[i].user_handle = DLT_FD_INIT;
759 int dlt_daemon_contexts_clear(DltDaemon *daemon,int verbose)
763 PRINT_FUNCTION_VERBOSE(verbose);
770 for (i=0; i<daemon->num_contexts; i++)
772 if (daemon->contexts[i].context_description!=0)
774 free(daemon->contexts[i].context_description);
775 daemon->contexts[i].context_description = 0;
779 if (daemon->contexts)
781 free(daemon->contexts);
784 daemon->contexts = 0;
786 for (i=0; i<daemon->num_applications; i++)
788 daemon->applications[i].num_contexts = 0;
791 daemon->num_contexts = 0;
796 int dlt_daemon_contexts_load(DltDaemon *daemon,const char *filename, int verbose)
800 char buf[DLT_DAEMON_COMMON_TEXTBUFSIZE];
805 PRINT_FUNCTION_VERBOSE(verbose);
807 if ((daemon==0) || (filename==0) ||( filename[0]=='\0'))
812 fd=fopen(filename, "r");
822 memset(buf, 0, sizeof(buf));
825 ret=fgets(buf,sizeof(buf),fd);
827 if (strcmp(buf,"")!=0)
839 /* pb contains now the description */
841 /* log_level_pos, and user_handle are unknown at loading time */
842 if (dlt_daemon_context_add(daemon,apid,ctid,(int8_t)ll,(int8_t)ts,0,0,pb,verbose)==0)
854 int dlt_daemon_contexts_save(DltDaemon *daemon,const char *filename, int verbose)
859 char apid[DLT_ID_SIZE+1], ctid[DLT_ID_SIZE+1]; /* DLT_ID_SIZE+1, because the 0-termination is required here */
861 PRINT_FUNCTION_VERBOSE(verbose);
863 if ((daemon==0) || (filename==0) ||( filename[0]=='\0'))
868 memset(apid,0, sizeof(apid));
869 memset(ctid,0, sizeof(ctid));
871 if ((daemon->contexts) && (daemon->num_contexts>0))
873 fd=fopen(filename, "w");
876 for (i=0; i<daemon->num_contexts; i++)
878 dlt_set_id(apid,daemon->contexts[i].apid);
879 dlt_set_id(ctid,daemon->contexts[i].ctid);
881 if ((daemon->contexts[i].context_description) &&
882 (daemon->contexts[i].context_description[0]!='\0'))
884 fprintf(fd,"%s:%s:%d:%d:%s:\n",apid,ctid,
885 (int)(daemon->contexts[i].log_level),
886 (int)(daemon->contexts[i].trace_status),
887 daemon->contexts[i].context_description);
891 fprintf(fd,"%s:%s:%d:%d::\n",apid,ctid,
892 (int)(daemon->contexts[i].log_level),
893 (int)(daemon->contexts[i].trace_status));
903 int dlt_daemon_configuration_save(DltDaemon *daemon,const char *filename, int verbose)
907 PRINT_FUNCTION_VERBOSE(verbose);
909 if ((daemon==0) || (filename==0) ||( filename[0]=='\0'))
914 fd=fopen(filename, "w");
917 fprintf(fd,"# 0 = off, 1 = external, 2 = internal, 3 = both\n");
918 fprintf(fd,"LoggingMode = %d\n",daemon->mode);
926 int dlt_daemon_configuration_load(DltDaemon *daemon,const char *filename, int verbose)
934 PRINT_FUNCTION_VERBOSE(verbose);
936 pFile = fopen (filename,"r");
942 /* fetch line from configuration file */
943 if ( fgets (line , 1024 , pFile) != NULL )
945 pch = strtok (line," =\r\n");
951 if(strcmp(pch,"#")==0)
956 strncpy(token,pch,sizeof(token));
960 strncpy(value,pch,sizeof(value));
964 pch = strtok (NULL, " =\r\n");
967 if(token[0] && value[0])
969 /* parse arguments here */
970 if(strcmp(token,"LoggingMode")==0)
972 daemon->mode = atoi(value);
973 sprintf(str,"Runtime Option: %s=%d\n",token,daemon->mode);
974 dlt_log(LOG_INFO, str);
978 sprintf(str,"Unknown option: %s=%s\n",token,value);
979 dlt_log(LOG_ERR, str);
992 sprintf(str,"Cannot open configuration file: %s\n",filename);
993 dlt_log(LOG_WARNING, str);
999 int dlt_daemon_user_send_log_level(DltDaemon *daemon,DltDaemonContext *context,int verbose)
1001 DltUserHeader userheader;
1002 DltUserControlMsgLogLevel usercontext;
1005 PRINT_FUNCTION_VERBOSE(verbose);
1007 if ((daemon==0) || (context==0))
1012 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG_LEVEL)==-1)
1017 usercontext.log_level = ((context->log_level == DLT_LOG_DEFAULT)?daemon->default_log_level:context->log_level);
1018 usercontext.trace_status = ((context->trace_status == DLT_TRACE_STATUS_DEFAULT)?daemon->default_trace_status:context->trace_status);
1020 usercontext.log_level_pos = context->log_level_pos;
1023 ret = dlt_user_log_out2(context->user_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgLogLevel));
1025 if (ret!=DLT_RETURN_OK)
1029 /* Close connection */
1030 close(context->user_handle);
1031 context->user_handle=DLT_FD_INIT;
1035 return ((ret==DLT_RETURN_OK)?0:-1);
1038 int dlt_daemon_user_send_log_state(DltDaemon *daemon,DltDaemonApplication *app,int verbose)
1040 DltUserHeader userheader;
1041 DltUserControlMsgLogState logstate;
1044 PRINT_FUNCTION_VERBOSE(verbose);
1046 if ((daemon==0) || (app==0))
1051 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG_STATE)==-1)
1056 logstate.log_state = daemon->state;
1059 ret = dlt_user_log_out2(app->user_handle, &(userheader), sizeof(DltUserHeader), &(logstate), sizeof(DltUserControlMsgLogState));
1061 if (ret!=DLT_RETURN_OK)
1065 /* Close connection */
1066 close(app->user_handle);
1067 app->user_handle=DLT_FD_INIT;
1071 return ((ret==DLT_RETURN_OK)?0:-1);
1074 int dlt_daemon_control_process_control(int sock, DltDaemon *daemon, DltMessage *msg, int verbose)
1076 uint32_t id,id_tmp=0;
1078 PRINT_FUNCTION_VERBOSE(verbose);
1080 if ((daemon==0) || (msg==0))
1085 if (msg->datasize < (int32_t)sizeof(uint32_t))
1090 id_tmp = *((uint32_t*)(msg->databuffer));
1091 id=DLT_ENDIAN_GET_32(msg->standardheader->htyp ,id_tmp);
1093 if ((id > 0) && (id <= DLT_SERVICE_ID_MESSAGE_BUFFER_OVERFLOW))
1095 /* Control message handling */
1098 case DLT_SERVICE_ID_SET_LOG_LEVEL:
1100 dlt_daemon_control_set_log_level(sock, daemon, msg, verbose);
1103 case DLT_SERVICE_ID_SET_TRACE_STATUS:
1105 dlt_daemon_control_set_trace_status(sock, daemon, msg, verbose);
1108 case DLT_SERVICE_ID_GET_LOG_INFO:
1110 dlt_daemon_control_get_log_info(sock, daemon, msg, verbose);
1113 case DLT_SERVICE_ID_GET_DEFAULT_LOG_LEVEL:
1115 dlt_daemon_control_get_default_log_level(sock, daemon, verbose);
1118 case DLT_SERVICE_ID_STORE_CONFIG:
1120 if (dlt_daemon_applications_save(daemon, daemon->runtime_application_cfg, verbose)==0)
1122 if (dlt_daemon_contexts_save(daemon, daemon->runtime_context_cfg, verbose)==0)
1124 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_OK, verbose);
1128 /* Delete saved files */
1129 dlt_daemon_control_reset_to_factory_default(daemon, daemon->runtime_application_cfg, daemon->runtime_context_cfg, verbose);
1130 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
1135 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
1139 case DLT_SERVICE_ID_RESET_TO_FACTORY_DEFAULT:
1141 dlt_daemon_control_reset_to_factory_default(daemon, daemon->runtime_application_cfg, daemon->runtime_context_cfg, verbose);
1142 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_OK, verbose);
1145 case DLT_SERVICE_ID_SET_COM_INTERFACE_STATUS:
1147 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose);
1150 case DLT_SERVICE_ID_SET_COM_INTERFACE_MAX_BANDWIDTH:
1152 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose);
1155 case DLT_SERVICE_ID_SET_VERBOSE_MODE:
1157 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose);
1160 case DLT_SERVICE_ID_SET_MESSAGE_FILTERING:
1162 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose);
1165 case DLT_SERVICE_ID_SET_TIMING_PACKETS:
1167 dlt_daemon_control_set_timing_packets(sock, daemon, msg, verbose);
1170 case DLT_SERVICE_ID_GET_LOCAL_TIME:
1172 /* Send response with valid timestamp (TMSP) field */
1173 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_OK, verbose);
1176 case DLT_SERVICE_ID_USE_ECU_ID:
1178 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose);
1181 case DLT_SERVICE_ID_USE_SESSION_ID:
1183 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose);
1186 case DLT_SERVICE_ID_USE_TIMESTAMP:
1188 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose);
1191 case DLT_SERVICE_ID_USE_EXTENDED_HEADER:
1193 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose);
1196 case DLT_SERVICE_ID_SET_DEFAULT_LOG_LEVEL:
1198 dlt_daemon_control_set_default_log_level(sock, daemon, msg, verbose);
1201 case DLT_SERVICE_ID_SET_DEFAULT_TRACE_STATUS:
1203 dlt_daemon_control_set_default_trace_status(sock, daemon, msg, verbose);
1206 case DLT_SERVICE_ID_GET_SOFTWARE_VERSION:
1208 dlt_daemon_control_get_software_version(sock, daemon, verbose);
1211 case DLT_SERVICE_ID_MESSAGE_BUFFER_OVERFLOW:
1213 dlt_daemon_control_message_buffer_overflow(sock, daemon, verbose);
1218 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose);
1225 /* Injection handling */
1226 dlt_daemon_control_callsw_cinjection(sock, daemon, msg, verbose);
1232 void dlt_daemon_control_callsw_cinjection(int sock, DltDaemon *daemon, DltMessage *msg, int verbose)
1234 char apid[DLT_ID_SIZE],ctid[DLT_ID_SIZE];
1235 uint32_t id=0,id_tmp=0;
1237 DltDaemonContext *context;
1238 uint32_t data_length_inject=0,data_length_inject_tmp=0;
1242 DltUserHeader userheader;
1243 DltUserControlMsgInjection usercontext;
1244 uint8_t *userbuffer;
1246 PRINT_FUNCTION_VERBOSE(verbose);
1248 if ((daemon==0) || (msg==0))
1253 datalength = msg->datasize;
1254 ptr = msg->databuffer;
1261 DLT_MSG_READ_VALUE(id_tmp,ptr,datalength,uint32_t); /* Get service id */
1262 id=DLT_ENDIAN_GET_32(msg->standardheader->htyp, id_tmp);
1264 if ((id>=DLT_DAEMON_INJECTION_MIN) && (id<=DLT_DAEMON_INJECTION_MAX))
1266 /* This a a real SW-C injection call */
1267 data_length_inject=0;
1268 data_length_inject_tmp=0;
1270 DLT_MSG_READ_VALUE(data_length_inject_tmp,ptr,datalength,uint32_t); /* Get data length */
1271 data_length_inject=DLT_ENDIAN_GET_32(msg->standardheader->htyp, data_length_inject_tmp);
1273 /* Get context handle for apid, ctid (and seid) */
1274 /* Warning: seid is ignored in this implementation! */
1275 if (DLT_IS_HTYP_UEH(msg->standardheader->htyp))
1277 dlt_set_id(apid, msg->extendedheader->apid);
1278 dlt_set_id(ctid, msg->extendedheader->ctid);
1282 /* No extended header, and therefore no apid and ctid available */
1283 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
1287 /* At this point, apid and ctid is available */
1288 context=dlt_daemon_context_find(daemon, apid, ctid, verbose);
1292 // dlt_log(LOG_INFO,"No context found!\n");
1293 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
1297 /* Send user message to handle, specified in context */
1298 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_INJECTION)==-1)
1300 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
1304 usercontext.log_level_pos = context->log_level_pos;
1306 userbuffer = malloc(data_length_inject);
1310 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
1314 usercontext.data_length_inject = data_length_inject;
1315 usercontext.service_id = id;
1317 memcpy(userbuffer,ptr,data_length_inject); /* Copy received injection to send buffer */
1320 DltReturnValue ret =
1321 dlt_user_log_out3(context->user_handle, &(userheader), sizeof(DltUserHeader),
1322 &(usercontext), sizeof(DltUserControlMsgInjection),
1323 userbuffer, data_length_inject);
1324 if (ret != DLT_RETURN_OK)
1326 if (ret == DLT_RETURN_PIPE_ERROR)
1328 /* Close connection */
1329 close(context->user_handle);
1330 context->user_handle=DLT_FD_INIT;
1332 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
1336 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_OK, verbose);
1346 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose);
1350 void dlt_daemon_control_set_log_level(int sock, DltDaemon *daemon, DltMessage *msg, int verbose)
1352 PRINT_FUNCTION_VERBOSE(verbose);
1354 char apid[DLT_ID_SIZE],ctid[DLT_ID_SIZE];
1355 DltServiceSetLogLevel *req;
1356 DltDaemonContext *context;
1357 int32_t id=DLT_SERVICE_ID_SET_LOG_LEVEL;
1359 int8_t old_log_level;
1361 if ((daemon==0) || (msg==0))
1366 req = (DltServiceSetLogLevel*) (msg->databuffer);
1368 dlt_set_id(apid, req->apid);
1369 dlt_set_id(ctid, req->ctid);
1371 context=dlt_daemon_context_find(daemon, apid, ctid, verbose);
1376 old_log_level = context->log_level;
1377 context->log_level = req->log_level; /* No endianess conversion necessary*/
1379 if ((context->user_handle >= DLT_FD_MINIMUM) &&
1380 (dlt_daemon_user_send_log_level(daemon, context, verbose)==0))
1382 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_OK, verbose);
1386 //dlt_log(LOG_ERR, "Log level could not be sent!\n");
1387 context->log_level = old_log_level;
1388 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
1393 //dlt_log(LOG_ERR, "Context not found!\n");
1394 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
1398 void dlt_daemon_control_set_trace_status(int sock, DltDaemon *daemon, DltMessage *msg, int verbose)
1400 PRINT_FUNCTION_VERBOSE(verbose);
1402 char apid[DLT_ID_SIZE],ctid[DLT_ID_SIZE];
1403 DltServiceSetLogLevel *req; /* request uses same struct as set log level */
1404 DltDaemonContext *context;
1405 int32_t id=DLT_SERVICE_ID_SET_TRACE_STATUS;
1407 int8_t old_trace_status;
1409 if ((daemon==0) || (msg==0))
1414 req = (DltServiceSetLogLevel*) (msg->databuffer);
1416 dlt_set_id(apid, req->apid);
1417 dlt_set_id(ctid, req->ctid);
1419 context=dlt_daemon_context_find(daemon, apid, ctid, verbose);
1424 old_trace_status = context->trace_status;
1425 context->trace_status = req->log_level; /* No endianess conversion necessary */
1427 if ((context->user_handle >= DLT_FD_MINIMUM ) &&
1428 (dlt_daemon_user_send_log_level(daemon, context, verbose)==0))
1430 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_OK, verbose);
1434 //dlt_log(LOG_ERR, "Trace Status could not be sent!\n");
1435 context->trace_status = old_trace_status;
1436 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
1441 //dlt_log(LOG_ERR, "Context not found!\n");
1442 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
1446 void dlt_daemon_control_set_default_log_level(int sock, DltDaemon *daemon, DltMessage *msg, int verbose)
1448 PRINT_FUNCTION_VERBOSE(verbose);
1450 DltServiceSetDefaultLogLevel *req;
1451 int32_t id=DLT_SERVICE_ID_SET_DEFAULT_LOG_LEVEL;
1453 if ((daemon==0) || (msg==0))
1458 req = (DltServiceSetDefaultLogLevel*) (msg->databuffer);
1460 /* No endianess conversion necessary */
1461 if (/*(req->log_level>=0) &&*/
1462 (req->log_level<=DLT_LOG_VERBOSE))
1464 daemon->default_log_level = req->log_level; /* No endianess conversion necessary */
1466 /* Send Update to all contexts using the default log level */
1467 dlt_daemon_user_send_default_update(daemon, verbose);
1469 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_OK, verbose);
1473 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
1477 void dlt_daemon_control_set_default_trace_status(int sock, DltDaemon *daemon, DltMessage *msg, int verbose)
1479 PRINT_FUNCTION_VERBOSE(verbose);
1481 /* Payload of request message */
1482 DltServiceSetDefaultLogLevel *req;
1483 int32_t id=DLT_SERVICE_ID_SET_DEFAULT_TRACE_STATUS;
1485 if ((daemon==0) || (msg==0))
1490 req = (DltServiceSetDefaultLogLevel*) (msg->databuffer);
1492 /* No endianess conversion necessary */
1493 if ((req->log_level==DLT_TRACE_STATUS_OFF) ||
1494 (req->log_level==DLT_TRACE_STATUS_ON))
1496 daemon->default_trace_status = req->log_level; /* No endianess conversion necessary*/
1498 /* Send Update to all contexts using the default trace status */
1499 dlt_daemon_user_send_default_update(daemon, verbose);
1501 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_OK, verbose);
1505 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
1509 void dlt_daemon_control_set_timing_packets(int sock, DltDaemon *daemon, DltMessage *msg, int verbose)
1511 PRINT_FUNCTION_VERBOSE(verbose);
1513 DltServiceSetVerboseMode *req; /* request uses same struct as set verbose mode */
1514 int32_t id=DLT_SERVICE_ID_SET_TIMING_PACKETS;
1516 if ((daemon==0) || (msg==0))
1521 req = (DltServiceSetVerboseMode*) (msg->databuffer);
1522 if ((req->new_status==0) || (req->new_status==1))
1524 daemon->timingpackets = req->new_status;
1526 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_OK, verbose);
1530 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
1534 void dlt_daemon_control_get_software_version(int sock, DltDaemon *daemon, int verbose)
1536 char version[DLT_DAEMON_COMMON_TEXTBUFSIZE];
1539 DltServiceGetSoftwareVersionResponse *resp;
1541 PRINT_FUNCTION_VERBOSE(verbose);
1548 /* initialise new message */
1549 if (dlt_message_init(&msg,0)==-1)
1551 dlt_daemon_control_service_response(sock, daemon, DLT_SERVICE_ID_GET_SOFTWARE_VERSION, DLT_SERVICE_RESPONSE_ERROR, verbose);
1555 /* prepare payload of data */
1556 dlt_get_version(version);
1557 len = strlen(version);
1559 msg.datasize = sizeof(DltServiceGetSoftwareVersionResponse) + len;
1560 if (msg.databuffer && (msg.databuffersize < msg.datasize))
1562 free(msg.databuffer);
1565 if (msg.databuffer == 0){
1566 msg.databuffer = (uint8_t *) malloc(msg.datasize);
1567 msg.databuffersize = msg.datasize;
1569 if (msg.databuffer==0)
1571 dlt_daemon_control_service_response(sock, daemon, DLT_SERVICE_ID_GET_SOFTWARE_VERSION, DLT_SERVICE_RESPONSE_ERROR, verbose);
1575 resp = (DltServiceGetSoftwareVersionResponse*) msg.databuffer;
1576 resp->service_id = DLT_SERVICE_ID_GET_SOFTWARE_VERSION;
1577 resp->status = DLT_SERVICE_RESPONSE_OK;
1579 memcpy(msg.databuffer+sizeof(DltServiceGetSoftwareVersionResponse),version,len);
1582 dlt_daemon_control_send_control_message(sock, daemon, &msg,"","", verbose);
1585 dlt_message_free(&msg,0);
1588 void dlt_daemon_control_get_default_log_level(int sock, DltDaemon *daemon, int verbose)
1591 DltServiceGetDefaultLogLevelResponse *resp;
1593 PRINT_FUNCTION_VERBOSE(verbose);
1600 /* initialise new message */
1601 if (dlt_message_init(&msg,0)==-1)
1603 dlt_daemon_control_service_response(sock, daemon, DLT_SERVICE_ID_GET_DEFAULT_LOG_LEVEL, DLT_SERVICE_RESPONSE_ERROR, verbose);
1607 msg.datasize = sizeof(DltServiceGetDefaultLogLevelResponse);
1608 if (msg.databuffer && (msg.databuffersize<msg.datasize))
1610 free(msg.databuffer);
1613 if (msg.databuffer == 0){
1614 msg.databuffer = (uint8_t *) malloc(msg.datasize);
1615 msg.databuffersize = msg.datasize;
1617 if (msg.databuffer==0)
1619 dlt_daemon_control_service_response(sock, daemon, DLT_SERVICE_ID_GET_DEFAULT_LOG_LEVEL, DLT_SERVICE_RESPONSE_ERROR, verbose);
1623 resp = (DltServiceGetDefaultLogLevelResponse*) msg.databuffer;
1624 resp->service_id = DLT_SERVICE_ID_GET_DEFAULT_LOG_LEVEL;
1625 resp->status = DLT_SERVICE_RESPONSE_OK;
1626 resp->log_level = daemon->default_log_level;
1629 dlt_daemon_control_send_control_message(sock,daemon,&msg,"","", verbose);
1632 dlt_message_free(&msg,0);
1635 void dlt_daemon_control_get_log_info(int sock, DltDaemon *daemon, DltMessage *msg, int verbose)
1637 DltServiceGetLogInfoRequest *req;
1639 DltDaemonContext *context=0;
1640 DltDaemonApplication *application=0;
1642 int num_applications=0, num_contexts=0;
1643 uint16_t count_app_ids=0, count_con_ids=0;
1645 #if (DLT_DEBUG_GETLOGINFO==1)
1649 int32_t i,j,offset=0;
1659 PRINT_FUNCTION_VERBOSE(verbose);
1661 if ((daemon==0) || (msg==0))
1666 /* prepare pointer to message request */
1667 req = (DltServiceGetLogInfoRequest*) (msg->databuffer);
1669 /* initialise new message */
1670 if (dlt_message_init(&resp,0)==-1)
1672 dlt_daemon_control_service_response(sock, daemon, DLT_SERVICE_ID_GET_LOG_INFO, DLT_SERVICE_RESPONSE_ERROR, verbose);
1677 if ((req->options < 3 ) || (req->options>7))
1679 dlt_daemon_control_service_response(sock, daemon, DLT_SERVICE_ID_GET_LOG_INFO, DLT_SERVICE_RESPONSE_ERROR, verbose);
1683 if (req->apid[0]!='\0')
1685 application = dlt_daemon_application_find(daemon, req->apid, verbose);
1688 num_applications = 1;
1689 if (req->ctid[0]!='\0')
1691 context = dlt_daemon_context_find(daemon, req->apid, req->ctid, verbose);
1693 num_contexts = ((context)?1:0);
1697 num_contexts = application->num_contexts;
1702 num_applications = 0;
1708 /* Request all applications and contexts */
1709 num_applications = daemon->num_applications;
1710 num_contexts = daemon->num_contexts;
1713 /* prepare payload of data */
1715 /* Calculate maximum size for a response */
1716 resp.datasize = sizeof(uint32_t) /* SID */ + sizeof(int8_t) /* status*/ + sizeof(ID4) /* DLT_DAEMON_REMO_STRING */;
1718 sizecont = sizeof(uint32_t) /* context_id */;
1720 /* Add additional size for response of Mode 4, 6, 7 */
1721 if ((req->options==4) || (req->options==6) || (req->options==7))
1723 sizecont += sizeof(int8_t); /* log level */
1726 /* Add additional size for response of Mode 5, 6, 7 */
1727 if ((req->options==5) || (req->options==6) || (req->options==7))
1729 sizecont+= sizeof(int8_t); /* trace status */
1732 resp.datasize+= (num_applications * (sizeof(uint32_t) /* app_id */ + sizeof(uint16_t) /* count_con_ids */)) +
1733 (num_contexts * sizecont);
1735 resp.datasize+= sizeof(uint16_t) /* count_app_ids */;
1737 /* Add additional size for response of Mode 7 */
1738 if (req->options==7)
1740 if (req->apid[0]!='\0')
1742 if (req->ctid[0]!='\0')
1744 /* One application, one context */
1745 // context = dlt_daemon_context_find(daemon, req->apid, req->ctid, verbose);
1748 resp.datasize+=sizeof(uint16_t) /* len_context_description */;
1749 if (context->context_description!=0)
1751 resp.datasize+=strlen(context->context_description); /* context_description */
1757 /* One application, all contexts */
1758 if ((daemon->applications) && (application))
1760 /* Calculate start offset within contexts[] */
1762 for (i=0; i<(application-(daemon->applications)); i++)
1764 offset_base+=daemon->applications[i].num_contexts;
1767 /* Iterate over all contexts belonging to this application */
1768 for (j=0;j<application->num_contexts;j++)
1771 context = &(daemon->contexts[offset_base+j]);
1774 resp.datasize+=sizeof(uint16_t) /* len_context_description */;
1775 if (context->context_description!=0)
1777 resp.datasize+=strlen(context->context_description); /* context_description */
1784 /* Space for application description */
1787 resp.datasize+=sizeof(uint16_t) /* len_app_description */;
1788 if (application->application_description!=0)
1790 resp.datasize+=strlen(application->application_description); /* app_description */
1796 /* All applications, all contexts */
1797 for (i=0;i<daemon->num_contexts;i++)
1799 resp.datasize+=sizeof(uint16_t) /* len_context_description */;
1800 if (daemon->contexts[i].context_description!=0)
1802 resp.datasize+=strlen(daemon->contexts[i].context_description); /* context_description */
1806 for (i=0;i<daemon->num_applications;i++)
1808 resp.datasize+=sizeof(uint16_t) /* len_app_description */;
1809 if (daemon->applications[i].application_description!=0)
1811 resp.datasize+=strlen(daemon->applications[i].application_description); /* app_description */
1819 sprintf(str,"Allocate %d bytes for response msg databuffer\n", resp.datasize);
1820 dlt_log(LOG_INFO, str);
1823 /* Allocate buffer for response message */
1824 resp.databuffer = (uint8_t *) malloc(resp.datasize);
1825 resp.databuffersize = resp.datasize;
1827 if (resp.databuffer==0)
1829 dlt_daemon_control_service_response(sock, daemon, DLT_SERVICE_ID_GET_LOG_INFO, DLT_SERVICE_RESPONSE_ERROR, verbose);
1832 memset(resp.databuffer,0,resp.datasize);
1833 /* Preparation finished */
1835 /* Prepare response */
1836 sid = DLT_SERVICE_ID_GET_LOG_INFO;
1837 memcpy(resp.databuffer,&sid,sizeof(uint32_t));
1838 offset+=sizeof(uint32_t);
1840 value = (((num_applications!=0)&&(num_contexts!=0))?req->options:8); /* 8 = no matching context found */
1842 memcpy(resp.databuffer+offset,&value,sizeof(int8_t));
1843 offset+=sizeof(int8_t);
1845 count_app_ids = num_applications;
1847 if (count_app_ids!=0)
1849 memcpy(resp.databuffer+offset,&count_app_ids,sizeof(uint16_t));
1850 offset+=sizeof(uint16_t);
1852 #if (DLT_DEBUG_GETLOGINFO==1)
1853 sprintf(str,"#apid: %d \n", count_app_ids);
1854 dlt_log(LOG_DEBUG, str);
1857 for (i=0;i<count_app_ids;i++)
1859 if (req->apid[0]!='\0')
1865 if (daemon->applications)
1867 apid = daemon->applications[i].apid;
1871 /* This should never occur! */
1876 application = dlt_daemon_application_find(daemon, apid, verbose);
1880 /* Calculate start offset within contexts[] */
1882 for (j=0; j<(application-(daemon->applications)); j++)
1884 offset_base+=daemon->applications[j].num_contexts;
1887 dlt_set_id((char*)(resp.databuffer+offset),apid);
1888 offset+=sizeof(ID4);
1890 #if (DLT_DEBUG_GETLOGINFO==1)
1891 dlt_print_id(buf, apid);
1892 sprintf(str,"apid: %s\n",buf);
1893 dlt_log(LOG_DEBUG, str);
1896 if (req->apid[0]!='\0')
1898 count_con_ids = num_contexts;
1902 count_con_ids = application->num_contexts;
1905 memcpy(resp.databuffer+offset,&count_con_ids,sizeof(uint16_t));
1906 offset+=sizeof(uint16_t);
1908 #if (DLT_DEBUG_GETLOGINFO==1)
1909 sprintf(str,"#ctid: %d \n", count_con_ids);
1910 dlt_log(LOG_DEBUG, str);
1913 for (j=0;j<count_con_ids;j++)
1915 #if (DLT_DEBUG_GETLOGINFO==1)
1916 sprintf(str,"j: %d \n",j);
1917 dlt_log(LOG_DEBUG, str);
1919 if (!((count_con_ids==1) && (req->apid[0]!='\0') && (req->ctid[0]!='\0')))
1921 context = &(daemon->contexts[offset_base+j]);
1923 /* else: context was already searched and found
1924 (one application (found) with one context (found))*/
1927 ((req->ctid[0]=='\0') ||
1928 ((req->ctid[0]!='\0') && (memcmp(context->ctid,req->ctid,DLT_ID_SIZE)==0)))
1931 dlt_set_id((char*)(resp.databuffer+offset),context->ctid);
1932 offset+=sizeof(ID4);
1934 #if (DLT_DEBUG_GETLOGINFO==1)
1935 dlt_print_id(buf, context->ctid);
1936 sprintf(str,"ctid: %s \n",buf);
1937 dlt_log(LOG_DEBUG, str);
1941 if ((req->options==4) || (req->options==6) || (req->options==7))
1943 ll=context->log_level;
1944 memcpy(resp.databuffer+offset,&ll,sizeof(int8_t));
1945 offset+=sizeof(int8_t);
1949 if ((req->options==5) || (req->options==6) || (req->options==7))
1951 ts=context->trace_status;
1952 memcpy(resp.databuffer+offset,&ts,sizeof(int8_t));
1953 offset+=sizeof(int8_t);
1957 if (req->options==7)
1959 if (context->context_description)
1961 len = strlen(context->context_description);
1962 memcpy(resp.databuffer+offset,&len,sizeof(uint16_t));
1963 offset+=sizeof(uint16_t);
1964 memcpy(resp.databuffer+offset,context->context_description,strlen(context->context_description));
1965 offset+=strlen(context->context_description);
1970 memcpy(resp.databuffer+offset,&len,sizeof(uint16_t));
1971 offset+=sizeof(uint16_t);
1975 #if (DLT_DEBUG_GETLOGINFO==1)
1976 sprintf(str,"ll=%d ts=%d \n",(int32_t)ll,(int32_t)ts);
1977 dlt_log(LOG_DEBUG, str);
1981 #if (DLT_DEBUG_GETLOGINFO==1)
1982 dlt_log(LOG_DEBUG,"\n");
1987 if (req->options==7)
1989 if (application->application_description)
1991 len = strlen(application->application_description);
1992 memcpy(resp.databuffer+offset,&len,sizeof(uint16_t));
1993 offset+=sizeof(uint16_t);
1994 memcpy(resp.databuffer+offset,application->application_description,strlen(application->application_description));
1995 offset+=strlen(application->application_description);
2000 memcpy(resp.databuffer+offset,&len,sizeof(uint16_t));
2001 offset+=sizeof(uint16_t);
2004 } /* if (application) */
2005 } /* for (i=0;i<count_app_ids;i++) */
2006 } /* if (count_app_ids!=0) */
2008 dlt_set_id((char*)(resp.databuffer+offset),DLT_DAEMON_REMO_STRING);
2011 dlt_daemon_control_send_control_message(sock,daemon,&resp,"","", verbose);
2014 dlt_message_free(&resp,0);
2017 void dlt_daemon_control_message_buffer_overflow(int sock, DltDaemon *daemon, int verbose)
2020 DltServiceMessageBufferOverflowResponse *resp;
2022 PRINT_FUNCTION_VERBOSE(verbose);
2029 /* initialise new message */
2030 if (dlt_message_init(&msg,0)==-1)
2032 dlt_daemon_control_service_response(sock, daemon, DLT_SERVICE_ID_MESSAGE_BUFFER_OVERFLOW, DLT_SERVICE_RESPONSE_ERROR, verbose);
2036 /* prepare payload of data */
2037 msg.datasize = sizeof(DltServiceMessageBufferOverflowResponse);
2038 if (msg.databuffer && (msg.databuffersize < msg.datasize))
2040 free(msg.databuffer);
2043 if (msg.databuffer == 0){
2044 msg.databuffer = (uint8_t *) malloc(msg.datasize);
2045 msg.databuffersize = msg.datasize;
2047 if (msg.databuffer==0)
2049 if (sock!=DLT_DAEMON_STORE_TO_BUFFER)
2051 dlt_daemon_control_service_response(sock, daemon, DLT_SERVICE_ID_MESSAGE_BUFFER_OVERFLOW, DLT_SERVICE_RESPONSE_ERROR, verbose);
2056 resp = (DltServiceMessageBufferOverflowResponse*) msg.databuffer;
2057 resp->service_id = DLT_SERVICE_ID_MESSAGE_BUFFER_OVERFLOW;
2058 resp->status = DLT_SERVICE_RESPONSE_OK;
2059 resp->overflow = daemon->message_buffer_overflow;
2062 dlt_daemon_control_send_control_message(sock,daemon,&msg,"","", verbose);
2065 dlt_message_free(&msg,0);
2068 void dlt_daemon_control_service_response( int sock, DltDaemon *daemon, uint32_t service_id, int8_t status , int verbose)
2071 DltServiceResponse *resp;
2073 PRINT_FUNCTION_VERBOSE(verbose);
2080 /* initialise new message */
2081 if (dlt_message_init(&msg,0)==-1)
2086 /* prepare payload of data */
2087 msg.datasize = sizeof(DltServiceResponse);
2088 if (msg.databuffer && (msg.databuffersize < msg.datasize))
2090 free(msg.databuffer);
2093 if (msg.databuffer == 0){
2094 msg.databuffer = (uint8_t *) malloc(msg.datasize);
2095 msg.databuffersize = msg.datasize;
2097 if (msg.databuffer==0)
2102 resp = (DltServiceResponse*) msg.databuffer;
2103 resp->service_id = service_id;
2104 resp->status = status;
2107 dlt_daemon_control_send_control_message(sock,daemon,&msg,"","", verbose);
2110 dlt_message_free(&msg,0);
2113 void dlt_daemon_control_send_control_message( int sock, DltDaemon *daemon, DltMessage *msg, char* appid, char* ctid, int verbose)
2118 PRINT_FUNCTION_VERBOSE(verbose);
2120 if ((daemon==0) || (msg==0) || (appid==0) || (ctid==0))
2125 /* prepare storage header */
2126 msg->storageheader = (DltStorageHeader*)msg->headerbuffer;
2128 if (dlt_set_storageheader(msg->storageheader,daemon->ecuid)==-1)
2133 /* prepare standard header */
2134 msg->standardheader = (DltStandardHeader*)(msg->headerbuffer + sizeof(DltStorageHeader));
2135 msg->standardheader->htyp = DLT_HTYP_WEID | DLT_HTYP_WTMS | DLT_HTYP_UEH | DLT_HTYP_PROTOCOL_VERSION1 ;
2137 #if (BYTE_ORDER==BIG_ENDIAN)
2138 msg->standardheader->htyp = ( msg->standardheader->htyp | DLT_HTYP_MSBF);
2141 msg->standardheader->mcnt = 0;
2143 /* Set header extra parameters */
2144 dlt_set_id(msg->headerextra.ecu,daemon->ecuid);
2146 //msg->headerextra.seid = 0;
2148 msg->headerextra.tmsp = dlt_uptime();
2150 dlt_message_set_extraparameters(msg, verbose);
2152 /* prepare extended header */
2153 msg->extendedheader = (DltExtendedHeader*)(msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg->standardheader->htyp));
2154 msg->extendedheader->msin = DLT_MSIN_CONTROL_RESPONSE;
2156 msg->extendedheader->noar = 1; /* number of arguments */
2157 if (strcmp(appid,"")==0)
2159 dlt_set_id(msg->extendedheader->apid,DLT_DAEMON_CTRL_APID); /* application id */
2163 dlt_set_id(msg->extendedheader->apid, appid);
2165 if (strcmp(ctid,"")==0)
2167 dlt_set_id(msg->extendedheader->ctid,DLT_DAEMON_CTRL_CTID); /* context id */
2171 dlt_set_id(msg->extendedheader->ctid, ctid);
2174 /* prepare length information */
2175 msg->headersize = sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + sizeof(DltExtendedHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg->standardheader->htyp);
2177 len=msg->headersize - sizeof(DltStorageHeader) + msg->datasize;
2180 dlt_log(LOG_CRIT,"Huge control message discarded!\n");
2184 msg->standardheader->len = DLT_HTOBE_16(((uint16_t)len));
2186 if (sock!=DLT_DAEMON_STORE_TO_BUFFER)
2191 DLT_DAEMON_SEM_LOCK();
2193 /* Optional: Send serial header, if requested */
2194 if (daemon->sendserialheader)
2196 ret=write(sock,dltSerialHeader,sizeof(dltSerialHeader));
2200 ret=write(sock, msg->headerbuffer+sizeof(DltStorageHeader),msg->headersize-sizeof(DltStorageHeader));
2201 ret=write(sock, msg->databuffer,msg->datasize);
2203 DLT_DAEMON_SEM_FREE();
2207 DLT_DAEMON_SEM_LOCK();
2209 /* Optional: Send serial header, if requested */
2210 if (daemon->sendserialheader)
2212 send(sock, dltSerialHeader,sizeof(dltSerialHeader),0);
2216 send(sock, msg->headerbuffer+sizeof(DltStorageHeader),msg->headersize-sizeof(DltStorageHeader),0);
2217 send(sock, msg->databuffer,msg->datasize,0);
2219 DLT_DAEMON_SEM_FREE();
2224 /* Store message in history buffer */
2225 if (dlt_buffer_push3(&(daemon->client_ringbuffer),
2226 msg->headerbuffer+sizeof(DltStorageHeader),msg->headersize-sizeof(DltStorageHeader),
2227 msg->databuffer,msg->datasize,
2231 dlt_log(LOG_ERR,"Storage of message in history buffer failed! Message discarded.\n");
2237 void dlt_daemon_control_reset_to_factory_default(DltDaemon *daemon,const char *filename, const char *filename1, int verbose)
2241 PRINT_FUNCTION_VERBOSE(verbose);
2243 if ((daemon==0) || (filename==0) || (filename1==0) || (filename[0]=='\0') || (filename1[0]=='\0'))
2248 /* Check for runtime cfg file and delete it, if available */
2249 fd=fopen(filename, "r");
2253 /* Close and delete file */
2258 fd=fopen(filename1, "r");
2262 /* Close and delete file */
2267 daemon->default_log_level = DLT_DAEMON_INITIAL_LOG_LEVEL ;
2268 daemon->default_trace_status = DLT_DAEMON_INITIAL_TRACE_STATUS ;
2270 daemon->message_buffer_overflow = DLT_MESSAGE_BUFFER_NO_OVERFLOW;
2272 /* Reset all other things (log level, trace status, etc.
2273 to default values */
2275 /* Inform user libraries about changed default log level/trace status */
2276 dlt_daemon_user_send_default_update(daemon, verbose);
2279 void dlt_daemon_user_send_default_update(DltDaemon *daemon, int verbose)
2282 DltDaemonContext *context;
2284 PRINT_FUNCTION_VERBOSE(verbose);
2291 for (count=0;count<daemon->num_contexts; count ++)
2293 context = &(daemon->contexts[count]);
2297 if ((context->log_level == DLT_LOG_DEFAULT) ||
2298 (context->trace_status == DLT_TRACE_STATUS_DEFAULT))
2300 if (context->user_handle >= DLT_FD_MINIMUM)
2302 if (dlt_daemon_user_send_log_level(daemon, context, verbose)==-1)
2312 void dlt_daemon_user_send_all_log_state(DltDaemon *daemon, int verbose)
2315 DltDaemonApplication *app;
2317 PRINT_FUNCTION_VERBOSE(verbose);
2324 for (count=0;count<daemon->num_applications; count ++)
2326 app = &(daemon->applications[count]);
2330 if (app->user_handle >= DLT_FD_MINIMUM)
2332 if (dlt_daemon_user_send_log_state(daemon, app, verbose)==-1)
2341 void dlt_daemon_control_message_time(int sock, DltDaemon *daemon, int verbose)
2347 PRINT_FUNCTION_VERBOSE(verbose);
2354 if (sock==DLT_DAEMON_STORE_TO_BUFFER)
2359 /* initialise new message */
2360 if (dlt_message_init(&msg,0)==-1)
2367 /* prepare storage header */
2368 msg.storageheader = (DltStorageHeader*)msg.headerbuffer;
2369 dlt_set_storageheader(msg.storageheader,daemon->ecuid);
2371 /* prepare standard header */
2372 msg.standardheader = (DltStandardHeader*)(msg.headerbuffer + sizeof(DltStorageHeader));
2373 msg.standardheader->htyp = DLT_HTYP_WEID | DLT_HTYP_WTMS | DLT_HTYP_UEH | DLT_HTYP_PROTOCOL_VERSION1 ;
2375 #if (BYTE_ORDER==BIG_ENDIAN)
2376 msg.standardheader->htyp = ( msg.standardheader->htyp | DLT_HTYP_MSBF);
2379 msg.standardheader->mcnt = 0;
2381 /* Set header extra parameters */
2382 dlt_set_id(msg.headerextra.ecu,daemon->ecuid);
2383 msg.headerextra.tmsp = dlt_uptime();
2385 dlt_message_set_extraparameters(&msg, verbose);
2387 /* prepare extended header */
2388 msg.extendedheader = (DltExtendedHeader*)(msg.headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp));
2389 msg.extendedheader->msin = DLT_MSIN_CONTROL_TIME;
2391 msg.extendedheader->noar = 0; /* number of arguments */
2392 dlt_set_id(msg.extendedheader->apid,""); /* application id */
2393 dlt_set_id(msg.extendedheader->ctid,""); /* context id */
2395 /* prepare length information */
2396 msg.headersize = sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + sizeof(DltExtendedHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp);
2398 len=msg.headersize - sizeof(DltStorageHeader) + msg.datasize;
2401 dlt_log(LOG_CRIT,"Huge control message discarded!\n");
2404 dlt_message_free(&msg,0);
2409 msg.standardheader->len = DLT_HTOBE_16(((uint16_t)len));
2414 DLT_DAEMON_SEM_LOCK();
2416 /* Optional: Send serial header, if requested */
2417 if (daemon->sendserialheader)
2419 ret=write(sock,dltSerialHeader,sizeof(dltSerialHeader));
2423 ret=write(sock, msg.headerbuffer+sizeof(DltStorageHeader),msg.headersize-sizeof(DltStorageHeader));
2424 if(msg.datasize > 0)
2425 ret=write(sock, msg.databuffer,msg.datasize);
2427 DLT_DAEMON_SEM_FREE();
2431 DLT_DAEMON_SEM_LOCK();
2433 /* Optional: Send serial header, if requested */
2434 if (daemon->sendserialheader)
2436 send(sock, dltSerialHeader,sizeof(dltSerialHeader),0);
2440 send(sock, msg.headerbuffer+sizeof(DltStorageHeader),msg.headersize-sizeof(DltStorageHeader),0);
2441 if(msg.datasize > 0)
2442 send(sock, msg.databuffer,msg.datasize,0);
2444 DLT_DAEMON_SEM_FREE();
2448 dlt_message_free(&msg,0);