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 int append_length = 0;
129 daemon->num_contexts = 0;
130 daemon->contexts = 0;
132 daemon->num_applications = 0;
133 daemon->applications = 0;
135 daemon->default_log_level = DLT_DAEMON_INITIAL_LOG_LEVEL ;
136 daemon->default_trace_status = DLT_DAEMON_INITIAL_TRACE_STATUS ;
138 daemon->message_buffer_overflow = DLT_MESSAGE_BUFFER_NO_OVERFLOW;
140 daemon->runtime_context_cfg_loaded = 0;
142 daemon->mode = DLT_USER_MODE_EXTERNAL;
144 /* prepare filenames for configuration */
146 append_length = PATH_MAX - sizeof(DLT_RUNTIME_APPLICATION_CFG);
147 if(runtime_directory[0])
148 strncpy(daemon->runtime_application_cfg,runtime_directory,append_length);
150 strcpy(daemon->runtime_application_cfg,DLT_RUNTIME_DEFAULT_DIRECTORY);
151 strcat(daemon->runtime_application_cfg,DLT_RUNTIME_APPLICATION_CFG);
153 append_length = PATH_MAX - sizeof(DLT_RUNTIME_CONTEXT_CFG);
154 if(runtime_directory[0])
155 strncpy(daemon->runtime_context_cfg,runtime_directory,append_length);
157 strcpy(daemon->runtime_context_cfg,DLT_RUNTIME_DEFAULT_DIRECTORY);
158 strcat(daemon->runtime_context_cfg,DLT_RUNTIME_CONTEXT_CFG);
160 append_length = PATH_MAX - sizeof(DLT_RUNTIME_CONFIGURATION);
161 if(runtime_directory[0])
162 strncpy(daemon->runtime_configuration,runtime_directory,append_length);
164 strcpy(daemon->runtime_configuration,DLT_RUNTIME_DEFAULT_DIRECTORY);
165 strcat(daemon->runtime_configuration,DLT_RUNTIME_CONFIGURATION);
167 /* Check for runtime cfg, if it is loadable, load it! */
168 if ((dlt_daemon_applications_load(daemon,daemon->runtime_application_cfg, verbose)==0) &&
169 (dlt_daemon_contexts_load(daemon,daemon->runtime_context_cfg, verbose)==0))
171 daemon->runtime_context_cfg_loaded = 1;
174 /* load configuration if available */
175 dlt_daemon_configuration_load(daemon,daemon->runtime_configuration, verbose);
177 daemon->sendserialheader = 0;
178 daemon->timingpackets = 0;
180 dlt_set_id(daemon->ecuid,"");
182 /* initialize ring buffer for client connection */
183 if (dlt_buffer_init_dynamic(&(daemon->client_ringbuffer), DLT_DAEMON_RINGBUFFER_MIN_SIZE,DLT_DAEMON_RINGBUFFER_MAX_SIZE,DLT_DAEMON_RINGBUFFER_STEP_SIZE)==-1)
191 int dlt_daemon_free(DltDaemon *daemon,int verbose)
193 PRINT_FUNCTION_VERBOSE(verbose);
201 if (dlt_daemon_contexts_clear(daemon, verbose)==-1)
206 /* Free applications */
207 if (dlt_daemon_applications_clear(daemon, verbose)==-1)
212 /* free ringbuffer */
213 dlt_buffer_free_dynamic(&(daemon->client_ringbuffer));
218 int dlt_daemon_applications_invalidate_fd(DltDaemon *daemon,int fd,int verbose)
222 PRINT_FUNCTION_VERBOSE(verbose);
229 for (i=0; i<daemon->num_applications; i++)
231 if (daemon->applications[i].user_handle==fd)
233 daemon->applications[i].user_handle = DLT_FD_INIT;
240 int dlt_daemon_applications_clear(DltDaemon *daemon,int verbose)
244 PRINT_FUNCTION_VERBOSE(verbose);
251 for (i=0; i<daemon->num_applications; i++)
253 if (daemon->applications[i].application_description!=0)
255 free(daemon->applications[i].application_description);
256 daemon->applications[i].application_description = 0;
260 if (daemon->applications)
262 free(daemon->applications);
265 daemon->applications = 0;
266 daemon->num_applications = 0;
271 DltDaemonApplication* dlt_daemon_application_add(DltDaemon *daemon,char *apid,pid_t pid,char *description, int verbose)
273 DltDaemonApplication *application;
274 DltDaemonApplication *old;
277 char filename[DLT_DAEMON_COMMON_TEXTBUFSIZE];
279 if ((daemon==0) || (apid==0) || (apid[0]=='\0'))
281 return (DltDaemonApplication*) 0;
284 if (daemon->applications == 0)
286 daemon->applications = (DltDaemonApplication*) malloc(sizeof(DltDaemonApplication)*DLT_DAEMON_APPL_ALLOC_SIZE);
287 if (daemon->applications==0)
289 return (DltDaemonApplication*) 0;
295 /* Check if application [apid] is already available */
296 application = dlt_daemon_application_find(daemon, apid, verbose);
299 daemon->num_applications += 1;
301 if (daemon->num_applications!=0)
303 if ((daemon->num_applications%DLT_DAEMON_APPL_ALLOC_SIZE)==0)
305 /* allocate memory in steps of DLT_DAEMON_APPL_ALLOC_SIZE, e.g. 100 */
306 old = daemon->applications;
307 daemon->applications = (DltDaemonApplication*) malloc(sizeof(DltDaemonApplication)*
308 ((daemon->num_applications/DLT_DAEMON_APPL_ALLOC_SIZE)+1)*DLT_DAEMON_APPL_ALLOC_SIZE);
309 if (daemon->applications==0)
311 daemon->applications = old;
312 daemon->num_applications -= 1;
313 return (DltDaemonApplication*) 0;
315 memcpy(daemon->applications,old,sizeof(DltDaemonApplication)*daemon->num_applications);
320 application = &(daemon->applications[daemon->num_applications-1]);
322 dlt_set_id(application->apid,apid);
323 application->pid = 0;
324 application->application_description = 0;
325 application->num_contexts = 0;
326 application->user_handle = DLT_FD_INIT;
332 snprintf(str,DLT_DAEMON_COMMON_TEXTBUFSIZE, "Duplicate registration of AppId: %s\n",apid);
333 dlt_log(LOG_ERR, str);
337 /* Store application description and pid of application */
338 if (application->application_description)
340 free(application->application_description);
341 application->application_description=0;
346 application->application_description = malloc(strlen(description)+1);
347 if (application->application_description)
349 strncpy(application->application_description,description,strlen(description)+1);
350 application->application_description[strlen(description)]='\0';
354 if( application->user_handle != DLT_FD_INIT )
356 if( application->pid != pid )
358 if ( close(application->user_handle) < 0 )
360 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 */
361 dlt_log(LOG_ERR, str);
364 application->user_handle = DLT_FD_INIT;
365 application->pid = 0;
369 /* open user pipe only if it is not yet opened */
370 if (application->user_handle==DLT_FD_INIT && pid!=0)
372 sprintf(filename,"%s/dlt%d",DLT_USER_DIR,pid);
374 dlt_user_handle = open(filename, O_WRONLY|O_NONBLOCK);
375 if ( dlt_user_handle < 0 )
377 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 */
378 dlt_log(LOG_ERR, str);
381 /* check if file file descriptor was already used, and make it invalid if it is reused */
382 /* This prevents sending messages to wrong file descriptor */
383 dlt_daemon_applications_invalidate_fd(daemon,dlt_user_handle,verbose);
384 dlt_daemon_contexts_invalidate_fd(daemon,dlt_user_handle,verbose);
386 application->pid = pid;
387 application->user_handle = dlt_user_handle;
393 qsort(daemon->applications,daemon->num_applications,sizeof(DltDaemonApplication),dlt_daemon_cmp_apid);
395 /* Find new position of application with apid*/
396 application = dlt_daemon_application_find(daemon, apid, verbose);
402 int dlt_daemon_application_del(DltDaemon *daemon, DltDaemonApplication *application, int verbose)
406 PRINT_FUNCTION_VERBOSE(verbose);
408 if ((daemon==0) || (application==0))
413 if (daemon->num_applications>0)
415 /* Check if user handle is open; if yes, close it */
416 if (application->user_handle >= DLT_FD_MINIMUM)
418 close(application->user_handle);
419 application->user_handle=DLT_FD_INIT;
422 /* Free description of application to be deleted */
423 if (application->application_description)
425 free(application->application_description);
426 application->application_description = 0;
429 pos = application-(daemon->applications);
431 /* move all applications above pos to pos */
432 memmove(&(daemon->applications[pos]),&(daemon->applications[pos+1]), sizeof(DltDaemonApplication)*((daemon->num_applications-1)-pos));
434 /* Clear last application */
435 memset(&(daemon->applications[daemon->num_applications-1]),0,sizeof(DltDaemonApplication));
437 daemon->num_applications--;
444 DltDaemonApplication* dlt_daemon_application_find(DltDaemon *daemon,char *apid,int verbose)
446 DltDaemonApplication application;
448 PRINT_FUNCTION_VERBOSE(verbose);
450 if ((daemon==0) || (apid==0) || (apid[0]=='\0') || (daemon->num_applications==0))
452 return (DltDaemonApplication*) 0;
455 /* Check, if apid is smaller than smallest apid or greater than greatest apid */
456 if ((memcmp(apid,daemon->applications[0].apid,DLT_ID_SIZE)<0) ||
457 (memcmp(apid,daemon->applications[daemon->num_applications-1].apid,DLT_ID_SIZE)>0))
459 return (DltDaemonApplication*) 0;
462 dlt_set_id(application.apid,apid);
463 return (DltDaemonApplication*)bsearch(&application,daemon->applications,daemon->num_applications,sizeof(DltDaemonApplication),dlt_daemon_cmp_apid);
466 int dlt_daemon_applications_load(DltDaemon *daemon,const char *filename, int verbose)
470 char buf[DLT_DAEMON_COMMON_TEXTBUFSIZE];
474 PRINT_FUNCTION_VERBOSE(verbose);
476 if ((daemon==0) || (filename==0) || (filename[0]=='\0'))
481 fd=fopen(filename, "r");
491 memset(buf, 0, sizeof(buf));
494 ret=fgets(buf,sizeof(buf),fd);
497 /* fgets always null pointer if the last byte of the file is a new line
498 * We need to check here if there was an error or was it feof.*/
501 snprintf(str,DLT_DAEMON_COMMON_TEXTBUFSIZE, "dlt_daemon_applications_load fgets(buf,sizeof(buf),fd) returned NULL. %s\n",
503 dlt_log(LOG_ERR, str);
513 snprintf(str,DLT_DAEMON_COMMON_TEXTBUFSIZE, "dlt_daemon_applications_load fgets(buf,sizeof(buf),fd) returned NULL. Unknown error.\n");
514 dlt_log(LOG_ERR, str);
520 if (strcmp(buf,"")!=0)
526 /* pb contains now the description */
528 /* pid is unknown at loading time */
529 if (dlt_daemon_application_add(daemon,apid,0,pb,verbose)==0)
541 int dlt_daemon_applications_save(DltDaemon *daemon,const char *filename, int verbose)
546 char apid[DLT_ID_SIZE+1]; /* DLT_ID_SIZE+1, because the 0-termination is required here */
548 PRINT_FUNCTION_VERBOSE(verbose);
550 if ((daemon==0) || (filename==0) || (filename[0]=='\0'))
555 memset(apid,0, sizeof(apid));
557 if ((daemon->applications) && (daemon->num_applications>0))
559 fd=fopen(filename, "w");
562 for (i=0; i<daemon->num_applications; i++)
564 dlt_set_id(apid,daemon->applications[i].apid);
566 if ((daemon->applications[i].application_description) &&
567 (daemon->applications[i].application_description!='\0'))
569 fprintf(fd,"%s:%s:\n",apid, daemon->applications[i].application_description);
573 fprintf(fd,"%s::\n",apid);
583 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)
585 DltDaemonApplication *application;
586 DltDaemonContext *context;
587 DltDaemonContext *old;
590 PRINT_FUNCTION_VERBOSE(verbose);
592 if ((daemon==0) || (apid==0) || (apid[0]=='\0') || (ctid==0) || (ctid[0]=='\0'))
594 return (DltDaemonContext*) 0;
597 if ((log_level<DLT_LOG_DEFAULT) || (log_level>DLT_LOG_VERBOSE))
599 return (DltDaemonContext*) 0;
602 if ((trace_status<DLT_TRACE_STATUS_DEFAULT) || (trace_status>DLT_TRACE_STATUS_ON))
604 return (DltDaemonContext*) 0;
607 if (daemon->contexts == 0)
609 daemon->contexts = (DltDaemonContext*) malloc(sizeof(DltDaemonContext)*DLT_DAEMON_CONTEXT_ALLOC_SIZE);
610 if (daemon->contexts==0)
612 return (DltDaemonContext*) 0;
616 /* Check if application [apid] is available */
617 application = dlt_daemon_application_find(daemon, apid, verbose);
620 return (DltDaemonContext*) 0;
623 /* Check if context [apid, ctid] is already available */
624 context = dlt_daemon_context_find(daemon, apid, ctid, verbose);
627 daemon->num_contexts += 1;
629 if (daemon->num_contexts!=0)
631 if ((daemon->num_contexts%DLT_DAEMON_CONTEXT_ALLOC_SIZE)==0)
633 /* allocate memory for context in steps of DLT_DAEMON_CONTEXT_ALLOC_SIZE, e.g 100 */
634 old = daemon->contexts;
635 daemon->contexts = (DltDaemonContext*) malloc(sizeof(DltDaemonContext)*
636 ((daemon->num_contexts/DLT_DAEMON_CONTEXT_ALLOC_SIZE)+1)*DLT_DAEMON_CONTEXT_ALLOC_SIZE);
637 if (daemon->contexts==0)
639 daemon->contexts = old;
640 daemon->num_contexts -= 1;
641 return (DltDaemonContext*) 0;
643 memcpy(daemon->contexts,old,sizeof(DltDaemonContext)*daemon->num_contexts);
648 context = &(daemon->contexts[daemon->num_contexts-1]);
650 dlt_set_id(context->apid,apid);
651 dlt_set_id(context->ctid,ctid);
652 context->context_description = 0;
654 application->num_contexts++;
658 /* Set context description */
659 if (context->context_description)
661 free(context->context_description);
662 context->context_description=0;
667 context->context_description = malloc(strlen(description)+1);
669 if (context->context_description)
671 strncpy(context->context_description,description,strlen(description)+1);
672 context->context_description[strlen(description)]='\0';
676 /* Store log level and trace status,
677 if this is a new context, or
678 if this is an old context and the runtime cfg was not loaded */
680 if ((new_context==1) ||
681 ((new_context==0) && (daemon->runtime_context_cfg_loaded==0)))
683 context->log_level = log_level;
684 context->trace_status = trace_status;
687 context->log_level_pos = log_level_pos;
688 context->user_handle = user_handle;
693 qsort(daemon->contexts,daemon->num_contexts, sizeof(DltDaemonContext),dlt_daemon_cmp_apid_ctid);
695 /* Find new position of context with apid, ctid */
696 context = dlt_daemon_context_find(daemon, apid, ctid, verbose);
702 int dlt_daemon_context_del(DltDaemon *daemon, DltDaemonContext* context, int verbose)
705 DltDaemonApplication *application;
707 PRINT_FUNCTION_VERBOSE(verbose);
709 if ((daemon==0) || (context==0))
714 if (daemon->num_contexts>0)
716 application = dlt_daemon_application_find(daemon, context->apid, verbose);
718 /* Free description of context to be deleted */
719 if (context->context_description)
721 free(context->context_description);
722 context->context_description = 0;
725 pos = context-(daemon->contexts);
727 /* move all contexts above pos to pos */
728 memmove(&(daemon->contexts[pos]),&(daemon->contexts[pos+1]), sizeof(DltDaemonContext)*((daemon->num_contexts-1)-pos));
730 /* Clear last context */
731 memset(&(daemon->contexts[daemon->num_contexts-1]),0,sizeof(DltDaemonContext));
733 daemon->num_contexts--;
735 /* Check if application [apid] is available */
738 application->num_contexts--;
745 DltDaemonContext* dlt_daemon_context_find(DltDaemon *daemon,char *apid,char *ctid,int verbose)
747 DltDaemonContext context;
749 PRINT_FUNCTION_VERBOSE(verbose);
751 if ((daemon==0) || (apid==0) || (apid[0]=='\0') || (ctid==0) || (ctid[0]=='\0') || (daemon->num_contexts==0))
753 return (DltDaemonContext*) 0;
756 /* Check, if apid is smaller than smallest apid or greater than greatest apid */
757 if ((memcmp(apid,daemon->contexts[0].apid,DLT_ID_SIZE)<0) ||
758 (memcmp(apid,daemon->contexts[daemon->num_contexts-1].apid,DLT_ID_SIZE)>0))
760 return (DltDaemonContext*) 0;
763 dlt_set_id(context.apid,apid);
764 dlt_set_id(context.ctid,ctid);
766 return (DltDaemonContext*)bsearch(&context,daemon->contexts,daemon->num_contexts,sizeof(DltDaemonContext),dlt_daemon_cmp_apid_ctid);
769 int dlt_daemon_contexts_invalidate_fd(DltDaemon *daemon,int fd,int verbose)
773 PRINT_FUNCTION_VERBOSE(verbose);
780 for (i=0; i<daemon->num_contexts; i++)
782 if (daemon->contexts[i].user_handle==fd)
784 daemon->contexts[i].user_handle = DLT_FD_INIT;
791 int dlt_daemon_contexts_clear(DltDaemon *daemon,int verbose)
795 PRINT_FUNCTION_VERBOSE(verbose);
802 for (i=0; i<daemon->num_contexts; i++)
804 if (daemon->contexts[i].context_description!=0)
806 free(daemon->contexts[i].context_description);
807 daemon->contexts[i].context_description = 0;
811 if (daemon->contexts)
813 free(daemon->contexts);
816 daemon->contexts = 0;
818 for (i=0; i<daemon->num_applications; i++)
820 daemon->applications[i].num_contexts = 0;
823 daemon->num_contexts = 0;
828 int dlt_daemon_contexts_load(DltDaemon *daemon,const char *filename, int verbose)
832 char buf[DLT_DAEMON_COMMON_TEXTBUFSIZE];
837 PRINT_FUNCTION_VERBOSE(verbose);
839 if ((daemon==0) || (filename==0) ||( filename[0]=='\0'))
844 fd=fopen(filename, "r");
854 memset(buf, 0, sizeof(buf));
857 ret=fgets(buf,sizeof(buf),fd);
860 /* fgets always returns null pointer if the last byte of the file is a new line.
861 * We need to check here if there was an error or was it feof.*/
864 snprintf(str,DLT_DAEMON_COMMON_TEXTBUFSIZE, "dlt_daemon_contexts_load fgets(buf,sizeof(buf),fd) returned NULL. %s\n",
866 dlt_log(LOG_ERR, str);
876 snprintf(str,DLT_DAEMON_COMMON_TEXTBUFSIZE, "dlt_daemon_contexts_load fgets(buf,sizeof(buf),fd) returned NULL. Unknown error.\n");
877 dlt_log(LOG_ERR, str);
883 if (strcmp(buf,"")!=0)
895 /* pb contains now the description */
897 /* log_level_pos, and user_handle are unknown at loading time */
898 if (dlt_daemon_context_add(daemon,apid,ctid,(int8_t)ll,(int8_t)ts,0,0,pb,verbose)==0)
910 int dlt_daemon_contexts_save(DltDaemon *daemon,const char *filename, int verbose)
915 char apid[DLT_ID_SIZE+1], ctid[DLT_ID_SIZE+1]; /* DLT_ID_SIZE+1, because the 0-termination is required here */
917 PRINT_FUNCTION_VERBOSE(verbose);
919 if ((daemon==0) || (filename==0) ||( filename[0]=='\0'))
924 memset(apid,0, sizeof(apid));
925 memset(ctid,0, sizeof(ctid));
927 if ((daemon->contexts) && (daemon->num_contexts>0))
929 fd=fopen(filename, "w");
932 for (i=0; i<daemon->num_contexts; i++)
934 dlt_set_id(apid,daemon->contexts[i].apid);
935 dlt_set_id(ctid,daemon->contexts[i].ctid);
937 if ((daemon->contexts[i].context_description) &&
938 (daemon->contexts[i].context_description[0]!='\0'))
940 fprintf(fd,"%s:%s:%d:%d:%s:\n",apid,ctid,
941 (int)(daemon->contexts[i].log_level),
942 (int)(daemon->contexts[i].trace_status),
943 daemon->contexts[i].context_description);
947 fprintf(fd,"%s:%s:%d:%d::\n",apid,ctid,
948 (int)(daemon->contexts[i].log_level),
949 (int)(daemon->contexts[i].trace_status));
959 int dlt_daemon_configuration_save(DltDaemon *daemon,const char *filename, int verbose)
963 PRINT_FUNCTION_VERBOSE(verbose);
965 if ((daemon==0) || (filename==0) ||( filename[0]=='\0'))
970 fd=fopen(filename, "w");
973 fprintf(fd,"# 0 = off, 1 = external, 2 = internal, 3 = both\n");
974 fprintf(fd,"LoggingMode = %d\n",daemon->mode);
982 int dlt_daemon_configuration_load(DltDaemon *daemon,const char *filename, int verbose)
990 PRINT_FUNCTION_VERBOSE(verbose);
992 pFile = fopen (filename,"r");
998 /* fetch line from configuration file */
999 if ( fgets (line , 1024 , pFile) != NULL )
1001 pch = strtok (line," =\r\n");
1007 if(strcmp(pch,"#")==0)
1012 strncpy(token,pch,sizeof(token));
1016 strncpy(value,pch,sizeof(value));
1020 pch = strtok (NULL, " =\r\n");
1023 if(token[0] && value[0])
1025 /* parse arguments here */
1026 if(strcmp(token,"LoggingMode")==0)
1028 daemon->mode = atoi(value);
1029 sprintf(str,"Runtime Option: %s=%d\n",token,daemon->mode);
1030 dlt_log(LOG_INFO, str);
1034 sprintf(str,"Unknown option: %s=%s\n",token,value);
1035 dlt_log(LOG_ERR, str);
1048 sprintf(str,"Cannot open configuration file: %s\n",filename);
1049 dlt_log(LOG_WARNING, str);
1055 int dlt_daemon_user_send_log_level(DltDaemon *daemon,DltDaemonContext *context,int verbose)
1057 DltUserHeader userheader;
1058 DltUserControlMsgLogLevel usercontext;
1061 PRINT_FUNCTION_VERBOSE(verbose);
1063 if ((daemon==0) || (context==0))
1068 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG_LEVEL)==-1)
1073 usercontext.log_level = ((context->log_level == DLT_LOG_DEFAULT)?daemon->default_log_level:context->log_level);
1074 usercontext.trace_status = ((context->trace_status == DLT_TRACE_STATUS_DEFAULT)?daemon->default_trace_status:context->trace_status);
1076 usercontext.log_level_pos = context->log_level_pos;
1079 ret = dlt_user_log_out2(context->user_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgLogLevel));
1081 if (ret!=DLT_RETURN_OK)
1085 /* Close connection */
1086 close(context->user_handle);
1087 context->user_handle=DLT_FD_INIT;
1091 return ((ret==DLT_RETURN_OK)?0:-1);
1094 int dlt_daemon_user_send_log_state(DltDaemon *daemon,DltDaemonApplication *app,int verbose)
1096 DltUserHeader userheader;
1097 DltUserControlMsgLogState logstate;
1100 PRINT_FUNCTION_VERBOSE(verbose);
1102 if ((daemon==0) || (app==0))
1107 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG_STATE)==-1)
1112 logstate.log_state = daemon->state;
1115 ret = dlt_user_log_out2(app->user_handle, &(userheader), sizeof(DltUserHeader), &(logstate), sizeof(DltUserControlMsgLogState));
1117 if (ret!=DLT_RETURN_OK)
1121 /* Close connection */
1122 close(app->user_handle);
1123 app->user_handle=DLT_FD_INIT;
1127 return ((ret==DLT_RETURN_OK)?0:-1);
1130 int dlt_daemon_control_process_control(int sock, DltDaemon *daemon, DltMessage *msg, int verbose)
1132 uint32_t id,id_tmp=0;
1134 PRINT_FUNCTION_VERBOSE(verbose);
1136 if ((daemon==0) || (msg==0))
1141 if (msg->datasize < (int32_t)sizeof(uint32_t))
1146 id_tmp = *((uint32_t*)(msg->databuffer));
1147 id=DLT_ENDIAN_GET_32(msg->standardheader->htyp ,id_tmp);
1149 if ((id > 0) && (id <= DLT_SERVICE_ID_MESSAGE_BUFFER_OVERFLOW))
1151 /* Control message handling */
1154 case DLT_SERVICE_ID_SET_LOG_LEVEL:
1156 dlt_daemon_control_set_log_level(sock, daemon, msg, verbose);
1159 case DLT_SERVICE_ID_SET_TRACE_STATUS:
1161 dlt_daemon_control_set_trace_status(sock, daemon, msg, verbose);
1164 case DLT_SERVICE_ID_GET_LOG_INFO:
1166 dlt_daemon_control_get_log_info(sock, daemon, msg, verbose);
1169 case DLT_SERVICE_ID_GET_DEFAULT_LOG_LEVEL:
1171 dlt_daemon_control_get_default_log_level(sock, daemon, verbose);
1174 case DLT_SERVICE_ID_STORE_CONFIG:
1176 if (dlt_daemon_applications_save(daemon, daemon->runtime_application_cfg, verbose)==0)
1178 if (dlt_daemon_contexts_save(daemon, daemon->runtime_context_cfg, verbose)==0)
1180 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_OK, verbose);
1184 /* Delete saved files */
1185 dlt_daemon_control_reset_to_factory_default(daemon, daemon->runtime_application_cfg, daemon->runtime_context_cfg, verbose);
1186 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
1191 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
1195 case DLT_SERVICE_ID_RESET_TO_FACTORY_DEFAULT:
1197 dlt_daemon_control_reset_to_factory_default(daemon, daemon->runtime_application_cfg, daemon->runtime_context_cfg, verbose);
1198 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_OK, verbose);
1201 case DLT_SERVICE_ID_SET_COM_INTERFACE_STATUS:
1203 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose);
1206 case DLT_SERVICE_ID_SET_COM_INTERFACE_MAX_BANDWIDTH:
1208 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose);
1211 case DLT_SERVICE_ID_SET_VERBOSE_MODE:
1213 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose);
1216 case DLT_SERVICE_ID_SET_MESSAGE_FILTERING:
1218 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose);
1221 case DLT_SERVICE_ID_SET_TIMING_PACKETS:
1223 dlt_daemon_control_set_timing_packets(sock, daemon, msg, verbose);
1226 case DLT_SERVICE_ID_GET_LOCAL_TIME:
1228 /* Send response with valid timestamp (TMSP) field */
1229 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_OK, verbose);
1232 case DLT_SERVICE_ID_USE_ECU_ID:
1234 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose);
1237 case DLT_SERVICE_ID_USE_SESSION_ID:
1239 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose);
1242 case DLT_SERVICE_ID_USE_TIMESTAMP:
1244 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose);
1247 case DLT_SERVICE_ID_USE_EXTENDED_HEADER:
1249 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose);
1252 case DLT_SERVICE_ID_SET_DEFAULT_LOG_LEVEL:
1254 dlt_daemon_control_set_default_log_level(sock, daemon, msg, verbose);
1257 case DLT_SERVICE_ID_SET_DEFAULT_TRACE_STATUS:
1259 dlt_daemon_control_set_default_trace_status(sock, daemon, msg, verbose);
1262 case DLT_SERVICE_ID_GET_SOFTWARE_VERSION:
1264 dlt_daemon_control_get_software_version(sock, daemon, verbose);
1267 case DLT_SERVICE_ID_MESSAGE_BUFFER_OVERFLOW:
1269 dlt_daemon_control_message_buffer_overflow(sock, daemon, verbose);
1274 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose);
1281 /* Injection handling */
1282 dlt_daemon_control_callsw_cinjection(sock, daemon, msg, verbose);
1288 void dlt_daemon_control_callsw_cinjection(int sock, DltDaemon *daemon, DltMessage *msg, int verbose)
1290 char apid[DLT_ID_SIZE],ctid[DLT_ID_SIZE];
1291 uint32_t id=0,id_tmp=0;
1293 DltDaemonContext *context;
1294 int32_t data_length_inject=0;
1295 uint32_t data_length_inject_tmp=0;
1299 DltUserHeader userheader;
1300 DltUserControlMsgInjection usercontext;
1301 uint8_t *userbuffer;
1303 PRINT_FUNCTION_VERBOSE(verbose);
1305 if ((daemon==0) || (msg==0))
1310 datalength = msg->datasize;
1311 ptr = msg->databuffer;
1318 DLT_MSG_READ_VALUE(id_tmp,ptr,datalength,uint32_t); /* Get service id */
1319 id=DLT_ENDIAN_GET_32(msg->standardheader->htyp, id_tmp);
1321 if ((id>=DLT_DAEMON_INJECTION_MIN) && (id<=DLT_DAEMON_INJECTION_MAX))
1323 /* This a a real SW-C injection call */
1324 data_length_inject=0;
1325 data_length_inject_tmp=0;
1327 DLT_MSG_READ_VALUE(data_length_inject_tmp,ptr,datalength,uint32_t); /* Get data length */
1328 data_length_inject=DLT_ENDIAN_GET_32(msg->standardheader->htyp, data_length_inject_tmp);
1330 /* Get context handle for apid, ctid (and seid) */
1331 /* Warning: seid is ignored in this implementation! */
1332 if (DLT_IS_HTYP_UEH(msg->standardheader->htyp))
1334 dlt_set_id(apid, msg->extendedheader->apid);
1335 dlt_set_id(ctid, msg->extendedheader->ctid);
1339 /* No extended header, and therefore no apid and ctid available */
1340 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
1344 /* At this point, apid and ctid is available */
1345 context=dlt_daemon_context_find(daemon, apid, ctid, verbose);
1349 // dlt_log(LOG_INFO,"No context found!\n");
1350 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
1354 /* Send user message to handle, specified in context */
1355 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_INJECTION)==-1)
1357 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
1361 usercontext.log_level_pos = context->log_level_pos;
1363 if(data_length_inject > msg->databuffersize)
1365 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
1369 userbuffer = malloc(data_length_inject);
1373 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
1377 usercontext.data_length_inject = data_length_inject;
1378 usercontext.service_id = id;
1380 memcpy(userbuffer,ptr,data_length_inject); /* Copy received injection to send buffer */
1383 DltReturnValue ret =
1384 dlt_user_log_out3(context->user_handle, &(userheader), sizeof(DltUserHeader),
1385 &(usercontext), sizeof(DltUserControlMsgInjection),
1386 userbuffer, data_length_inject);
1387 if (ret != DLT_RETURN_OK)
1389 if (ret == DLT_RETURN_PIPE_ERROR)
1391 /* Close connection */
1392 close(context->user_handle);
1393 context->user_handle=DLT_FD_INIT;
1395 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
1399 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_OK, verbose);
1409 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose);
1413 void dlt_daemon_control_set_log_level(int sock, DltDaemon *daemon, DltMessage *msg, int verbose)
1415 PRINT_FUNCTION_VERBOSE(verbose);
1417 char apid[DLT_ID_SIZE],ctid[DLT_ID_SIZE];
1418 DltServiceSetLogLevel *req;
1419 DltDaemonContext *context;
1420 int32_t id=DLT_SERVICE_ID_SET_LOG_LEVEL;
1422 int8_t old_log_level;
1424 if ((daemon==0) || (msg==0))
1429 req = (DltServiceSetLogLevel*) (msg->databuffer);
1431 dlt_set_id(apid, req->apid);
1432 dlt_set_id(ctid, req->ctid);
1434 context=dlt_daemon_context_find(daemon, apid, ctid, verbose);
1439 old_log_level = context->log_level;
1440 context->log_level = req->log_level; /* No endianess conversion necessary*/
1442 if ((context->user_handle >= DLT_FD_MINIMUM) &&
1443 (dlt_daemon_user_send_log_level(daemon, context, verbose)==0))
1445 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_OK, verbose);
1449 //dlt_log(LOG_ERR, "Log level could not be sent!\n");
1450 context->log_level = old_log_level;
1451 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
1456 //dlt_log(LOG_ERR, "Context not found!\n");
1457 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
1461 void dlt_daemon_control_set_trace_status(int sock, DltDaemon *daemon, DltMessage *msg, int verbose)
1463 PRINT_FUNCTION_VERBOSE(verbose);
1465 char apid[DLT_ID_SIZE],ctid[DLT_ID_SIZE];
1466 DltServiceSetLogLevel *req; /* request uses same struct as set log level */
1467 DltDaemonContext *context;
1468 int32_t id=DLT_SERVICE_ID_SET_TRACE_STATUS;
1470 int8_t old_trace_status;
1472 if ((daemon==0) || (msg==0))
1477 req = (DltServiceSetLogLevel*) (msg->databuffer);
1479 dlt_set_id(apid, req->apid);
1480 dlt_set_id(ctid, req->ctid);
1482 context=dlt_daemon_context_find(daemon, apid, ctid, verbose);
1487 old_trace_status = context->trace_status;
1488 context->trace_status = req->log_level; /* No endianess conversion necessary */
1490 if ((context->user_handle >= DLT_FD_MINIMUM ) &&
1491 (dlt_daemon_user_send_log_level(daemon, context, verbose)==0))
1493 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_OK, verbose);
1497 //dlt_log(LOG_ERR, "Trace Status could not be sent!\n");
1498 context->trace_status = old_trace_status;
1499 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
1504 //dlt_log(LOG_ERR, "Context not found!\n");
1505 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
1509 void dlt_daemon_control_set_default_log_level(int sock, DltDaemon *daemon, DltMessage *msg, int verbose)
1511 PRINT_FUNCTION_VERBOSE(verbose);
1513 DltServiceSetDefaultLogLevel *req;
1514 int32_t id=DLT_SERVICE_ID_SET_DEFAULT_LOG_LEVEL;
1516 if ((daemon==0) || (msg==0))
1521 req = (DltServiceSetDefaultLogLevel*) (msg->databuffer);
1523 /* No endianess conversion necessary */
1524 if (/*(req->log_level>=0) &&*/
1525 (req->log_level<=DLT_LOG_VERBOSE))
1527 daemon->default_log_level = req->log_level; /* No endianess conversion necessary */
1529 /* Send Update to all contexts using the default log level */
1530 dlt_daemon_user_send_default_update(daemon, verbose);
1532 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_OK, verbose);
1536 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
1540 void dlt_daemon_control_set_default_trace_status(int sock, DltDaemon *daemon, DltMessage *msg, int verbose)
1542 PRINT_FUNCTION_VERBOSE(verbose);
1544 /* Payload of request message */
1545 DltServiceSetDefaultLogLevel *req;
1546 int32_t id=DLT_SERVICE_ID_SET_DEFAULT_TRACE_STATUS;
1548 if ((daemon==0) || (msg==0))
1553 req = (DltServiceSetDefaultLogLevel*) (msg->databuffer);
1555 /* No endianess conversion necessary */
1556 if ((req->log_level==DLT_TRACE_STATUS_OFF) ||
1557 (req->log_level==DLT_TRACE_STATUS_ON))
1559 daemon->default_trace_status = req->log_level; /* No endianess conversion necessary*/
1561 /* Send Update to all contexts using the default trace status */
1562 dlt_daemon_user_send_default_update(daemon, verbose);
1564 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_OK, verbose);
1568 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
1572 void dlt_daemon_control_set_timing_packets(int sock, DltDaemon *daemon, DltMessage *msg, int verbose)
1574 PRINT_FUNCTION_VERBOSE(verbose);
1576 DltServiceSetVerboseMode *req; /* request uses same struct as set verbose mode */
1577 int32_t id=DLT_SERVICE_ID_SET_TIMING_PACKETS;
1579 if ((daemon==0) || (msg==0))
1584 req = (DltServiceSetVerboseMode*) (msg->databuffer);
1585 if ((req->new_status==0) || (req->new_status==1))
1587 daemon->timingpackets = req->new_status;
1589 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_OK, verbose);
1593 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR, verbose);
1597 void dlt_daemon_control_get_software_version(int sock, DltDaemon *daemon, int verbose)
1601 DltServiceGetSoftwareVersionResponse *resp;
1603 PRINT_FUNCTION_VERBOSE(verbose);
1610 /* initialise new message */
1611 if (dlt_message_init(&msg,0)==-1)
1613 dlt_daemon_control_service_response(sock, daemon, DLT_SERVICE_ID_GET_SOFTWARE_VERSION, DLT_SERVICE_RESPONSE_ERROR, verbose);
1617 /* prepare payload of data */
1618 len = strlen(daemon->ECUVersionString);
1620 msg.datasize = sizeof(DltServiceGetSoftwareVersionResponse) + len;
1621 if (msg.databuffer && (msg.databuffersize < msg.datasize))
1623 free(msg.databuffer);
1626 if (msg.databuffer == 0){
1627 msg.databuffer = (uint8_t *) malloc(msg.datasize);
1628 msg.databuffersize = msg.datasize;
1630 if (msg.databuffer==0)
1632 dlt_daemon_control_service_response(sock, daemon, DLT_SERVICE_ID_GET_SOFTWARE_VERSION, DLT_SERVICE_RESPONSE_ERROR, verbose);
1636 resp = (DltServiceGetSoftwareVersionResponse*) msg.databuffer;
1637 resp->service_id = DLT_SERVICE_ID_GET_SOFTWARE_VERSION;
1638 resp->status = DLT_SERVICE_RESPONSE_OK;
1640 memcpy(msg.databuffer+sizeof(DltServiceGetSoftwareVersionResponse),daemon->ECUVersionString,len);
1643 dlt_daemon_control_send_control_message(sock, daemon, &msg,"","", verbose);
1646 dlt_message_free(&msg,0);
1649 void dlt_daemon_control_get_default_log_level(int sock, DltDaemon *daemon, int verbose)
1652 DltServiceGetDefaultLogLevelResponse *resp;
1654 PRINT_FUNCTION_VERBOSE(verbose);
1661 /* initialise new message */
1662 if (dlt_message_init(&msg,0)==-1)
1664 dlt_daemon_control_service_response(sock, daemon, DLT_SERVICE_ID_GET_DEFAULT_LOG_LEVEL, DLT_SERVICE_RESPONSE_ERROR, verbose);
1668 msg.datasize = sizeof(DltServiceGetDefaultLogLevelResponse);
1669 if (msg.databuffer && (msg.databuffersize<msg.datasize))
1671 free(msg.databuffer);
1674 if (msg.databuffer == 0){
1675 msg.databuffer = (uint8_t *) malloc(msg.datasize);
1676 msg.databuffersize = msg.datasize;
1678 if (msg.databuffer==0)
1680 dlt_daemon_control_service_response(sock, daemon, DLT_SERVICE_ID_GET_DEFAULT_LOG_LEVEL, DLT_SERVICE_RESPONSE_ERROR, verbose);
1684 resp = (DltServiceGetDefaultLogLevelResponse*) msg.databuffer;
1685 resp->service_id = DLT_SERVICE_ID_GET_DEFAULT_LOG_LEVEL;
1686 resp->status = DLT_SERVICE_RESPONSE_OK;
1687 resp->log_level = daemon->default_log_level;
1690 dlt_daemon_control_send_control_message(sock,daemon,&msg,"","", verbose);
1693 dlt_message_free(&msg,0);
1696 void dlt_daemon_control_get_log_info(int sock, DltDaemon *daemon, DltMessage *msg, int verbose)
1698 DltServiceGetLogInfoRequest *req;
1700 DltDaemonContext *context=0;
1701 DltDaemonApplication *application=0;
1703 int num_applications=0, num_contexts=0;
1704 uint16_t count_app_ids=0, count_con_ids=0;
1706 #if (DLT_DEBUG_GETLOGINFO==1)
1710 int32_t i,j,offset=0;
1720 PRINT_FUNCTION_VERBOSE(verbose);
1722 if ((daemon==0) || (msg==0))
1727 /* prepare pointer to message request */
1728 req = (DltServiceGetLogInfoRequest*) (msg->databuffer);
1730 /* initialise new message */
1731 if (dlt_message_init(&resp,0)==-1)
1733 dlt_daemon_control_service_response(sock, daemon, DLT_SERVICE_ID_GET_LOG_INFO, DLT_SERVICE_RESPONSE_ERROR, verbose);
1738 if ((req->options < 3 ) || (req->options>7))
1740 dlt_daemon_control_service_response(sock, daemon, DLT_SERVICE_ID_GET_LOG_INFO, DLT_SERVICE_RESPONSE_ERROR, verbose);
1744 if (req->apid[0]!='\0')
1746 application = dlt_daemon_application_find(daemon, req->apid, verbose);
1749 num_applications = 1;
1750 if (req->ctid[0]!='\0')
1752 context = dlt_daemon_context_find(daemon, req->apid, req->ctid, verbose);
1754 num_contexts = ((context)?1:0);
1758 num_contexts = application->num_contexts;
1763 num_applications = 0;
1769 /* Request all applications and contexts */
1770 num_applications = daemon->num_applications;
1771 num_contexts = daemon->num_contexts;
1774 /* prepare payload of data */
1776 /* Calculate maximum size for a response */
1777 resp.datasize = sizeof(uint32_t) /* SID */ + sizeof(int8_t) /* status*/ + sizeof(ID4) /* DLT_DAEMON_REMO_STRING */;
1779 sizecont = sizeof(uint32_t) /* context_id */;
1781 /* Add additional size for response of Mode 4, 6, 7 */
1782 if ((req->options==4) || (req->options==6) || (req->options==7))
1784 sizecont += sizeof(int8_t); /* log level */
1787 /* Add additional size for response of Mode 5, 6, 7 */
1788 if ((req->options==5) || (req->options==6) || (req->options==7))
1790 sizecont+= sizeof(int8_t); /* trace status */
1793 resp.datasize+= (num_applications * (sizeof(uint32_t) /* app_id */ + sizeof(uint16_t) /* count_con_ids */)) +
1794 (num_contexts * sizecont);
1796 resp.datasize+= sizeof(uint16_t) /* count_app_ids */;
1798 /* Add additional size for response of Mode 7 */
1799 if (req->options==7)
1801 if (req->apid[0]!='\0')
1803 if (req->ctid[0]!='\0')
1805 /* One application, one context */
1806 // context = dlt_daemon_context_find(daemon, req->apid, req->ctid, verbose);
1809 resp.datasize+=sizeof(uint16_t) /* len_context_description */;
1810 if (context->context_description!=0)
1812 resp.datasize+=strlen(context->context_description); /* context_description */
1818 /* One application, all contexts */
1819 if ((daemon->applications) && (application))
1821 /* Calculate start offset within contexts[] */
1823 for (i=0; i<(application-(daemon->applications)); i++)
1825 offset_base+=daemon->applications[i].num_contexts;
1828 /* Iterate over all contexts belonging to this application */
1829 for (j=0;j<application->num_contexts;j++)
1832 context = &(daemon->contexts[offset_base+j]);
1835 resp.datasize+=sizeof(uint16_t) /* len_context_description */;
1836 if (context->context_description!=0)
1838 resp.datasize+=strlen(context->context_description); /* context_description */
1845 /* Space for application description */
1848 resp.datasize+=sizeof(uint16_t) /* len_app_description */;
1849 if (application->application_description!=0)
1851 resp.datasize+=strlen(application->application_description); /* app_description */
1857 /* All applications, all contexts */
1858 for (i=0;i<daemon->num_contexts;i++)
1860 resp.datasize+=sizeof(uint16_t) /* len_context_description */;
1861 if (daemon->contexts[i].context_description!=0)
1863 resp.datasize+=strlen(daemon->contexts[i].context_description); /* context_description */
1867 for (i=0;i<daemon->num_applications;i++)
1869 resp.datasize+=sizeof(uint16_t) /* len_app_description */;
1870 if (daemon->applications[i].application_description!=0)
1872 resp.datasize+=strlen(daemon->applications[i].application_description); /* app_description */
1880 sprintf(str,"Allocate %d bytes for response msg databuffer\n", resp.datasize);
1881 dlt_log(LOG_INFO, str);
1884 /* Allocate buffer for response message */
1885 resp.databuffer = (uint8_t *) malloc(resp.datasize);
1886 resp.databuffersize = resp.datasize;
1888 if (resp.databuffer==0)
1890 dlt_daemon_control_service_response(sock, daemon, DLT_SERVICE_ID_GET_LOG_INFO, DLT_SERVICE_RESPONSE_ERROR, verbose);
1893 memset(resp.databuffer,0,resp.datasize);
1894 /* Preparation finished */
1896 /* Prepare response */
1897 sid = DLT_SERVICE_ID_GET_LOG_INFO;
1898 memcpy(resp.databuffer,&sid,sizeof(uint32_t));
1899 offset+=sizeof(uint32_t);
1901 value = (((num_applications!=0)&&(num_contexts!=0))?req->options:8); /* 8 = no matching context found */
1903 memcpy(resp.databuffer+offset,&value,sizeof(int8_t));
1904 offset+=sizeof(int8_t);
1906 count_app_ids = num_applications;
1908 if (count_app_ids!=0)
1910 memcpy(resp.databuffer+offset,&count_app_ids,sizeof(uint16_t));
1911 offset+=sizeof(uint16_t);
1913 #if (DLT_DEBUG_GETLOGINFO==1)
1914 sprintf(str,"#apid: %d \n", count_app_ids);
1915 dlt_log(LOG_DEBUG, str);
1918 for (i=0;i<count_app_ids;i++)
1920 if (req->apid[0]!='\0')
1926 if (daemon->applications)
1928 apid = daemon->applications[i].apid;
1932 /* This should never occur! */
1937 application = dlt_daemon_application_find(daemon, apid, verbose);
1941 /* Calculate start offset within contexts[] */
1943 for (j=0; j<(application-(daemon->applications)); j++)
1945 offset_base+=daemon->applications[j].num_contexts;
1948 dlt_set_id((char*)(resp.databuffer+offset),apid);
1949 offset+=sizeof(ID4);
1951 #if (DLT_DEBUG_GETLOGINFO==1)
1952 dlt_print_id(buf, apid);
1953 sprintf(str,"apid: %s\n",buf);
1954 dlt_log(LOG_DEBUG, str);
1957 if (req->apid[0]!='\0')
1959 count_con_ids = num_contexts;
1963 count_con_ids = application->num_contexts;
1966 memcpy(resp.databuffer+offset,&count_con_ids,sizeof(uint16_t));
1967 offset+=sizeof(uint16_t);
1969 #if (DLT_DEBUG_GETLOGINFO==1)
1970 sprintf(str,"#ctid: %d \n", count_con_ids);
1971 dlt_log(LOG_DEBUG, str);
1974 for (j=0;j<count_con_ids;j++)
1976 #if (DLT_DEBUG_GETLOGINFO==1)
1977 sprintf(str,"j: %d \n",j);
1978 dlt_log(LOG_DEBUG, str);
1980 if (!((count_con_ids==1) && (req->apid[0]!='\0') && (req->ctid[0]!='\0')))
1982 context = &(daemon->contexts[offset_base+j]);
1984 /* else: context was already searched and found
1985 (one application (found) with one context (found))*/
1988 ((req->ctid[0]=='\0') ||
1989 ((req->ctid[0]!='\0') && (memcmp(context->ctid,req->ctid,DLT_ID_SIZE)==0)))
1992 dlt_set_id((char*)(resp.databuffer+offset),context->ctid);
1993 offset+=sizeof(ID4);
1995 #if (DLT_DEBUG_GETLOGINFO==1)
1996 dlt_print_id(buf, context->ctid);
1997 sprintf(str,"ctid: %s \n",buf);
1998 dlt_log(LOG_DEBUG, str);
2002 if ((req->options==4) || (req->options==6) || (req->options==7))
2004 ll=context->log_level;
2005 memcpy(resp.databuffer+offset,&ll,sizeof(int8_t));
2006 offset+=sizeof(int8_t);
2010 if ((req->options==5) || (req->options==6) || (req->options==7))
2012 ts=context->trace_status;
2013 memcpy(resp.databuffer+offset,&ts,sizeof(int8_t));
2014 offset+=sizeof(int8_t);
2018 if (req->options==7)
2020 if (context->context_description)
2022 len = strlen(context->context_description);
2023 memcpy(resp.databuffer+offset,&len,sizeof(uint16_t));
2024 offset+=sizeof(uint16_t);
2025 memcpy(resp.databuffer+offset,context->context_description,strlen(context->context_description));
2026 offset+=strlen(context->context_description);
2031 memcpy(resp.databuffer+offset,&len,sizeof(uint16_t));
2032 offset+=sizeof(uint16_t);
2036 #if (DLT_DEBUG_GETLOGINFO==1)
2037 sprintf(str,"ll=%d ts=%d \n",(int32_t)ll,(int32_t)ts);
2038 dlt_log(LOG_DEBUG, str);
2042 #if (DLT_DEBUG_GETLOGINFO==1)
2043 dlt_log(LOG_DEBUG,"\n");
2048 if (req->options==7)
2050 if (application->application_description)
2052 len = strlen(application->application_description);
2053 memcpy(resp.databuffer+offset,&len,sizeof(uint16_t));
2054 offset+=sizeof(uint16_t);
2055 memcpy(resp.databuffer+offset,application->application_description,strlen(application->application_description));
2056 offset+=strlen(application->application_description);
2061 memcpy(resp.databuffer+offset,&len,sizeof(uint16_t));
2062 offset+=sizeof(uint16_t);
2065 } /* if (application) */
2066 } /* for (i=0;i<count_app_ids;i++) */
2067 } /* if (count_app_ids!=0) */
2069 dlt_set_id((char*)(resp.databuffer+offset),DLT_DAEMON_REMO_STRING);
2072 dlt_daemon_control_send_control_message(sock,daemon,&resp,"","", verbose);
2075 dlt_message_free(&resp,0);
2078 void dlt_daemon_control_message_buffer_overflow(int sock, DltDaemon *daemon, int verbose)
2081 DltServiceMessageBufferOverflowResponse *resp;
2083 PRINT_FUNCTION_VERBOSE(verbose);
2090 /* initialise new message */
2091 if (dlt_message_init(&msg,0)==-1)
2093 dlt_daemon_control_service_response(sock, daemon, DLT_SERVICE_ID_MESSAGE_BUFFER_OVERFLOW, DLT_SERVICE_RESPONSE_ERROR, verbose);
2097 /* prepare payload of data */
2098 msg.datasize = sizeof(DltServiceMessageBufferOverflowResponse);
2099 if (msg.databuffer && (msg.databuffersize < msg.datasize))
2101 free(msg.databuffer);
2104 if (msg.databuffer == 0){
2105 msg.databuffer = (uint8_t *) malloc(msg.datasize);
2106 msg.databuffersize = msg.datasize;
2108 if (msg.databuffer==0)
2110 if (sock!=DLT_DAEMON_STORE_TO_BUFFER)
2112 dlt_daemon_control_service_response(sock, daemon, DLT_SERVICE_ID_MESSAGE_BUFFER_OVERFLOW, DLT_SERVICE_RESPONSE_ERROR, verbose);
2117 resp = (DltServiceMessageBufferOverflowResponse*) msg.databuffer;
2118 resp->service_id = DLT_SERVICE_ID_MESSAGE_BUFFER_OVERFLOW;
2119 resp->status = DLT_SERVICE_RESPONSE_OK;
2120 resp->overflow = daemon->message_buffer_overflow;
2123 dlt_daemon_control_send_control_message(sock,daemon,&msg,"","", verbose);
2126 dlt_message_free(&msg,0);
2129 void dlt_daemon_control_service_response( int sock, DltDaemon *daemon, uint32_t service_id, int8_t status , int verbose)
2132 DltServiceResponse *resp;
2134 PRINT_FUNCTION_VERBOSE(verbose);
2141 /* initialise new message */
2142 if (dlt_message_init(&msg,0)==-1)
2147 /* prepare payload of data */
2148 msg.datasize = sizeof(DltServiceResponse);
2149 if (msg.databuffer && (msg.databuffersize < msg.datasize))
2151 free(msg.databuffer);
2154 if (msg.databuffer == 0){
2155 msg.databuffer = (uint8_t *) malloc(msg.datasize);
2156 msg.databuffersize = msg.datasize;
2158 if (msg.databuffer==0)
2163 resp = (DltServiceResponse*) msg.databuffer;
2164 resp->service_id = service_id;
2165 resp->status = status;
2168 dlt_daemon_control_send_control_message(sock,daemon,&msg,"","", verbose);
2171 dlt_message_free(&msg,0);
2174 void dlt_daemon_control_send_control_message( int sock, DltDaemon *daemon, DltMessage *msg, char* appid, char* ctid, int verbose)
2179 PRINT_FUNCTION_VERBOSE(verbose);
2181 if ((daemon==0) || (msg==0) || (appid==0) || (ctid==0))
2186 /* prepare storage header */
2187 msg->storageheader = (DltStorageHeader*)msg->headerbuffer;
2189 if (dlt_set_storageheader(msg->storageheader,daemon->ecuid)==-1)
2194 /* prepare standard header */
2195 msg->standardheader = (DltStandardHeader*)(msg->headerbuffer + sizeof(DltStorageHeader));
2196 msg->standardheader->htyp = DLT_HTYP_WEID | DLT_HTYP_WTMS | DLT_HTYP_UEH | DLT_HTYP_PROTOCOL_VERSION1 ;
2198 #if (BYTE_ORDER==BIG_ENDIAN)
2199 msg->standardheader->htyp = ( msg->standardheader->htyp | DLT_HTYP_MSBF);
2202 msg->standardheader->mcnt = 0;
2204 /* Set header extra parameters */
2205 dlt_set_id(msg->headerextra.ecu,daemon->ecuid);
2207 //msg->headerextra.seid = 0;
2209 msg->headerextra.tmsp = dlt_uptime();
2211 dlt_message_set_extraparameters(msg, verbose);
2213 /* prepare extended header */
2214 msg->extendedheader = (DltExtendedHeader*)(msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg->standardheader->htyp));
2215 msg->extendedheader->msin = DLT_MSIN_CONTROL_RESPONSE;
2217 msg->extendedheader->noar = 1; /* number of arguments */
2218 if (strcmp(appid,"")==0)
2220 dlt_set_id(msg->extendedheader->apid,DLT_DAEMON_CTRL_APID); /* application id */
2224 dlt_set_id(msg->extendedheader->apid, appid);
2226 if (strcmp(ctid,"")==0)
2228 dlt_set_id(msg->extendedheader->ctid,DLT_DAEMON_CTRL_CTID); /* context id */
2232 dlt_set_id(msg->extendedheader->ctid, ctid);
2235 /* prepare length information */
2236 msg->headersize = sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + sizeof(DltExtendedHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg->standardheader->htyp);
2238 len=msg->headersize - sizeof(DltStorageHeader) + msg->datasize;
2241 dlt_log(LOG_CRIT,"Huge control message discarded!\n");
2245 msg->standardheader->len = DLT_HTOBE_16(((uint16_t)len));
2247 if (sock!=DLT_DAEMON_STORE_TO_BUFFER)
2252 DLT_DAEMON_SEM_LOCK();
2254 /* Optional: Send serial header, if requested */
2255 if (daemon->sendserialheader)
2257 ret=write(sock,dltSerialHeader,sizeof(dltSerialHeader));
2260 dlt_log(LOG_CRIT,"dlt_daemon_control_send_control_message: write dltSerialHeader failed\n");
2261 DLT_DAEMON_SEM_FREE();
2267 ret=write(sock, msg->headerbuffer+sizeof(DltStorageHeader),msg->headersize-sizeof(DltStorageHeader));
2270 dlt_log(LOG_CRIT,"dlt_daemon_control_send_control_message: write msg->headerbuffer failed\n");
2271 DLT_DAEMON_SEM_FREE();
2274 ret=write(sock, msg->databuffer,msg->datasize);
2277 dlt_log(LOG_CRIT,"dlt_daemon_control_send_control_message: write msg->databuffer failed\n");
2278 DLT_DAEMON_SEM_FREE();
2282 DLT_DAEMON_SEM_FREE();
2286 DLT_DAEMON_SEM_LOCK();
2288 /* Optional: Send serial header, if requested */
2289 if (daemon->sendserialheader)
2291 if (0 > send(sock, dltSerialHeader,sizeof(dltSerialHeader),0))
2292 dlt_log(LOG_WARNING,"dlt_daemon_control_send_control_message: send serialheader failed\n");
2298 if ( 0 > send(sock, msg->headerbuffer+sizeof(DltStorageHeader),msg->headersize-sizeof(DltStorageHeader),0))
2299 dlt_log(LOG_WARNING,"dlt_daemon_control_send_control_message: send DltStorageHeader failed\n");
2301 if ( 0 > send(sock, msg->databuffer,msg->datasize,0))
2302 dlt_log(LOG_WARNING,"dlt_daemon_control_send_control_message: send databuffer failed\n");
2304 DLT_DAEMON_SEM_FREE();
2309 DLT_DAEMON_SEM_LOCK();
2310 /* Store message in history buffer */
2311 if (dlt_buffer_push3(&(daemon->client_ringbuffer),
2312 msg->headerbuffer+sizeof(DltStorageHeader),msg->headersize-sizeof(DltStorageHeader),
2313 msg->databuffer,msg->datasize,
2317 DLT_DAEMON_SEM_FREE();
2318 dlt_log(LOG_ERR,"Storage of message in history buffer failed! Message discarded.\n");
2321 DLT_DAEMON_SEM_FREE();
2325 void dlt_daemon_control_reset_to_factory_default(DltDaemon *daemon,const char *filename, const char *filename1, int verbose)
2329 PRINT_FUNCTION_VERBOSE(verbose);
2331 if ((daemon==0) || (filename==0) || (filename1==0) || (filename[0]=='\0') || (filename1[0]=='\0'))
2336 /* Check for runtime cfg file and delete it, if available */
2337 fd=fopen(filename, "r");
2341 /* Close and delete file */
2346 fd=fopen(filename1, "r");
2350 /* Close and delete file */
2355 daemon->default_log_level = DLT_DAEMON_INITIAL_LOG_LEVEL ;
2356 daemon->default_trace_status = DLT_DAEMON_INITIAL_TRACE_STATUS ;
2358 daemon->message_buffer_overflow = DLT_MESSAGE_BUFFER_NO_OVERFLOW;
2360 /* Reset all other things (log level, trace status, etc.
2361 to default values */
2363 /* Inform user libraries about changed default log level/trace status */
2364 dlt_daemon_user_send_default_update(daemon, verbose);
2367 void dlt_daemon_user_send_default_update(DltDaemon *daemon, int verbose)
2370 DltDaemonContext *context;
2372 PRINT_FUNCTION_VERBOSE(verbose);
2379 for (count=0;count<daemon->num_contexts; count ++)
2381 context = &(daemon->contexts[count]);
2385 if ((context->log_level == DLT_LOG_DEFAULT) ||
2386 (context->trace_status == DLT_TRACE_STATUS_DEFAULT))
2388 if (context->user_handle >= DLT_FD_MINIMUM)
2390 if (dlt_daemon_user_send_log_level(daemon, context, verbose)==-1)
2400 void dlt_daemon_user_send_all_log_state(DltDaemon *daemon, int verbose)
2403 DltDaemonApplication *app;
2405 PRINT_FUNCTION_VERBOSE(verbose);
2412 for (count=0;count<daemon->num_applications; count ++)
2414 app = &(daemon->applications[count]);
2418 if (app->user_handle >= DLT_FD_MINIMUM)
2420 if (dlt_daemon_user_send_log_state(daemon, app, verbose)==-1)
2429 void dlt_daemon_control_message_time(int sock, DltDaemon *daemon, int verbose)
2435 PRINT_FUNCTION_VERBOSE(verbose);
2442 if (sock==DLT_DAEMON_STORE_TO_BUFFER)
2447 /* initialise new message */
2448 if (dlt_message_init(&msg,0)==-1)
2455 /* prepare storage header */
2456 msg.storageheader = (DltStorageHeader*)msg.headerbuffer;
2457 dlt_set_storageheader(msg.storageheader,daemon->ecuid);
2459 /* prepare standard header */
2460 msg.standardheader = (DltStandardHeader*)(msg.headerbuffer + sizeof(DltStorageHeader));
2461 msg.standardheader->htyp = DLT_HTYP_WEID | DLT_HTYP_WTMS | DLT_HTYP_UEH | DLT_HTYP_PROTOCOL_VERSION1 ;
2463 #if (BYTE_ORDER==BIG_ENDIAN)
2464 msg.standardheader->htyp = ( msg.standardheader->htyp | DLT_HTYP_MSBF);
2467 msg.standardheader->mcnt = 0;
2469 /* Set header extra parameters */
2470 dlt_set_id(msg.headerextra.ecu,daemon->ecuid);
2471 msg.headerextra.tmsp = dlt_uptime();
2473 dlt_message_set_extraparameters(&msg, verbose);
2475 /* prepare extended header */
2476 msg.extendedheader = (DltExtendedHeader*)(msg.headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp));
2477 msg.extendedheader->msin = DLT_MSIN_CONTROL_TIME;
2479 msg.extendedheader->noar = 0; /* number of arguments */
2480 dlt_set_id(msg.extendedheader->apid,""); /* application id */
2481 dlt_set_id(msg.extendedheader->ctid,""); /* context id */
2483 /* prepare length information */
2484 msg.headersize = sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + sizeof(DltExtendedHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp);
2486 len=msg.headersize - sizeof(DltStorageHeader) + msg.datasize;
2489 dlt_log(LOG_CRIT,"Huge control message discarded!\n");
2492 dlt_message_free(&msg,0);
2497 msg.standardheader->len = DLT_HTOBE_16(((uint16_t)len));
2502 DLT_DAEMON_SEM_LOCK();
2504 /* Optional: Send serial header, if requested */
2505 if (daemon->sendserialheader)
2507 ret=write(sock,dltSerialHeader,sizeof(dltSerialHeader));
2511 ret=write(sock, msg.headerbuffer+sizeof(DltStorageHeader),msg.headersize-sizeof(DltStorageHeader));
2512 if(msg.datasize > 0)
2514 ret=write(sock, msg.databuffer,msg.datasize);
2516 dlt_log(LOG_CRIT,"dlt_daemon_control_message_time: Failed to write databuffer\n");
2517 dlt_message_free(&msg,0);
2518 DLT_DAEMON_SEM_FREE();
2523 DLT_DAEMON_SEM_FREE();
2527 DLT_DAEMON_SEM_LOCK();
2529 /* Optional: Send serial header, if requested */
2530 if (daemon->sendserialheader)
2532 if ( -1 == send(sock, dltSerialHeader,sizeof(dltSerialHeader),0) )
2533 dlt_log(LOG_ERR,"dlt_daemon_control_message_time: Failed to send dltSerialHeader");
2538 if (-1 == send(sock, msg.headerbuffer+sizeof(DltStorageHeader),msg.headersize-sizeof(DltStorageHeader),0))
2539 dlt_log(LOG_ERR,"dlt_daemon_control_message_time: Failed to send DltStorageHeader");
2541 if(msg.datasize > 0)
2543 if (-1 == send(sock, msg.databuffer,msg.datasize,0) )
2544 dlt_log(LOG_ERR,"dlt_daemon_control_message_time: Failed to send databuffer");
2547 DLT_DAEMON_SEM_FREE();
2551 dlt_message_free(&msg,0);