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"
82 #include "dlt-daemon.h"
84 #include "dlt_daemon_socket.h"
85 #include "dlt_daemon_serial.h"
87 static char str[DLT_DAEMON_COMMON_TEXTBUFSIZE];
89 sem_t dlt_daemon_mutex;
91 static int dlt_daemon_cmp_apid(const void *m1, const void *m2)
93 DltDaemonApplication *mi1 = (DltDaemonApplication *) m1;
94 DltDaemonApplication *mi2 = (DltDaemonApplication *) m2;
96 return memcmp(mi1->apid, mi2->apid, DLT_ID_SIZE);
99 static int dlt_daemon_cmp_apid_ctid(const void *m1, const void *m2)
103 DltDaemonContext *mi1 = (DltDaemonContext *) m1;
104 DltDaemonContext *mi2 = (DltDaemonContext *) m2;
106 cmp=memcmp(mi1->apid, mi2->apid, DLT_ID_SIZE);
113 ret=memcmp(mi1->ctid, mi2->ctid, DLT_ID_SIZE);
123 int dlt_daemon_init(DltDaemon *daemon,unsigned long RingbufferMinSize,unsigned long RingbufferMaxSize,unsigned long RingbufferStepSize,const char *runtime_directory, int verbose)
125 PRINT_FUNCTION_VERBOSE(verbose);
132 int append_length = 0;
133 daemon->num_contexts = 0;
134 daemon->contexts = 0;
136 daemon->num_applications = 0;
137 daemon->applications = 0;
139 daemon->default_log_level = DLT_DAEMON_INITIAL_LOG_LEVEL ;
140 daemon->default_trace_status = DLT_DAEMON_INITIAL_TRACE_STATUS ;
142 daemon->overflow_counter = 0;
144 daemon->runtime_context_cfg_loaded = 0;
146 daemon->mode = DLT_USER_MODE_EXTERNAL;
148 daemon->connectionState = 0; /* no logger connected */
150 daemon->state = DLT_DAEMON_STATE_INIT; /* initial logging state */
152 /* prepare filenames for configuration */
154 append_length = PATH_MAX - sizeof(DLT_RUNTIME_APPLICATION_CFG);
155 if(runtime_directory[0])
157 strncpy(daemon->runtime_application_cfg,runtime_directory,append_length);
158 daemon->runtime_application_cfg[append_length]=0;
162 strncpy(daemon->runtime_application_cfg,DLT_RUNTIME_DEFAULT_DIRECTORY,append_length);
163 daemon->runtime_application_cfg[append_length]=0;
165 strcat(daemon->runtime_application_cfg,DLT_RUNTIME_APPLICATION_CFG); /* strcat uncritical here, because max length already checked */
167 append_length = PATH_MAX - sizeof(DLT_RUNTIME_CONTEXT_CFG);
168 if(runtime_directory[0])
170 strncpy(daemon->runtime_context_cfg,runtime_directory,append_length);
171 daemon->runtime_context_cfg[append_length]=0;
175 strncpy(daemon->runtime_context_cfg,DLT_RUNTIME_DEFAULT_DIRECTORY,append_length);
176 daemon->runtime_context_cfg[append_length]=0;
178 strcat(daemon->runtime_context_cfg,DLT_RUNTIME_CONTEXT_CFG); /* strcat uncritical here, because max length already checked */
180 append_length = PATH_MAX - sizeof(DLT_RUNTIME_CONFIGURATION);
181 if(runtime_directory[0])
183 strncpy(daemon->runtime_configuration,runtime_directory,append_length);
184 daemon->runtime_configuration[append_length]=0;
188 strncpy(daemon->runtime_configuration,DLT_RUNTIME_DEFAULT_DIRECTORY,append_length);
189 daemon->runtime_configuration[append_length]=0;
191 strcat(daemon->runtime_configuration,DLT_RUNTIME_CONFIGURATION); /* strcat uncritical here, because max length already checked */
193 /* Check for runtime cfg, if it is loadable, load it! */
194 if ((dlt_daemon_applications_load(daemon,daemon->runtime_application_cfg, verbose)==0) &&
195 (dlt_daemon_contexts_load(daemon,daemon->runtime_context_cfg, verbose)==0))
197 daemon->runtime_context_cfg_loaded = 1;
200 /* load configuration if available */
201 dlt_daemon_configuration_load(daemon,daemon->runtime_configuration, verbose);
203 daemon->sendserialheader = 0;
204 daemon->timingpackets = 0;
206 dlt_set_id(daemon->ecuid,"");
208 /* initialize ring buffer for client connection */
209 snprintf(str,DLT_DAEMON_COMMON_TEXTBUFSIZE,"Ringbuffer configuration: %lu/%lu/%lu\n", RingbufferMinSize,RingbufferMaxSize,RingbufferStepSize );
210 dlt_log(LOG_INFO, str);
211 if (dlt_buffer_init_dynamic(&(daemon->client_ringbuffer), RingbufferMinSize,RingbufferMaxSize,RingbufferStepSize)==-1)
219 int dlt_daemon_free(DltDaemon *daemon,int verbose)
221 PRINT_FUNCTION_VERBOSE(verbose);
229 if (dlt_daemon_contexts_clear(daemon, verbose)==-1)
234 /* Free applications */
235 if (dlt_daemon_applications_clear(daemon, verbose)==-1)
240 /* free ringbuffer */
241 dlt_buffer_free_dynamic(&(daemon->client_ringbuffer));
246 int dlt_daemon_applications_invalidate_fd(DltDaemon *daemon,int fd,int verbose)
250 PRINT_FUNCTION_VERBOSE(verbose);
257 for (i=0; i<daemon->num_applications; i++)
259 if (daemon->applications[i].user_handle==fd)
261 daemon->applications[i].user_handle = DLT_FD_INIT;
268 int dlt_daemon_applications_clear(DltDaemon *daemon,int verbose)
272 PRINT_FUNCTION_VERBOSE(verbose);
279 for (i=0; i<daemon->num_applications; i++)
281 if (daemon->applications[i].application_description!=0)
283 free(daemon->applications[i].application_description);
284 daemon->applications[i].application_description = 0;
288 if (daemon->applications)
290 free(daemon->applications);
293 daemon->applications = 0;
294 daemon->num_applications = 0;
299 DltDaemonApplication* dlt_daemon_application_add(DltDaemon *daemon,char *apid,pid_t pid,char *description, int verbose)
301 DltDaemonApplication *application;
302 DltDaemonApplication *old;
305 char filename[DLT_DAEMON_COMMON_TEXTBUFSIZE];
307 if ((daemon==0) || (apid==0) || (apid[0]=='\0'))
309 return (DltDaemonApplication*) 0;
312 if (daemon->applications == 0)
314 daemon->applications = (DltDaemonApplication*) malloc(sizeof(DltDaemonApplication)*DLT_DAEMON_APPL_ALLOC_SIZE);
315 if (daemon->applications==0)
317 return (DltDaemonApplication*) 0;
323 /* Check if application [apid] is already available */
324 application = dlt_daemon_application_find(daemon, apid, verbose);
327 daemon->num_applications += 1;
329 if (daemon->num_applications!=0)
331 if ((daemon->num_applications%DLT_DAEMON_APPL_ALLOC_SIZE)==0)
333 /* allocate memory in steps of DLT_DAEMON_APPL_ALLOC_SIZE, e.g. 100 */
334 old = daemon->applications;
335 daemon->applications = (DltDaemonApplication*) malloc(sizeof(DltDaemonApplication)*
336 ((daemon->num_applications/DLT_DAEMON_APPL_ALLOC_SIZE)+1)*DLT_DAEMON_APPL_ALLOC_SIZE);
337 if (daemon->applications==0)
339 daemon->applications = old;
340 daemon->num_applications -= 1;
341 return (DltDaemonApplication*) 0;
343 memcpy(daemon->applications,old,sizeof(DltDaemonApplication)*daemon->num_applications);
348 application = &(daemon->applications[daemon->num_applications-1]);
350 dlt_set_id(application->apid,apid);
351 application->pid = 0;
352 application->application_description = 0;
353 application->num_contexts = 0;
354 application->user_handle = DLT_FD_INIT;
360 snprintf(str,DLT_DAEMON_COMMON_TEXTBUFSIZE, "Duplicate registration of AppId: %s\n",apid);
361 dlt_log(LOG_ERR, str);
365 /* Store application description and pid of application */
366 if (application->application_description)
368 free(application->application_description);
369 application->application_description=0;
374 application->application_description = malloc(strlen(description)+1);
375 if (application->application_description)
377 strncpy(application->application_description,description,strlen(description));
378 application->application_description[strlen(description)]='\0';
382 if( application->user_handle != DLT_FD_INIT )
384 if( application->pid != pid )
386 if ( close(application->user_handle) < 0 )
388 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 */
389 dlt_log(LOG_ERR, str);
392 application->user_handle = DLT_FD_INIT;
393 application->pid = 0;
397 /* open user pipe only if it is not yet opened */
398 if (application->user_handle==DLT_FD_INIT && pid!=0)
400 snprintf(filename,DLT_DAEMON_COMMON_TEXTBUFSIZE,"%s/dlt%d",DLT_USER_DIR,pid);
402 dlt_user_handle = open(filename, O_WRONLY|O_NONBLOCK);
403 if ( dlt_user_handle < 0 )
405 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 */
406 dlt_log(LOG_ERR, str);
409 /* check if file file descriptor was already used, and make it invalid if it is reused */
410 /* This prevents sending messages to wrong file descriptor */
411 dlt_daemon_applications_invalidate_fd(daemon,dlt_user_handle,verbose);
412 dlt_daemon_contexts_invalidate_fd(daemon,dlt_user_handle,verbose);
414 application->pid = pid;
415 application->user_handle = dlt_user_handle;
421 qsort(daemon->applications,daemon->num_applications,sizeof(DltDaemonApplication),dlt_daemon_cmp_apid);
423 /* Find new position of application with apid*/
424 application = dlt_daemon_application_find(daemon, apid, verbose);
430 int dlt_daemon_application_del(DltDaemon *daemon, DltDaemonApplication *application, int verbose)
434 PRINT_FUNCTION_VERBOSE(verbose);
436 if ((daemon==0) || (application==0))
441 if (daemon->num_applications>0)
443 /* Check if user handle is open; if yes, close it */
444 if (application->user_handle >= DLT_FD_MINIMUM)
446 close(application->user_handle);
447 application->user_handle=DLT_FD_INIT;
450 /* Free description of application to be deleted */
451 if (application->application_description)
453 free(application->application_description);
454 application->application_description = 0;
457 pos = application-(daemon->applications);
459 /* move all applications above pos to pos */
460 memmove(&(daemon->applications[pos]),&(daemon->applications[pos+1]), sizeof(DltDaemonApplication)*((daemon->num_applications-1)-pos));
462 /* Clear last application */
463 memset(&(daemon->applications[daemon->num_applications-1]),0,sizeof(DltDaemonApplication));
465 daemon->num_applications--;
472 DltDaemonApplication* dlt_daemon_application_find(DltDaemon *daemon,char *apid,int verbose)
474 DltDaemonApplication application;
476 PRINT_FUNCTION_VERBOSE(verbose);
478 if ((daemon==0) || (apid==0) || (apid[0]=='\0') || (daemon->num_applications==0))
480 return (DltDaemonApplication*) 0;
483 /* Check, if apid is smaller than smallest apid or greater than greatest apid */
484 if ((memcmp(apid,daemon->applications[0].apid,DLT_ID_SIZE)<0) ||
485 (memcmp(apid,daemon->applications[daemon->num_applications-1].apid,DLT_ID_SIZE)>0))
487 return (DltDaemonApplication*) 0;
490 dlt_set_id(application.apid,apid);
491 return (DltDaemonApplication*)bsearch(&application,daemon->applications,daemon->num_applications,sizeof(DltDaemonApplication),dlt_daemon_cmp_apid);
494 int dlt_daemon_applications_load(DltDaemon *daemon,const char *filename, int verbose)
498 char buf[DLT_DAEMON_COMMON_TEXTBUFSIZE];
502 PRINT_FUNCTION_VERBOSE(verbose);
504 if ((daemon==0) || (filename==0) || (filename[0]=='\0'))
509 fd=fopen(filename, "r");
513 snprintf(str,DLT_DAEMON_COMMON_TEXTBUFSIZE, "DLT runtime-application load, cannot open file %s: %s\n", filename, strerror(errno));
514 dlt_log(LOG_WARNING, str);
522 memset(buf, 0, sizeof(buf));
525 ret=fgets(buf,sizeof(buf),fd);
528 /* fgets always null pointer if the last byte of the file is a new line
529 * We need to check here if there was an error or was it feof.*/
532 snprintf(str,DLT_DAEMON_COMMON_TEXTBUFSIZE, "dlt_daemon_applications_load fgets(buf,sizeof(buf),fd) returned NULL. %s\n",
534 dlt_log(LOG_ERR, str);
544 snprintf(str,DLT_DAEMON_COMMON_TEXTBUFSIZE, "dlt_daemon_applications_load fgets(buf,sizeof(buf),fd) returned NULL. Unknown error.\n");
545 dlt_log(LOG_ERR, str);
551 if (strcmp(buf,"")!=0)
561 /* pb contains now the description */
562 /* pid is unknown at loading time */
563 if (dlt_daemon_application_add(daemon,apid,0,pb,verbose)==0)
565 dlt_log(LOG_ERR, "dlt_daemon_applications_load dlt_daemon_application_add failed\n");
578 int dlt_daemon_applications_save(DltDaemon *daemon,const char *filename, int verbose)
583 char apid[DLT_ID_SIZE+1]; /* DLT_ID_SIZE+1, because the 0-termination is required here */
585 PRINT_FUNCTION_VERBOSE(verbose);
587 if ((daemon==0) || (filename==0) || (filename[0]=='\0'))
592 memset(apid,0, sizeof(apid));
594 if ((daemon->applications) && (daemon->num_applications>0))
596 fd=fopen(filename, "w");
599 for (i=0; i<daemon->num_applications; i++)
601 dlt_set_id(apid,daemon->applications[i].apid);
603 if ((daemon->applications[i].application_description) &&
604 (daemon->applications[i].application_description!='\0'))
606 fprintf(fd,"%s:%s:\n",apid, daemon->applications[i].application_description);
610 fprintf(fd,"%s::\n",apid);
620 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)
622 DltDaemonApplication *application;
623 DltDaemonContext *context;
624 DltDaemonContext *old;
627 PRINT_FUNCTION_VERBOSE(verbose);
629 if ((daemon==0) || (apid==0) || (apid[0]=='\0') || (ctid==0) || (ctid[0]=='\0'))
631 return (DltDaemonContext*) 0;
634 if ((log_level<DLT_LOG_DEFAULT) || (log_level>DLT_LOG_VERBOSE))
636 return (DltDaemonContext*) 0;
639 if ((trace_status<DLT_TRACE_STATUS_DEFAULT) || (trace_status>DLT_TRACE_STATUS_ON))
641 return (DltDaemonContext*) 0;
644 if (daemon->contexts == 0)
646 daemon->contexts = (DltDaemonContext*) malloc(sizeof(DltDaemonContext)*DLT_DAEMON_CONTEXT_ALLOC_SIZE);
647 if (daemon->contexts==0)
649 return (DltDaemonContext*) 0;
653 /* Check if application [apid] is available */
654 application = dlt_daemon_application_find(daemon, apid, verbose);
657 return (DltDaemonContext*) 0;
660 /* Check if context [apid, ctid] is already available */
661 context = dlt_daemon_context_find(daemon, apid, ctid, verbose);
664 daemon->num_contexts += 1;
666 if (daemon->num_contexts!=0)
668 if ((daemon->num_contexts%DLT_DAEMON_CONTEXT_ALLOC_SIZE)==0)
670 /* allocate memory for context in steps of DLT_DAEMON_CONTEXT_ALLOC_SIZE, e.g 100 */
671 old = daemon->contexts;
672 daemon->contexts = (DltDaemonContext*) malloc(sizeof(DltDaemonContext)*
673 ((daemon->num_contexts/DLT_DAEMON_CONTEXT_ALLOC_SIZE)+1)*DLT_DAEMON_CONTEXT_ALLOC_SIZE);
674 if (daemon->contexts==0)
676 daemon->contexts = old;
677 daemon->num_contexts -= 1;
678 return (DltDaemonContext*) 0;
680 memcpy(daemon->contexts,old,sizeof(DltDaemonContext)*daemon->num_contexts);
685 context = &(daemon->contexts[daemon->num_contexts-1]);
687 dlt_set_id(context->apid,apid);
688 dlt_set_id(context->ctid,ctid);
689 context->context_description = 0;
691 application->num_contexts++;
695 /* Set context description */
696 if (context->context_description)
698 free(context->context_description);
699 context->context_description=0;
704 context->context_description = malloc(strlen(description)+1);
706 if (context->context_description)
708 strncpy(context->context_description,description,strlen(description));
709 context->context_description[strlen(description)]='\0';
713 /* Store log level and trace status,
714 if this is a new context, or
715 if this is an old context and the runtime cfg was not loaded */
717 if ((new_context==1) ||
718 ((new_context==0) && (daemon->runtime_context_cfg_loaded==0)))
720 context->log_level = log_level;
721 context->trace_status = trace_status;
724 context->log_level_pos = log_level_pos;
725 context->user_handle = user_handle;
730 qsort(daemon->contexts,daemon->num_contexts, sizeof(DltDaemonContext),dlt_daemon_cmp_apid_ctid);
732 /* Find new position of context with apid, ctid */
733 context = dlt_daemon_context_find(daemon, apid, ctid, verbose);
739 int dlt_daemon_context_del(DltDaemon *daemon, DltDaemonContext* context, int verbose)
742 DltDaemonApplication *application;
744 PRINT_FUNCTION_VERBOSE(verbose);
746 if ((daemon==0) || (context==0))
751 if (daemon->num_contexts>0)
753 application = dlt_daemon_application_find(daemon, context->apid, verbose);
755 /* Free description of context to be deleted */
756 if (context->context_description)
758 free(context->context_description);
759 context->context_description = 0;
762 pos = context-(daemon->contexts);
764 /* move all contexts above pos to pos */
765 memmove(&(daemon->contexts[pos]),&(daemon->contexts[pos+1]), sizeof(DltDaemonContext)*((daemon->num_contexts-1)-pos));
767 /* Clear last context */
768 memset(&(daemon->contexts[daemon->num_contexts-1]),0,sizeof(DltDaemonContext));
770 daemon->num_contexts--;
772 /* Check if application [apid] is available */
775 application->num_contexts--;
782 DltDaemonContext* dlt_daemon_context_find(DltDaemon *daemon,char *apid,char *ctid,int verbose)
784 DltDaemonContext context;
786 PRINT_FUNCTION_VERBOSE(verbose);
788 if ((daemon==0) || (apid==0) || (apid[0]=='\0') || (ctid==0) || (ctid[0]=='\0') || (daemon->num_contexts==0))
790 return (DltDaemonContext*) 0;
793 /* Check, if apid is smaller than smallest apid or greater than greatest apid */
794 if ((memcmp(apid,daemon->contexts[0].apid,DLT_ID_SIZE)<0) ||
795 (memcmp(apid,daemon->contexts[daemon->num_contexts-1].apid,DLT_ID_SIZE)>0))
797 return (DltDaemonContext*) 0;
800 dlt_set_id(context.apid,apid);
801 dlt_set_id(context.ctid,ctid);
803 return (DltDaemonContext*)bsearch(&context,daemon->contexts,daemon->num_contexts,sizeof(DltDaemonContext),dlt_daemon_cmp_apid_ctid);
806 int dlt_daemon_contexts_invalidate_fd(DltDaemon *daemon,int fd,int verbose)
810 PRINT_FUNCTION_VERBOSE(verbose);
817 for (i=0; i<daemon->num_contexts; i++)
819 if (daemon->contexts[i].user_handle==fd)
821 daemon->contexts[i].user_handle = DLT_FD_INIT;
828 int dlt_daemon_contexts_clear(DltDaemon *daemon,int verbose)
832 PRINT_FUNCTION_VERBOSE(verbose);
839 for (i=0; i<daemon->num_contexts; i++)
841 if (daemon->contexts[i].context_description!=0)
843 free(daemon->contexts[i].context_description);
844 daemon->contexts[i].context_description = 0;
848 if (daemon->contexts)
850 free(daemon->contexts);
853 daemon->contexts = 0;
855 for (i=0; i<daemon->num_applications; i++)
857 daemon->applications[i].num_contexts = 0;
860 daemon->num_contexts = 0;
865 int dlt_daemon_contexts_load(DltDaemon *daemon,const char *filename, int verbose)
869 char buf[DLT_DAEMON_COMMON_TEXTBUFSIZE];
874 PRINT_FUNCTION_VERBOSE(verbose);
876 if ((daemon==0) || (filename==0) ||( filename[0]=='\0'))
881 fd=fopen(filename, "r");
885 snprintf(str,DLT_DAEMON_COMMON_TEXTBUFSIZE, "DLT runtime-context load, cannot open file %s: %s\n", filename, strerror(errno));
886 dlt_log(LOG_WARNING, str);
894 memset(buf, 0, sizeof(buf));
897 ret=fgets(buf,sizeof(buf),fd);
900 /* fgets always returns null pointer if the last byte of the file is a new line.
901 * We need to check here if there was an error or was it feof.*/
904 snprintf(str,DLT_DAEMON_COMMON_TEXTBUFSIZE, "dlt_daemon_contexts_load fgets(buf,sizeof(buf),fd) returned NULL. %s\n",
906 dlt_log(LOG_ERR, str);
916 snprintf(str,DLT_DAEMON_COMMON_TEXTBUFSIZE, "dlt_daemon_contexts_load fgets(buf,sizeof(buf),fd) returned NULL. Unknown error.\n");
917 dlt_log(LOG_ERR, str);
923 if (strcmp(buf,"")!=0)
945 /* pb contains now the description */
947 /* log_level_pos, and user_handle are unknown at loading time */
948 if (dlt_daemon_context_add(daemon,apid,ctid,(int8_t)ll,(int8_t)ts,0,0,pb,verbose)==0)
950 dlt_log(LOG_ERR, "dlt_daemon_contexts_load dlt_daemon_context_add failed\n");
966 int dlt_daemon_contexts_save(DltDaemon *daemon,const char *filename, int verbose)
971 char apid[DLT_ID_SIZE+1], ctid[DLT_ID_SIZE+1]; /* DLT_ID_SIZE+1, because the 0-termination is required here */
973 PRINT_FUNCTION_VERBOSE(verbose);
975 if ((daemon==0) || (filename==0) ||( filename[0]=='\0'))
980 memset(apid,0, sizeof(apid));
981 memset(ctid,0, sizeof(ctid));
983 if ((daemon->contexts) && (daemon->num_contexts>0))
985 fd=fopen(filename, "w");
988 for (i=0; i<daemon->num_contexts; i++)
990 dlt_set_id(apid,daemon->contexts[i].apid);
991 dlt_set_id(ctid,daemon->contexts[i].ctid);
993 if ((daemon->contexts[i].context_description) &&
994 (daemon->contexts[i].context_description[0]!='\0'))
996 fprintf(fd,"%s:%s:%d:%d:%s:\n",apid,ctid,
997 (int)(daemon->contexts[i].log_level),
998 (int)(daemon->contexts[i].trace_status),
999 daemon->contexts[i].context_description);
1003 fprintf(fd,"%s:%s:%d:%d::\n",apid,ctid,
1004 (int)(daemon->contexts[i].log_level),
1005 (int)(daemon->contexts[i].trace_status));
1015 int dlt_daemon_configuration_save(DltDaemon *daemon,const char *filename, int verbose)
1019 PRINT_FUNCTION_VERBOSE(verbose);
1021 if ((daemon==0) || (filename==0) ||( filename[0]=='\0'))
1026 fd=fopen(filename, "w");
1029 fprintf(fd,"# 0 = off, 1 = external, 2 = internal, 3 = both\n");
1030 fprintf(fd,"LoggingMode = %d\n",daemon->mode);
1038 int dlt_daemon_configuration_load(DltDaemon *daemon,const char *filename, int verbose)
1046 PRINT_FUNCTION_VERBOSE(verbose);
1048 pFile = fopen (filename,"r");
1054 /* fetch line from configuration file */
1055 if ( fgets (line , 1024 , pFile) != NULL )
1057 pch = strtok (line," =\r\n");
1063 if(strcmp(pch,"#")==0)
1068 strncpy(token,pch,sizeof(token)-1);
1069 token[sizeof(token)-1]=0;
1073 strncpy(value,pch,sizeof(value)-1);
1074 value[sizeof(value)-1]=0;
1078 pch = strtok (NULL, " =\r\n");
1081 if(token[0] && value[0])
1083 /* parse arguments here */
1084 if(strcmp(token,"LoggingMode")==0)
1086 daemon->mode = atoi(value);
1087 snprintf(str,DLT_DAEMON_COMMON_TEXTBUFSIZE,"Runtime Option: %s=%d\n",token,daemon->mode);
1088 dlt_log(LOG_INFO, str);
1092 snprintf(str,DLT_DAEMON_COMMON_TEXTBUFSIZE,"Unknown option: %s=%s\n",token,value);
1093 dlt_log(LOG_ERR, str);
1106 snprintf(str,DLT_DAEMON_COMMON_TEXTBUFSIZE,"Cannot open configuration file: %s\n",filename);
1107 dlt_log(LOG_WARNING, str);
1113 int dlt_daemon_user_send_log_level(DltDaemon *daemon,DltDaemonContext *context,int verbose)
1115 DltUserHeader userheader;
1116 DltUserControlMsgLogLevel usercontext;
1119 PRINT_FUNCTION_VERBOSE(verbose);
1121 if ((daemon==0) || (context==0))
1126 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG_LEVEL)==-1)
1131 usercontext.log_level = ((context->log_level == DLT_LOG_DEFAULT)?daemon->default_log_level:context->log_level);
1132 usercontext.trace_status = ((context->trace_status == DLT_TRACE_STATUS_DEFAULT)?daemon->default_trace_status:context->trace_status);
1134 usercontext.log_level_pos = context->log_level_pos;
1137 ret = dlt_user_log_out2(context->user_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgLogLevel));
1139 if (ret!=DLT_RETURN_OK)
1143 /* Close connection */
1144 close(context->user_handle);
1145 context->user_handle=DLT_FD_INIT;
1149 return ((ret==DLT_RETURN_OK)?0:-1);
1152 int dlt_daemon_user_send_log_state(DltDaemon *daemon,DltDaemonApplication *app,int verbose)
1154 DltUserHeader userheader;
1155 DltUserControlMsgLogState logstate;
1158 PRINT_FUNCTION_VERBOSE(verbose);
1160 if ((daemon==0) || (app==0))
1165 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG_STATE)==-1)
1170 logstate.log_state = daemon->connectionState;
1173 ret = dlt_user_log_out2(app->user_handle, &(userheader), sizeof(DltUserHeader), &(logstate), sizeof(DltUserControlMsgLogState));
1175 if (ret!=DLT_RETURN_OK)
1179 /* Close connection */
1180 close(app->user_handle);
1181 app->user_handle=DLT_FD_INIT;
1185 return ((ret==DLT_RETURN_OK)?0:-1);
1188 void dlt_daemon_control_reset_to_factory_default(DltDaemon *daemon,const char *filename, const char *filename1, int verbose)
1192 PRINT_FUNCTION_VERBOSE(verbose);
1194 if ((daemon==0) || (filename==0) || (filename1==0) || (filename[0]=='\0') || (filename1[0]=='\0'))
1199 /* Check for runtime cfg file and delete it, if available */
1200 fd=fopen(filename, "r");
1204 /* Close and delete file */
1209 fd=fopen(filename1, "r");
1213 /* Close and delete file */
1218 daemon->default_log_level = DLT_DAEMON_INITIAL_LOG_LEVEL ;
1219 daemon->default_trace_status = DLT_DAEMON_INITIAL_TRACE_STATUS ;
1221 /* Reset all other things (log level, trace status, etc.
1222 to default values */
1224 /* Inform user libraries about changed default log level/trace status */
1225 dlt_daemon_user_send_default_update(daemon, verbose);
1228 void dlt_daemon_user_send_default_update(DltDaemon *daemon, int verbose)
1231 DltDaemonContext *context;
1233 PRINT_FUNCTION_VERBOSE(verbose);
1240 for (count=0;count<daemon->num_contexts; count ++)
1242 context = &(daemon->contexts[count]);
1246 if ((context->log_level == DLT_LOG_DEFAULT) ||
1247 (context->trace_status == DLT_TRACE_STATUS_DEFAULT))
1249 if (context->user_handle >= DLT_FD_MINIMUM)
1251 if (dlt_daemon_user_send_log_level(daemon, context, verbose)==-1)
1261 void dlt_daemon_user_send_all_log_state(DltDaemon *daemon, int verbose)
1264 DltDaemonApplication *app;
1266 PRINT_FUNCTION_VERBOSE(verbose);
1273 for (count=0;count<daemon->num_applications; count ++)
1275 app = &(daemon->applications[count]);
1279 if (app->user_handle >= DLT_FD_MINIMUM)
1281 if (dlt_daemon_user_send_log_state(daemon, app, verbose)==-1)
1290 void dlt_daemon_change_state(DltDaemon *daemon, DltDaemonState newState)
1294 case DLT_DAEMON_STATE_INIT:
1295 dlt_log(LOG_INFO,"Switched to init state.\n");
1296 daemon->state = DLT_DAEMON_STATE_INIT;
1298 case DLT_DAEMON_STATE_BUFFER:
1299 dlt_log(LOG_INFO,"Switched to buffer state.\n");
1300 daemon->state = DLT_DAEMON_STATE_BUFFER;
1302 case DLT_DAEMON_STATE_BUFFER_FULL:
1303 dlt_log(LOG_INFO,"Switched to buffer full state.\n");
1304 daemon->state = DLT_DAEMON_STATE_BUFFER_FULL;
1306 case DLT_DAEMON_STATE_SEND_BUFFER:
1307 dlt_log(LOG_INFO,"Switched to send buffer state.\n");
1308 daemon->state = DLT_DAEMON_STATE_SEND_BUFFER;
1310 case DLT_DAEMON_STATE_SEND_DIRECT:
1311 dlt_log(LOG_INFO,"Switched to send direct state.\n");
1312 daemon->state = DLT_DAEMON_STATE_SEND_DIRECT;