Bug 44 - Don't print "Buffer full" message from DLT daemon for each trace.
[profile/ivi/dlt-daemon.git] / src / daemon / dlt_daemon_common.c
1 /**
2  * @licence app begin@
3  * Copyright (C) 2012  BMW AG
4  *
5  * This file is part of GENIVI Project Dlt - Diagnostic Log and Trace console apps.
6  *
7  * Contributions are licensed to the GENIVI Alliance under one or more
8  * Contribution License Agreements.
9  *
10  * \copyright
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/.
14  *
15  *
16  * \author Alexander Wenzel <alexander.aw.wenzel@bmw.de> BMW 2011-2012
17  *
18  * \file dlt_daemon_common.c
19  * For further information see http://www.genivi.org/.
20  * @licence end@
21  */
22
23 /*******************************************************************************
24 **                                                                            **
25 **  SRC-MODULE: dlt_daemon_common.c                                           **
26 **                                                                            **
27 **  TARGET    : linux                                                         **
28 **                                                                            **
29 **  PROJECT   : DLT                                                           **
30 **                                                                            **
31 **  AUTHOR    : Alexander Wenzel Alexander.AW.Wenzel@bmw.de                   **
32 **              Markus Klein                                                  **
33 **                                                                            **
34 **  PURPOSE   :                                                               **
35 **                                                                            **
36 **  REMARKS   :                                                               **
37 **                                                                            **
38 **  PLATFORM DEPENDANT [yes/no]: yes                                          **
39 **                                                                            **
40 **  TO BE CHANGED BY USER [yes/no]: no                                        **
41 **                                                                            **
42 *******************************************************************************/
43
44 /*******************************************************************************
45 **                      Author Identity                                       **
46 ********************************************************************************
47 **                                                                            **
48 ** Initials     Name                       Company                            **
49 ** --------     -------------------------  ---------------------------------- **
50 **  aw          Alexander Wenzel           BMW                                **
51 **  mk          Markus Klein               Fraunhofer ESK                     **
52 *******************************************************************************/
53
54 /*******************************************************************************
55 **                      Revision Control History                              **
56 *******************************************************************************/
57
58 /*
59  * $LastChangedRevision: 1670 $
60  * $LastChangedDate: 2011-04-08 15:12:06 +0200 (Fr, 08. Apr 2011) $
61  * $LastChangedBy$
62  Initials    Date         Comment
63  aw          13.01.2010   initial
64  */
65
66 #include <stdio.h>
67 #include <stdlib.h>
68 #include <string.h>
69 #include <syslog.h>
70 #include <errno.h>
71 #include <unistd.h>
72 #include <fcntl.h>
73
74 #include <sys/types.h>  /* send() */
75 #include <sys/socket.h> /* send() */
76
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
83 static char str[DLT_DAEMON_COMMON_TEXTBUFSIZE];
84
85 sem_t dlt_daemon_mutex;
86
87 static int dlt_daemon_cmp_apid(const void *m1, const void *m2)
88 {
89     DltDaemonApplication *mi1 = (DltDaemonApplication *) m1;
90     DltDaemonApplication *mi2 = (DltDaemonApplication *) m2;
91
92     return memcmp(mi1->apid, mi2->apid, DLT_ID_SIZE);
93 }
94
95 static int dlt_daemon_cmp_apid_ctid(const void *m1, const void *m2)
96 {
97
98     int ret, cmp;
99     DltDaemonContext *mi1 = (DltDaemonContext *) m1;
100     DltDaemonContext *mi2 = (DltDaemonContext *) m2;
101
102     cmp=memcmp(mi1->apid, mi2->apid, DLT_ID_SIZE);
103     if (cmp<0)
104     {
105         ret=-1;
106     }
107     else if (cmp==0)
108     {
109         ret=memcmp(mi1->ctid, mi2->ctid, DLT_ID_SIZE);
110     }
111     else
112     {
113         ret=1;
114     }
115
116     return ret;
117 }
118
119 int dlt_daemon_init(DltDaemon *daemon,const char *runtime_directory, int verbose)
120 {
121     PRINT_FUNCTION_VERBOSE(verbose);
122
123     if (daemon==0)
124     {
125         return -1;
126     }
127
128     int append_length = 0;
129     daemon->num_contexts = 0;
130     daemon->contexts = 0;
131
132     daemon->num_applications = 0;
133     daemon->applications = 0;
134
135     daemon->default_log_level = DLT_DAEMON_INITIAL_LOG_LEVEL ;
136     daemon->default_trace_status = DLT_DAEMON_INITIAL_TRACE_STATUS ;
137
138     daemon->message_buffer_overflow = DLT_MESSAGE_BUFFER_NO_OVERFLOW;
139     daemon->overflow_counter = 0;
140
141     daemon->runtime_context_cfg_loaded = 0;
142     
143     daemon->mode = DLT_USER_MODE_EXTERNAL;
144
145     /* prepare filenames for configuration */
146
147     append_length = PATH_MAX - sizeof(DLT_RUNTIME_APPLICATION_CFG);
148     if(runtime_directory[0])
149         strncpy(daemon->runtime_application_cfg,runtime_directory,append_length);
150     else
151         strcpy(daemon->runtime_application_cfg,DLT_RUNTIME_DEFAULT_DIRECTORY);
152     strcat(daemon->runtime_application_cfg,DLT_RUNTIME_APPLICATION_CFG);
153
154     append_length = PATH_MAX - sizeof(DLT_RUNTIME_CONTEXT_CFG);
155     if(runtime_directory[0])
156         strncpy(daemon->runtime_context_cfg,runtime_directory,append_length);
157     else
158         strcpy(daemon->runtime_context_cfg,DLT_RUNTIME_DEFAULT_DIRECTORY);
159     strcat(daemon->runtime_context_cfg,DLT_RUNTIME_CONTEXT_CFG);
160
161     append_length = PATH_MAX - sizeof(DLT_RUNTIME_CONFIGURATION);
162     if(runtime_directory[0])    
163         strncpy(daemon->runtime_configuration,runtime_directory,append_length);
164     else
165         strcpy(daemon->runtime_configuration,DLT_RUNTIME_DEFAULT_DIRECTORY);
166     strcat(daemon->runtime_configuration,DLT_RUNTIME_CONFIGURATION);
167
168     /* Check for runtime cfg, if it is loadable, load it! */
169     if ((dlt_daemon_applications_load(daemon,daemon->runtime_application_cfg, verbose)==0) &&
170             (dlt_daemon_contexts_load(daemon,daemon->runtime_context_cfg, verbose)==0))
171     {
172         daemon->runtime_context_cfg_loaded = 1;
173     }
174     
175     /* load configuration if available */
176     dlt_daemon_configuration_load(daemon,daemon->runtime_configuration, verbose);
177     
178     daemon->sendserialheader = 0;
179     daemon->timingpackets = 0;
180
181     dlt_set_id(daemon->ecuid,"");
182
183     /* initialize ring buffer for client connection */
184     if (dlt_buffer_init_dynamic(&(daemon->client_ringbuffer), DLT_DAEMON_RINGBUFFER_MIN_SIZE,DLT_DAEMON_RINGBUFFER_MAX_SIZE,DLT_DAEMON_RINGBUFFER_STEP_SIZE)==-1)
185     {
186         return -1;
187     }
188
189     return 0;
190 }
191
192 int dlt_daemon_free(DltDaemon *daemon,int verbose)
193 {
194     PRINT_FUNCTION_VERBOSE(verbose);
195
196     if (daemon==0)
197     {
198         return -1;
199     }
200
201     /* Free contexts */
202     if (dlt_daemon_contexts_clear(daemon, verbose)==-1)
203     {
204                 return -1;
205     }
206
207     /* Free applications */
208     if (dlt_daemon_applications_clear(daemon, verbose)==-1)
209         {
210                 return -1;
211     }
212
213         /* free ringbuffer */
214         dlt_buffer_free_dynamic(&(daemon->client_ringbuffer));
215
216     return 0;
217 }
218
219 int dlt_daemon_applications_invalidate_fd(DltDaemon *daemon,int fd,int verbose)
220 {
221     int i;
222
223     PRINT_FUNCTION_VERBOSE(verbose);
224
225     if (daemon==0)
226     {
227         return -1;
228     }
229
230     for (i=0; i<daemon->num_applications; i++)
231     {
232         if (daemon->applications[i].user_handle==fd)
233         {
234                 daemon->applications[i].user_handle = DLT_FD_INIT;
235         }
236     }
237
238     return 0;
239 }
240
241 int dlt_daemon_applications_clear(DltDaemon *daemon,int verbose)
242 {
243     int i;
244
245     PRINT_FUNCTION_VERBOSE(verbose);
246
247     if (daemon==0)
248     {
249         return -1;
250     }
251
252     for (i=0; i<daemon->num_applications; i++)
253     {
254         if (daemon->applications[i].application_description!=0)
255         {
256             free(daemon->applications[i].application_description);
257             daemon->applications[i].application_description = 0;
258         }
259     }
260
261     if (daemon->applications)
262     {
263         free(daemon->applications);
264     }
265
266     daemon->applications = 0;
267     daemon->num_applications = 0;
268
269     return 0;
270 }
271
272 DltDaemonApplication* dlt_daemon_application_add(DltDaemon *daemon,char *apid,pid_t pid,char *description, int verbose)
273 {
274     DltDaemonApplication *application;
275         DltDaemonApplication *old;
276     int new_application;
277     int dlt_user_handle;
278         char filename[DLT_DAEMON_COMMON_TEXTBUFSIZE];
279
280     if ((daemon==0) || (apid==0) || (apid[0]=='\0'))
281     {
282         return (DltDaemonApplication*) 0;
283     }
284
285     if (daemon->applications == 0)
286     {
287         daemon->applications = (DltDaemonApplication*) malloc(sizeof(DltDaemonApplication)*DLT_DAEMON_APPL_ALLOC_SIZE);
288         if (daemon->applications==0)
289         {
290                 return (DltDaemonApplication*) 0;
291         }
292     }
293
294     new_application=0;
295
296     /* Check if application [apid] is already available */
297     application = dlt_daemon_application_find(daemon, apid, verbose);
298     if (application==0)
299     {
300         daemon->num_applications += 1;
301
302         if (daemon->num_applications!=0)
303         {
304             if ((daemon->num_applications%DLT_DAEMON_APPL_ALLOC_SIZE)==0)
305             {
306                 /* allocate memory in steps of DLT_DAEMON_APPL_ALLOC_SIZE, e.g. 100 */
307                 old = daemon->applications;
308                 daemon->applications = (DltDaemonApplication*) malloc(sizeof(DltDaemonApplication)*
309                                        ((daemon->num_applications/DLT_DAEMON_APPL_ALLOC_SIZE)+1)*DLT_DAEMON_APPL_ALLOC_SIZE);
310                                 if (daemon->applications==0)
311                                 {
312                                         daemon->applications = old;
313                                         daemon->num_applications -= 1;
314                                         return (DltDaemonApplication*) 0;
315                                 }
316                 memcpy(daemon->applications,old,sizeof(DltDaemonApplication)*daemon->num_applications);
317                 free(old);
318             }
319         }
320
321         application = &(daemon->applications[daemon->num_applications-1]);
322
323         dlt_set_id(application->apid,apid);
324         application->pid = 0;
325         application->application_description = 0;
326         application->num_contexts = 0;
327         application->user_handle = DLT_FD_INIT;
328
329         new_application = 1;
330
331     } else {
332
333                 snprintf(str,DLT_DAEMON_COMMON_TEXTBUFSIZE, "Duplicate registration of AppId: %s\n",apid);
334                 dlt_log(LOG_ERR, str);
335
336     }
337
338     /* Store application description and pid of application */
339     if (application->application_description)
340     {
341         free(application->application_description);
342         application->application_description=0;
343     }
344
345     if (description)
346     {
347         application->application_description = malloc(strlen(description)+1);
348         if (application->application_description)
349         {
350             strncpy(application->application_description,description,strlen(description)+1);
351             application->application_description[strlen(description)]='\0';
352         }
353     }
354
355     if( application->user_handle != DLT_FD_INIT )
356     {
357         if( application->pid != pid )
358         {
359                 if ( close(application->user_handle) < 0 )
360                 {
361                         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 */
362                     dlt_log(LOG_ERR, str);
363                 }
364
365                 application->user_handle = DLT_FD_INIT;
366                 application->pid = 0;
367         }
368     }
369
370     /* open user pipe only if it is not yet opened */
371     if (application->user_handle==DLT_FD_INIT && pid!=0)
372     {
373         sprintf(filename,"%s/dlt%d",DLT_USER_DIR,pid);
374
375         dlt_user_handle = open(filename, O_WRONLY|O_NONBLOCK);
376         if ( dlt_user_handle < 0 )
377         {
378             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 */
379             dlt_log(LOG_ERR, str);
380         } /* if */
381
382         /* check if file file descriptor was already used, and make it invalid if it is reused */
383         /* This prevents sending messages to wrong file descriptor */
384         dlt_daemon_applications_invalidate_fd(daemon,dlt_user_handle,verbose);
385         dlt_daemon_contexts_invalidate_fd(daemon,dlt_user_handle,verbose);
386
387         application->pid = pid;
388         application->user_handle = dlt_user_handle;
389     }
390
391     /* Sort */
392     if (new_application)
393     {
394         qsort(daemon->applications,daemon->num_applications,sizeof(DltDaemonApplication),dlt_daemon_cmp_apid);
395
396         /* Find new position of application with apid*/
397         application = dlt_daemon_application_find(daemon, apid, verbose);
398     }
399
400     return application;
401 }
402
403 int dlt_daemon_application_del(DltDaemon *daemon, DltDaemonApplication *application, int verbose)
404 {
405     int pos;
406
407     PRINT_FUNCTION_VERBOSE(verbose);
408
409     if ((daemon==0) || (application==0))
410     {
411         return -1;
412     }
413
414     if (daemon->num_applications>0)
415     {
416         /* Check if user handle is open; if yes, close it */
417         if (application->user_handle >= DLT_FD_MINIMUM)
418         {
419             close(application->user_handle);
420             application->user_handle=DLT_FD_INIT;
421         }
422
423         /* Free description of application to be deleted */
424         if (application->application_description)
425         {
426             free(application->application_description);
427             application->application_description = 0;
428         }
429
430         pos = application-(daemon->applications);
431
432         /* move all applications above pos to pos */
433         memmove(&(daemon->applications[pos]),&(daemon->applications[pos+1]), sizeof(DltDaemonApplication)*((daemon->num_applications-1)-pos));
434
435         /* Clear last application */
436         memset(&(daemon->applications[daemon->num_applications-1]),0,sizeof(DltDaemonApplication));
437
438         daemon->num_applications--;
439
440     }
441
442     return 0;
443 }
444
445 DltDaemonApplication* dlt_daemon_application_find(DltDaemon *daemon,char *apid,int verbose)
446 {
447     DltDaemonApplication application;
448
449     PRINT_FUNCTION_VERBOSE(verbose);
450
451     if ((daemon==0) || (apid==0) || (apid[0]=='\0') || (daemon->num_applications==0))
452     {
453         return (DltDaemonApplication*) 0;
454     }
455
456     /* Check, if apid is smaller than smallest apid or greater than greatest apid */
457     if ((memcmp(apid,daemon->applications[0].apid,DLT_ID_SIZE)<0) ||
458             (memcmp(apid,daemon->applications[daemon->num_applications-1].apid,DLT_ID_SIZE)>0))
459     {
460         return (DltDaemonApplication*) 0;
461     }
462
463     dlt_set_id(application.apid,apid);
464     return (DltDaemonApplication*)bsearch(&application,daemon->applications,daemon->num_applications,sizeof(DltDaemonApplication),dlt_daemon_cmp_apid);
465 }
466
467 int dlt_daemon_applications_load(DltDaemon *daemon,const char *filename, int verbose)
468 {
469     FILE *fd;
470     ID4 apid;
471     char buf[DLT_DAEMON_COMMON_TEXTBUFSIZE];
472     char *ret;
473     char *pb;
474
475     PRINT_FUNCTION_VERBOSE(verbose);
476
477     if ((daemon==0) || (filename==0) || (filename[0]=='\0'))
478     {
479         return -1;
480     }
481
482     fd=fopen(filename, "r");
483
484     if (fd==0)
485     {
486         return -1;
487     }
488
489     while (!feof(fd))
490     {
491         /* Clear buf */
492         memset(buf, 0, sizeof(buf));
493
494         /* Get line */
495         ret=fgets(buf,sizeof(buf),fd);
496         if (NULL == ret)
497         {
498             /* fgets always null pointer if the last byte of the file is a new line
499              * We need to check here if there was an error or was it feof.*/
500             if(ferror(fd))
501             {
502                 snprintf(str,DLT_DAEMON_COMMON_TEXTBUFSIZE, "dlt_daemon_applications_load fgets(buf,sizeof(buf),fd) returned NULL. %s\n",
503                          strerror(errno));
504                 dlt_log(LOG_ERR, str);
505                 fclose(fd);
506                 return -1;
507             }
508             else if(feof(fd))
509             {
510                 fclose(fd);
511                 return 0;
512             }
513             else {
514                 snprintf(str,DLT_DAEMON_COMMON_TEXTBUFSIZE, "dlt_daemon_applications_load fgets(buf,sizeof(buf),fd) returned NULL. Unknown error.\n");
515                 dlt_log(LOG_ERR, str);
516                 fclose(fd);
517                 return -1;
518             }
519         }
520
521         if (strcmp(buf,"")!=0)
522         {
523             /* Split line */
524             pb=strtok(buf,":");
525             dlt_set_id(apid,pb);
526             pb=strtok(NULL,":");
527             /* pb contains now the description */
528
529             /* pid is unknown at loading time */
530             if (dlt_daemon_application_add(daemon,apid,0,pb,verbose)==0)
531             {
532                 fclose(fd);
533                 return -1;
534             }
535         }
536     }
537     fclose(fd);
538
539     return 0;
540 }
541
542 int dlt_daemon_applications_save(DltDaemon *daemon,const char *filename, int verbose)
543 {
544     FILE *fd;
545     int i;
546
547     char apid[DLT_ID_SIZE+1]; /* DLT_ID_SIZE+1, because the 0-termination is required here */
548
549     PRINT_FUNCTION_VERBOSE(verbose);
550
551     if ((daemon==0) || (filename==0) || (filename[0]=='\0'))
552     {
553         return -1;
554     }
555
556     memset(apid,0, sizeof(apid));
557
558     if ((daemon->applications) && (daemon->num_applications>0))
559     {
560         fd=fopen(filename, "w");
561         if (fd!=0)
562         {
563             for (i=0; i<daemon->num_applications; i++)
564             {
565                 dlt_set_id(apid,daemon->applications[i].apid);
566
567                 if ((daemon->applications[i].application_description) &&
568                         (daemon->applications[i].application_description!='\0'))
569                 {
570                     fprintf(fd,"%s:%s:\n",apid, daemon->applications[i].application_description);
571                 }
572                 else
573                 {
574                     fprintf(fd,"%s::\n",apid);
575                 }
576             }
577             fclose(fd);
578         }
579     }
580
581     return 0;
582 }
583
584 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 {
586     DltDaemonApplication *application;
587     DltDaemonContext *context;
588     DltDaemonContext *old;
589     int new_context=0;
590
591     PRINT_FUNCTION_VERBOSE(verbose);
592
593     if ((daemon==0) || (apid==0) || (apid[0]=='\0') || (ctid==0) || (ctid[0]=='\0'))
594     {
595         return (DltDaemonContext*) 0;
596     }
597
598     if ((log_level<DLT_LOG_DEFAULT) || (log_level>DLT_LOG_VERBOSE))
599     {
600         return (DltDaemonContext*) 0;
601     }
602
603     if ((trace_status<DLT_TRACE_STATUS_DEFAULT) || (trace_status>DLT_TRACE_STATUS_ON))
604     {
605         return (DltDaemonContext*) 0;
606     }
607
608     if (daemon->contexts == 0)
609     {
610         daemon->contexts = (DltDaemonContext*) malloc(sizeof(DltDaemonContext)*DLT_DAEMON_CONTEXT_ALLOC_SIZE);
611         if (daemon->contexts==0)
612         {
613                         return (DltDaemonContext*) 0;
614         }
615     }
616
617     /* Check if application [apid] is available */
618     application = dlt_daemon_application_find(daemon, apid, verbose);
619     if (application==0)
620     {
621         return (DltDaemonContext*) 0;
622     }
623
624     /* Check if context [apid, ctid] is already available */
625     context = dlt_daemon_context_find(daemon, apid, ctid, verbose);
626     if (context==0)
627     {
628         daemon->num_contexts += 1;
629
630         if (daemon->num_contexts!=0)
631         {
632             if ((daemon->num_contexts%DLT_DAEMON_CONTEXT_ALLOC_SIZE)==0)
633             {
634                 /* allocate memory for context in steps of DLT_DAEMON_CONTEXT_ALLOC_SIZE, e.g 100 */
635                 old = daemon->contexts;
636                 daemon->contexts = (DltDaemonContext*) malloc(sizeof(DltDaemonContext)*
637                                    ((daemon->num_contexts/DLT_DAEMON_CONTEXT_ALLOC_SIZE)+1)*DLT_DAEMON_CONTEXT_ALLOC_SIZE);
638                                 if (daemon->contexts==0)
639                                 {
640                                         daemon->contexts = old;
641                                         daemon->num_contexts -= 1;
642                                         return (DltDaemonContext*) 0;
643                                 }
644                 memcpy(daemon->contexts,old,sizeof(DltDaemonContext)*daemon->num_contexts);
645                 free(old);
646             }
647         }
648
649         context = &(daemon->contexts[daemon->num_contexts-1]);
650
651         dlt_set_id(context->apid,apid);
652         dlt_set_id(context->ctid,ctid);
653         context->context_description = 0;
654
655         application->num_contexts++;
656         new_context =1;
657     }
658
659     /* Set context description */
660     if (context->context_description)
661     {
662         free(context->context_description);
663         context->context_description=0;
664     }
665
666     if (description)
667     {
668         context->context_description = malloc(strlen(description)+1);
669
670         if (context->context_description)
671         {
672             strncpy(context->context_description,description,strlen(description)+1);
673             context->context_description[strlen(description)]='\0';
674         }
675     }
676
677     /* Store log level and trace status,
678        if this is a new context, or
679        if this is an old context and the runtime cfg was not loaded */
680
681     if ((new_context==1) ||
682             ((new_context==0) && (daemon->runtime_context_cfg_loaded==0)))
683     {
684         context->log_level = log_level;
685         context->trace_status = trace_status;
686     }
687
688     context->log_level_pos = log_level_pos;
689     context->user_handle = user_handle;
690
691     /* Sort */
692     if (new_context)
693     {
694         qsort(daemon->contexts,daemon->num_contexts, sizeof(DltDaemonContext),dlt_daemon_cmp_apid_ctid);
695
696         /* Find new position of context with apid, ctid */
697         context = dlt_daemon_context_find(daemon, apid, ctid, verbose);
698     }
699
700     return context;
701 }
702
703 int dlt_daemon_context_del(DltDaemon *daemon, DltDaemonContext* context, int verbose)
704 {
705     int pos;
706     DltDaemonApplication *application;
707
708     PRINT_FUNCTION_VERBOSE(verbose);
709
710     if ((daemon==0) || (context==0))
711     {
712         return -1;
713     }
714
715     if (daemon->num_contexts>0)
716     {
717         application = dlt_daemon_application_find(daemon, context->apid, verbose);
718
719         /* Free description of context to be deleted */
720         if (context->context_description)
721         {
722             free(context->context_description);
723             context->context_description = 0;
724         }
725
726         pos = context-(daemon->contexts);
727
728         /* move all contexts above pos to pos */
729         memmove(&(daemon->contexts[pos]),&(daemon->contexts[pos+1]), sizeof(DltDaemonContext)*((daemon->num_contexts-1)-pos));
730
731         /* Clear last context */
732         memset(&(daemon->contexts[daemon->num_contexts-1]),0,sizeof(DltDaemonContext));
733
734         daemon->num_contexts--;
735
736         /* Check if application [apid] is available */
737         if (application)
738         {
739             application->num_contexts--;
740         }
741     }
742
743     return 0;
744 }
745
746 DltDaemonContext* dlt_daemon_context_find(DltDaemon *daemon,char *apid,char *ctid,int verbose)
747 {
748     DltDaemonContext context;
749
750     PRINT_FUNCTION_VERBOSE(verbose);
751
752     if ((daemon==0) || (apid==0) || (apid[0]=='\0') || (ctid==0) || (ctid[0]=='\0') || (daemon->num_contexts==0))
753     {
754         return (DltDaemonContext*) 0;
755     }
756
757     /* Check, if apid is smaller than smallest apid or greater than greatest apid */
758     if ((memcmp(apid,daemon->contexts[0].apid,DLT_ID_SIZE)<0) ||
759             (memcmp(apid,daemon->contexts[daemon->num_contexts-1].apid,DLT_ID_SIZE)>0))
760     {
761         return (DltDaemonContext*) 0;
762     }
763
764     dlt_set_id(context.apid,apid);
765     dlt_set_id(context.ctid,ctid);
766
767     return (DltDaemonContext*)bsearch(&context,daemon->contexts,daemon->num_contexts,sizeof(DltDaemonContext),dlt_daemon_cmp_apid_ctid);
768 }
769
770 int dlt_daemon_contexts_invalidate_fd(DltDaemon *daemon,int fd,int verbose)
771 {
772     int i;
773
774     PRINT_FUNCTION_VERBOSE(verbose);
775
776     if (daemon==0)
777     {
778         return -1;
779     }
780
781     for (i=0; i<daemon->num_contexts; i++)
782     {
783         if (daemon->contexts[i].user_handle==fd)
784         {
785                 daemon->contexts[i].user_handle = DLT_FD_INIT;
786         }
787     }
788
789     return 0;
790 }
791
792 int dlt_daemon_contexts_clear(DltDaemon *daemon,int verbose)
793 {
794     int i;
795
796     PRINT_FUNCTION_VERBOSE(verbose);
797
798     if (daemon==0)
799     {
800         return -1;
801     }
802
803     for (i=0; i<daemon->num_contexts; i++)
804     {
805         if (daemon->contexts[i].context_description!=0)
806         {
807             free(daemon->contexts[i].context_description);
808             daemon->contexts[i].context_description = 0;
809         }
810     }
811
812     if (daemon->contexts)
813     {
814         free(daemon->contexts);
815     }
816
817     daemon->contexts = 0;
818
819     for (i=0; i<daemon->num_applications; i++)
820     {
821         daemon->applications[i].num_contexts = 0;
822     }
823
824     daemon->num_contexts = 0;
825
826     return 0;
827 }
828
829 int dlt_daemon_contexts_load(DltDaemon *daemon,const char *filename, int verbose)
830 {
831     FILE *fd;
832     ID4 apid, ctid;
833     char buf[DLT_DAEMON_COMMON_TEXTBUFSIZE];
834     char *ret;
835     char *pb;
836     int ll, ts;
837
838     PRINT_FUNCTION_VERBOSE(verbose);
839
840     if ((daemon==0) || (filename==0) ||( filename[0]=='\0'))
841     {
842         return -1;
843     }
844
845     fd=fopen(filename, "r");
846
847     if (fd==0)
848     {
849         return -1;
850     }
851
852     while (!feof(fd))
853     {
854         /* Clear buf */
855         memset(buf, 0, sizeof(buf));
856
857         /* Get line */
858         ret=fgets(buf,sizeof(buf),fd);
859         if (NULL == ret)
860         {
861             /* fgets always returns null pointer if the last byte of the file is a new line.
862              * We need to check here if there was an error or was it feof.*/
863             if(ferror(fd))
864             {
865                 snprintf(str,DLT_DAEMON_COMMON_TEXTBUFSIZE, "dlt_daemon_contexts_load fgets(buf,sizeof(buf),fd) returned NULL. %s\n",
866                          strerror(errno));
867                 dlt_log(LOG_ERR, str);
868                 fclose(fd);
869                 return -1;
870             }
871             else if(feof(fd))
872             {
873                 fclose(fd);
874                 return 0;
875             }
876             else {
877                 snprintf(str,DLT_DAEMON_COMMON_TEXTBUFSIZE, "dlt_daemon_contexts_load fgets(buf,sizeof(buf),fd) returned NULL. Unknown error.\n");
878                 dlt_log(LOG_ERR, str);
879                 fclose(fd);
880                 return -1;
881             }
882         }
883
884         if (strcmp(buf,"")!=0)
885         {
886             /* Split line */
887             pb=strtok(buf,":");
888             dlt_set_id(apid,pb);
889             pb=strtok(NULL,":");
890             dlt_set_id(ctid,pb);
891             pb=strtok(NULL,":");
892             sscanf(pb,"%d",&ll);
893             pb=strtok(NULL,":");
894             sscanf(pb,"%d",&ts);
895             pb=strtok(NULL,":");
896             /* pb contains now the description */
897
898             /* log_level_pos, and user_handle are unknown at loading time */
899             if (dlt_daemon_context_add(daemon,apid,ctid,(int8_t)ll,(int8_t)ts,0,0,pb,verbose)==0)
900             {
901                                 fclose(fd);
902                                 return -1;
903             }
904         }
905     }
906     fclose(fd);
907
908     return 0;
909 }
910
911 int dlt_daemon_contexts_save(DltDaemon *daemon,const char *filename, int verbose)
912 {
913     FILE *fd;
914     int i;
915
916     char apid[DLT_ID_SIZE+1], ctid[DLT_ID_SIZE+1]; /* DLT_ID_SIZE+1, because the 0-termination is required here */
917
918     PRINT_FUNCTION_VERBOSE(verbose);
919
920     if ((daemon==0) || (filename==0) ||( filename[0]=='\0'))
921     {
922         return -1;
923     }
924
925     memset(apid,0, sizeof(apid));
926     memset(ctid,0, sizeof(ctid));
927
928     if ((daemon->contexts) && (daemon->num_contexts>0))
929     {
930         fd=fopen(filename, "w");
931         if (fd!=0)
932         {
933             for (i=0; i<daemon->num_contexts; i++)
934             {
935                 dlt_set_id(apid,daemon->contexts[i].apid);
936                 dlt_set_id(ctid,daemon->contexts[i].ctid);
937
938                 if ((daemon->contexts[i].context_description) &&
939                         (daemon->contexts[i].context_description[0]!='\0'))
940                 {
941                     fprintf(fd,"%s:%s:%d:%d:%s:\n",apid,ctid,
942                             (int)(daemon->contexts[i].log_level),
943                             (int)(daemon->contexts[i].trace_status),
944                             daemon->contexts[i].context_description);
945                 }
946                 else
947                 {
948                     fprintf(fd,"%s:%s:%d:%d::\n",apid,ctid,
949                             (int)(daemon->contexts[i].log_level),
950                             (int)(daemon->contexts[i].trace_status));
951                 }
952             }
953             fclose(fd);
954         }
955     }
956
957     return 0;
958 }
959
960 int dlt_daemon_configuration_save(DltDaemon *daemon,const char *filename, int verbose)
961 {
962     FILE *fd;
963
964     PRINT_FUNCTION_VERBOSE(verbose);
965
966     if ((daemon==0) || (filename==0) ||( filename[0]=='\0'))
967     {
968         return -1;
969     }
970
971         fd=fopen(filename, "w");
972         if (fd!=0)
973         {
974                 fprintf(fd,"# 0 = off, 1 = external, 2 = internal, 3 = both\n");
975                 fprintf(fd,"LoggingMode = %d\n",daemon->mode);
976
977                 fclose(fd);
978         }
979
980     return 0;
981 }
982
983 int dlt_daemon_configuration_load(DltDaemon *daemon,const char *filename, int verbose)
984 {
985         FILE * pFile;
986         char line[1024];
987         char token[1024];
988         char value[1024];
989     char *pch;
990
991     PRINT_FUNCTION_VERBOSE(verbose);
992
993         pFile = fopen (filename,"r");
994
995         if (pFile!=NULL)
996         {
997                 while(1)
998                 {
999                         /* fetch line from configuration file */
1000                         if ( fgets (line , 1024 , pFile) != NULL )
1001                         {
1002                                   pch = strtok (line," =\r\n");
1003                                   token[0]=0;
1004                                   value[0]=0;
1005                                   
1006                                   while (pch != NULL)
1007                                   {
1008                                         if(strcmp(pch,"#")==0)
1009                                                 break;
1010
1011                                         if(token[0]==0)
1012                                         {
1013                                                 strncpy(token,pch,sizeof(token));
1014                                         }
1015                                         else
1016                                         {
1017                                                 strncpy(value,pch,sizeof(value));
1018                                                 break;
1019                                         }
1020
1021                                         pch = strtok (NULL, " =\r\n");
1022                                   }
1023                                   
1024                                   if(token[0] && value[0])
1025                                   {
1026                                                 /* parse arguments here */
1027                                                 if(strcmp(token,"LoggingMode")==0)
1028                                                 {
1029                                                         daemon->mode = atoi(value);
1030                                                         sprintf(str,"Runtime Option: %s=%d\n",token,daemon->mode);
1031                                                         dlt_log(LOG_INFO, str);
1032                                                 }
1033                                                 else
1034                                                 {
1035                                                         sprintf(str,"Unknown option: %s=%s\n",token,value);
1036                                                         dlt_log(LOG_ERR, str);
1037                                                 }
1038                                         }
1039                         }
1040                         else
1041                         {
1042                                 break;
1043                         }
1044                 }
1045                 fclose (pFile);
1046         }
1047         else
1048         {
1049         sprintf(str,"Cannot open configuration file: %s\n",filename);
1050         dlt_log(LOG_WARNING, str);
1051         }       
1052         
1053     return 0;
1054 }
1055
1056 int dlt_daemon_user_send_log_level(DltDaemon *daemon,DltDaemonContext *context,int verbose)
1057 {
1058     DltUserHeader userheader;
1059     DltUserControlMsgLogLevel usercontext;
1060     DltReturnValue ret;
1061
1062     PRINT_FUNCTION_VERBOSE(verbose);
1063
1064     if ((daemon==0) || (context==0))
1065     {
1066         return -1;
1067     }
1068
1069     if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG_LEVEL)==-1)
1070     {
1071         return -1;
1072     }
1073
1074     usercontext.log_level = ((context->log_level == DLT_LOG_DEFAULT)?daemon->default_log_level:context->log_level);
1075     usercontext.trace_status = ((context->trace_status == DLT_TRACE_STATUS_DEFAULT)?daemon->default_trace_status:context->trace_status);
1076
1077     usercontext.log_level_pos = context->log_level_pos;
1078
1079     /* log to FIFO */
1080     ret = dlt_user_log_out2(context->user_handle, &(userheader), sizeof(DltUserHeader),  &(usercontext), sizeof(DltUserControlMsgLogLevel));
1081
1082     if (ret!=DLT_RETURN_OK)
1083     {
1084         if (errno==EPIPE)
1085         {
1086             /* Close connection */
1087             close(context->user_handle);
1088             context->user_handle=DLT_FD_INIT;
1089         }
1090     }
1091
1092     return ((ret==DLT_RETURN_OK)?0:-1);
1093 }
1094
1095 int dlt_daemon_user_send_log_state(DltDaemon *daemon,DltDaemonApplication *app,int verbose)
1096 {
1097     DltUserHeader userheader;
1098     DltUserControlMsgLogState logstate;
1099     DltReturnValue ret;
1100
1101     PRINT_FUNCTION_VERBOSE(verbose);
1102
1103     if ((daemon==0) || (app==0))
1104     {
1105         return -1;
1106     }
1107
1108     if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG_STATE)==-1)
1109     {
1110         return -1;
1111     }
1112
1113     logstate.log_state = daemon->state;
1114
1115     /* log to FIFO */
1116     ret = dlt_user_log_out2(app->user_handle, &(userheader), sizeof(DltUserHeader),  &(logstate), sizeof(DltUserControlMsgLogState));
1117
1118     if (ret!=DLT_RETURN_OK)
1119     {
1120         if (errno==EPIPE)
1121         {
1122             /* Close connection */
1123             close(app->user_handle);
1124             app->user_handle=DLT_FD_INIT;
1125         }
1126     }
1127
1128     return ((ret==DLT_RETURN_OK)?0:-1);
1129 }
1130
1131 int dlt_daemon_control_process_control(int sock, DltDaemon *daemon, DltMessage *msg, int verbose)
1132 {
1133     uint32_t id,id_tmp=0;
1134
1135     PRINT_FUNCTION_VERBOSE(verbose);
1136
1137     if ((daemon==0) || (msg==0))
1138     {
1139         return -1;
1140     }
1141
1142     if (msg->datasize < (int32_t)sizeof(uint32_t))
1143     {
1144         return -1;
1145     }
1146
1147     id_tmp = *((uint32_t*)(msg->databuffer));
1148     id=DLT_ENDIAN_GET_32(msg->standardheader->htyp ,id_tmp);
1149
1150     if ((id > 0) && (id <= DLT_SERVICE_ID_MESSAGE_BUFFER_OVERFLOW))
1151     {
1152         /* Control message handling */
1153         switch (id)
1154         {
1155         case DLT_SERVICE_ID_SET_LOG_LEVEL:
1156         {
1157             dlt_daemon_control_set_log_level(sock, daemon, msg,  verbose);
1158             break;
1159         }
1160         case DLT_SERVICE_ID_SET_TRACE_STATUS:
1161         {
1162             dlt_daemon_control_set_trace_status(sock, daemon, msg,  verbose);
1163             break;
1164         }
1165         case DLT_SERVICE_ID_GET_LOG_INFO:
1166         {
1167             dlt_daemon_control_get_log_info(sock, daemon, msg, verbose);
1168             break;
1169         }
1170         case DLT_SERVICE_ID_GET_DEFAULT_LOG_LEVEL:
1171         {
1172             dlt_daemon_control_get_default_log_level(sock, daemon,  verbose);
1173             break;
1174         }
1175         case DLT_SERVICE_ID_STORE_CONFIG:
1176         {
1177             if (dlt_daemon_applications_save(daemon, daemon->runtime_application_cfg, verbose)==0)
1178             {
1179                                 if (dlt_daemon_contexts_save(daemon, daemon->runtime_context_cfg, verbose)==0)
1180                                 {
1181                                         dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_OK,  verbose);
1182                                 }
1183                                 else
1184                                 {
1185                                         /* Delete saved files */
1186                                         dlt_daemon_control_reset_to_factory_default(daemon, daemon->runtime_application_cfg, daemon->runtime_context_cfg, verbose);
1187                                         dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR,  verbose);
1188                                 }
1189             }
1190             else
1191             {
1192                 dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR,  verbose);
1193             }
1194             break;
1195         }
1196         case DLT_SERVICE_ID_RESET_TO_FACTORY_DEFAULT:
1197         {
1198             dlt_daemon_control_reset_to_factory_default(daemon, daemon->runtime_application_cfg, daemon->runtime_context_cfg, verbose);
1199             dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_OK,  verbose);
1200             break;
1201         }
1202         case DLT_SERVICE_ID_SET_COM_INTERFACE_STATUS:
1203         {
1204             dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED,  verbose);
1205             break;
1206         }
1207         case DLT_SERVICE_ID_SET_COM_INTERFACE_MAX_BANDWIDTH:
1208         {
1209             dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED,  verbose);
1210             break;
1211         }
1212         case DLT_SERVICE_ID_SET_VERBOSE_MODE:
1213         {
1214             dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED,  verbose);
1215             break;
1216         }
1217         case DLT_SERVICE_ID_SET_MESSAGE_FILTERING:
1218         {
1219             dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED,  verbose);
1220             break;
1221         }
1222         case DLT_SERVICE_ID_SET_TIMING_PACKETS:
1223         {
1224             dlt_daemon_control_set_timing_packets(sock, daemon, msg,  verbose);
1225             break;
1226         }
1227         case DLT_SERVICE_ID_GET_LOCAL_TIME:
1228         {
1229             /* Send response with valid timestamp (TMSP) field */
1230             dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_OK,  verbose);
1231             break;
1232         }
1233         case DLT_SERVICE_ID_USE_ECU_ID:
1234         {
1235             dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED,  verbose);
1236             break;
1237         }
1238         case DLT_SERVICE_ID_USE_SESSION_ID:
1239         {
1240             dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED,  verbose);
1241             break;
1242         }
1243         case DLT_SERVICE_ID_USE_TIMESTAMP:
1244         {
1245             dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED,  verbose);
1246             break;
1247         }
1248         case DLT_SERVICE_ID_USE_EXTENDED_HEADER:
1249         {
1250             dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED,  verbose);
1251             break;
1252         }
1253         case DLT_SERVICE_ID_SET_DEFAULT_LOG_LEVEL:
1254         {
1255             dlt_daemon_control_set_default_log_level(sock, daemon, msg,  verbose);
1256             break;
1257         }
1258         case DLT_SERVICE_ID_SET_DEFAULT_TRACE_STATUS:
1259         {
1260             dlt_daemon_control_set_default_trace_status(sock, daemon, msg,  verbose);
1261             break;
1262         }
1263         case DLT_SERVICE_ID_GET_SOFTWARE_VERSION:
1264         {
1265             dlt_daemon_control_get_software_version(sock, daemon,  verbose);
1266             break;
1267         }
1268         case DLT_SERVICE_ID_MESSAGE_BUFFER_OVERFLOW:
1269         {
1270             dlt_daemon_control_message_buffer_overflow(sock, daemon, daemon->overflow_counter,"",verbose);
1271             break;
1272         }
1273         default:
1274         {
1275             dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED,  verbose);
1276             break;
1277         }
1278         }
1279     }
1280     else
1281     {
1282         /* Injection handling */
1283         dlt_daemon_control_callsw_cinjection(sock, daemon, msg,  verbose);
1284     }
1285
1286     return 0;
1287 }
1288
1289 void dlt_daemon_control_callsw_cinjection(int sock, DltDaemon *daemon, DltMessage *msg, int verbose)
1290 {
1291     char apid[DLT_ID_SIZE],ctid[DLT_ID_SIZE];
1292     uint32_t id=0,id_tmp=0;
1293     uint8_t *ptr;
1294     DltDaemonContext *context;
1295         int32_t data_length_inject=0;
1296         uint32_t data_length_inject_tmp=0;
1297
1298         int32_t datalength;
1299
1300         DltUserHeader userheader;
1301         DltUserControlMsgInjection usercontext;
1302         uint8_t *userbuffer;
1303
1304     PRINT_FUNCTION_VERBOSE(verbose);
1305
1306     if ((daemon==0) || (msg==0))
1307     {
1308         return;
1309     }
1310
1311     datalength = msg->datasize;
1312     ptr = msg->databuffer;
1313
1314     if (ptr==0)
1315     {
1316         return;
1317     }
1318
1319     DLT_MSG_READ_VALUE(id_tmp,ptr,datalength,uint32_t); /* Get service id */
1320     id=DLT_ENDIAN_GET_32(msg->standardheader->htyp, id_tmp);
1321
1322     if ((id>=DLT_DAEMON_INJECTION_MIN) && (id<=DLT_DAEMON_INJECTION_MAX))
1323     {
1324         /* This a a real SW-C injection call */
1325         data_length_inject=0;
1326         data_length_inject_tmp=0;
1327
1328         DLT_MSG_READ_VALUE(data_length_inject_tmp,ptr,datalength,uint32_t); /* Get data length */
1329         data_length_inject=DLT_ENDIAN_GET_32(msg->standardheader->htyp, data_length_inject_tmp);
1330
1331         /* Get context handle for apid, ctid (and seid) */
1332         /* Warning: seid is ignored in this implementation! */
1333         if (DLT_IS_HTYP_UEH(msg->standardheader->htyp))
1334         {
1335             dlt_set_id(apid, msg->extendedheader->apid);
1336             dlt_set_id(ctid, msg->extendedheader->ctid);
1337         }
1338         else
1339         {
1340             /* No extended header, and therefore no apid and ctid available */
1341             dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR,  verbose);
1342             return;
1343         }
1344
1345         /* At this point, apid and ctid is available */
1346         context=dlt_daemon_context_find(daemon, apid, ctid, verbose);
1347
1348         if (context==0)
1349         {
1350             // dlt_log(LOG_INFO,"No context found!\n");
1351             dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR,  verbose);
1352             return;
1353         }
1354
1355         /* Send user message to handle, specified in context */
1356                 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_INJECTION)==-1)
1357                 {
1358                         dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR,  verbose);
1359                         return;
1360                 }
1361
1362                 usercontext.log_level_pos = context->log_level_pos;
1363
1364                 if(data_length_inject > msg->databuffersize)
1365                 {
1366                         dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR,  verbose);
1367                         return;
1368                 }
1369
1370                 userbuffer = malloc(data_length_inject);
1371
1372                 if (userbuffer==0)
1373                 {
1374                         dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR,  verbose);
1375                         return;
1376                 }
1377
1378                 usercontext.data_length_inject = data_length_inject;
1379                 usercontext.service_id = id;
1380
1381                 memcpy(userbuffer,ptr,data_length_inject);  /* Copy received injection to send buffer */
1382
1383                 /* write to FIFO */
1384                 DltReturnValue ret =
1385                                 dlt_user_log_out3(context->user_handle, &(userheader), sizeof(DltUserHeader),
1386                                   &(usercontext), sizeof(DltUserControlMsgInjection),
1387                                   userbuffer, data_length_inject);
1388                 if (ret != DLT_RETURN_OK)
1389                 {
1390                         if (ret == DLT_RETURN_PIPE_ERROR)
1391                         {
1392                                 /* Close connection */
1393                                 close(context->user_handle);
1394                                 context->user_handle=DLT_FD_INIT;
1395                         }
1396                         dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR,  verbose);
1397                 }
1398                 else
1399                 {
1400                         dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_OK,  verbose);
1401                 }
1402
1403                 free(userbuffer);
1404                 userbuffer=0;
1405
1406     }
1407     else
1408     {
1409         /* Invalid ID */
1410         dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED,  verbose);
1411     }
1412 }
1413
1414 void dlt_daemon_control_set_log_level(int sock, DltDaemon *daemon, DltMessage *msg, int verbose)
1415 {
1416     PRINT_FUNCTION_VERBOSE(verbose);
1417
1418     char apid[DLT_ID_SIZE],ctid[DLT_ID_SIZE];
1419     DltServiceSetLogLevel *req;
1420     DltDaemonContext *context;
1421     int32_t id=DLT_SERVICE_ID_SET_LOG_LEVEL;
1422
1423         int8_t old_log_level;
1424
1425     if ((daemon==0) || (msg==0))
1426     {
1427         return;
1428     }
1429
1430     req = (DltServiceSetLogLevel*) (msg->databuffer);
1431
1432     dlt_set_id(apid, req->apid);
1433     dlt_set_id(ctid, req->ctid);
1434
1435     context=dlt_daemon_context_find(daemon, apid, ctid, verbose);
1436
1437     /* Set log level */
1438     if (context!=0)
1439     {
1440         old_log_level = context->log_level;
1441         context->log_level = req->log_level; /* No endianess conversion necessary*/
1442
1443         if ((context->user_handle >= DLT_FD_MINIMUM) &&
1444                 (dlt_daemon_user_send_log_level(daemon, context, verbose)==0))
1445         {
1446             dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_OK,  verbose);
1447         }
1448         else
1449         {
1450             //dlt_log(LOG_ERR, "Log level could not be sent!\n");
1451             context->log_level = old_log_level;
1452             dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR,  verbose);
1453         }
1454     }
1455     else
1456     {
1457         //dlt_log(LOG_ERR, "Context not found!\n");
1458         dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR,  verbose);
1459     }
1460 }
1461
1462 void dlt_daemon_control_set_trace_status(int sock, DltDaemon *daemon, DltMessage *msg, int verbose)
1463 {
1464     PRINT_FUNCTION_VERBOSE(verbose);
1465
1466     char apid[DLT_ID_SIZE],ctid[DLT_ID_SIZE];
1467     DltServiceSetLogLevel *req;             /* request uses same struct as set log level */
1468     DltDaemonContext *context;
1469     int32_t id=DLT_SERVICE_ID_SET_TRACE_STATUS;
1470
1471         int8_t old_trace_status;
1472
1473     if ((daemon==0) || (msg==0))
1474     {
1475         return;
1476     }
1477
1478     req = (DltServiceSetLogLevel*) (msg->databuffer);
1479
1480     dlt_set_id(apid, req->apid);
1481     dlt_set_id(ctid, req->ctid);
1482
1483     context=dlt_daemon_context_find(daemon, apid, ctid, verbose);
1484
1485     /* Set log level */
1486     if (context!=0)
1487     {
1488         old_trace_status = context->trace_status;
1489         context->trace_status = req->log_level;   /* No endianess conversion necessary */
1490
1491         if ((context->user_handle >= DLT_FD_MINIMUM ) &&
1492                 (dlt_daemon_user_send_log_level(daemon, context, verbose)==0))
1493         {
1494             dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_OK,  verbose);
1495         }
1496         else
1497         {
1498             //dlt_log(LOG_ERR, "Trace Status could not be sent!\n");
1499             context->trace_status = old_trace_status;
1500             dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR,  verbose);
1501         }
1502     }
1503     else
1504     {
1505         //dlt_log(LOG_ERR, "Context not found!\n");
1506         dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR,  verbose);
1507     }
1508 }
1509
1510 void dlt_daemon_control_set_default_log_level(int sock, DltDaemon *daemon, DltMessage *msg, int verbose)
1511 {
1512     PRINT_FUNCTION_VERBOSE(verbose);
1513
1514     DltServiceSetDefaultLogLevel *req;
1515     int32_t id=DLT_SERVICE_ID_SET_DEFAULT_LOG_LEVEL;
1516
1517     if ((daemon==0) || (msg==0))
1518     {
1519         return;
1520     }
1521
1522     req = (DltServiceSetDefaultLogLevel*) (msg->databuffer);
1523
1524     /* No endianess conversion necessary */
1525     if (/*(req->log_level>=0) &&*/
1526             (req->log_level<=DLT_LOG_VERBOSE))
1527     {
1528         daemon->default_log_level = req->log_level; /* No endianess conversion necessary */
1529
1530         /* Send Update to all contexts using the default log level */
1531         dlt_daemon_user_send_default_update(daemon, verbose);
1532
1533         dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_OK,  verbose);
1534     }
1535     else
1536     {
1537         dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR,  verbose);
1538     }
1539 }
1540
1541 void dlt_daemon_control_set_default_trace_status(int sock, DltDaemon *daemon, DltMessage *msg, int verbose)
1542 {
1543     PRINT_FUNCTION_VERBOSE(verbose);
1544
1545     /* Payload of request message */
1546     DltServiceSetDefaultLogLevel *req;
1547     int32_t id=DLT_SERVICE_ID_SET_DEFAULT_TRACE_STATUS;
1548
1549     if ((daemon==0) || (msg==0))
1550     {
1551         return;
1552     }
1553
1554     req = (DltServiceSetDefaultLogLevel*) (msg->databuffer);
1555
1556     /* No endianess conversion necessary */
1557     if ((req->log_level==DLT_TRACE_STATUS_OFF) ||
1558             (req->log_level==DLT_TRACE_STATUS_ON))
1559     {
1560         daemon->default_trace_status = req->log_level; /* No endianess conversion necessary*/
1561
1562         /* Send Update to all contexts using the default trace status */
1563         dlt_daemon_user_send_default_update(daemon, verbose);
1564
1565         dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_OK,  verbose);
1566     }
1567     else
1568     {
1569         dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR,  verbose);
1570     }
1571 }
1572
1573 void dlt_daemon_control_set_timing_packets(int sock, DltDaemon *daemon, DltMessage *msg, int verbose)
1574 {
1575     PRINT_FUNCTION_VERBOSE(verbose);
1576
1577     DltServiceSetVerboseMode *req;  /* request uses same struct as set verbose mode */
1578     int32_t id=DLT_SERVICE_ID_SET_TIMING_PACKETS;
1579
1580     if ((daemon==0) || (msg==0))
1581     {
1582         return;
1583     }
1584
1585     req = (DltServiceSetVerboseMode*) (msg->databuffer);
1586     if ((req->new_status==0) || (req->new_status==1))
1587     {
1588         daemon->timingpackets = req->new_status;
1589
1590         dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_OK,  verbose);
1591     }
1592     else
1593     {
1594         dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR,  verbose);
1595     }
1596 }
1597
1598 void dlt_daemon_control_get_software_version(int sock, DltDaemon *daemon, int verbose)
1599 {
1600     DltMessage msg;
1601     uint32_t len;
1602         DltServiceGetSoftwareVersionResponse *resp;
1603
1604     PRINT_FUNCTION_VERBOSE(verbose);
1605
1606     if (daemon==0)
1607     {
1608         return;
1609     }
1610
1611     /* initialise new message */
1612     if (dlt_message_init(&msg,0)==-1)
1613     {
1614         dlt_daemon_control_service_response(sock, daemon, DLT_SERVICE_ID_GET_SOFTWARE_VERSION, DLT_SERVICE_RESPONSE_ERROR,  verbose);
1615                 return;
1616     }
1617
1618     /* prepare payload of data */
1619     len = strlen(daemon->ECUVersionString);
1620
1621     msg.datasize = sizeof(DltServiceGetSoftwareVersionResponse) + len;
1622     if (msg.databuffer && (msg.databuffersize < msg.datasize))
1623     {
1624         free(msg.databuffer);
1625         msg.databuffer=0;
1626     }
1627     if (msg.databuffer == 0){
1628         msg.databuffer = (uint8_t *) malloc(msg.datasize);
1629         msg.databuffersize = msg.datasize;
1630     }
1631     if (msg.databuffer==0)
1632     {
1633         dlt_daemon_control_service_response(sock, daemon, DLT_SERVICE_ID_GET_SOFTWARE_VERSION, DLT_SERVICE_RESPONSE_ERROR,  verbose);
1634         return;
1635     }
1636
1637     resp = (DltServiceGetSoftwareVersionResponse*) msg.databuffer;
1638     resp->service_id = DLT_SERVICE_ID_GET_SOFTWARE_VERSION;
1639     resp->status = DLT_SERVICE_RESPONSE_OK;
1640     resp->length = len;
1641     memcpy(msg.databuffer+sizeof(DltServiceGetSoftwareVersionResponse),daemon->ECUVersionString,len);
1642
1643     /* send message */
1644     dlt_daemon_control_send_control_message(sock, daemon, &msg,"","",  verbose);
1645
1646     /* free message */
1647     dlt_message_free(&msg,0);
1648 }
1649
1650 void dlt_daemon_control_get_default_log_level(int sock, DltDaemon *daemon, int verbose)
1651 {
1652     DltMessage msg;
1653         DltServiceGetDefaultLogLevelResponse *resp;
1654
1655     PRINT_FUNCTION_VERBOSE(verbose);
1656
1657     if (daemon==0)
1658     {
1659         return;
1660     }
1661
1662     /* initialise new message */
1663     if (dlt_message_init(&msg,0)==-1)
1664     {
1665         dlt_daemon_control_service_response(sock, daemon, DLT_SERVICE_ID_GET_DEFAULT_LOG_LEVEL, DLT_SERVICE_RESPONSE_ERROR,  verbose);
1666         return;
1667     }
1668
1669     msg.datasize = sizeof(DltServiceGetDefaultLogLevelResponse);
1670     if (msg.databuffer && (msg.databuffersize<msg.datasize))
1671     {
1672         free(msg.databuffer);
1673         msg.databuffer=0;
1674     }
1675     if (msg.databuffer == 0){
1676         msg.databuffer = (uint8_t *) malloc(msg.datasize);
1677         msg.databuffersize = msg.datasize;
1678     }
1679     if (msg.databuffer==0)
1680     {
1681         dlt_daemon_control_service_response(sock, daemon, DLT_SERVICE_ID_GET_DEFAULT_LOG_LEVEL, DLT_SERVICE_RESPONSE_ERROR,  verbose);
1682         return;
1683     }
1684
1685     resp = (DltServiceGetDefaultLogLevelResponse*) msg.databuffer;
1686     resp->service_id = DLT_SERVICE_ID_GET_DEFAULT_LOG_LEVEL;
1687     resp->status = DLT_SERVICE_RESPONSE_OK;
1688     resp->log_level = daemon->default_log_level;
1689
1690     /* send message */
1691     dlt_daemon_control_send_control_message(sock,daemon,&msg,"","",  verbose);
1692
1693     /* free message */
1694     dlt_message_free(&msg,0);
1695 }
1696
1697 void dlt_daemon_control_get_log_info(int sock, DltDaemon *daemon, DltMessage *msg, int verbose)
1698 {
1699     DltServiceGetLogInfoRequest *req;
1700     DltMessage resp;
1701     DltDaemonContext *context=0;
1702     DltDaemonApplication *application=0;
1703
1704     int num_applications=0, num_contexts=0;
1705     uint16_t count_app_ids=0, count_con_ids=0;
1706
1707 #if (DLT_DEBUG_GETLOGINFO==1)
1708     char buf[255];
1709 #endif
1710
1711     int32_t i,j,offset=0;
1712     char *apid=0;
1713     int8_t ll,ts;
1714     uint16_t len;
1715     int8_t value;
1716     int32_t sizecont=0;
1717     int offset_base;
1718
1719     uint32_t sid;
1720
1721     PRINT_FUNCTION_VERBOSE(verbose);
1722
1723     if ((daemon==0) || (msg==0))
1724     {
1725         return;
1726     }
1727
1728     /* prepare pointer to message request */
1729     req = (DltServiceGetLogInfoRequest*) (msg->databuffer);
1730
1731     /* initialise new message */
1732     if (dlt_message_init(&resp,0)==-1)
1733     {
1734                 dlt_daemon_control_service_response(sock, daemon, DLT_SERVICE_ID_GET_LOG_INFO, DLT_SERVICE_RESPONSE_ERROR,  verbose);
1735         return;
1736     }
1737
1738     /* check request */
1739     if ((req->options < 3 ) || (req->options>7))
1740     {
1741         dlt_daemon_control_service_response(sock, daemon, DLT_SERVICE_ID_GET_LOG_INFO, DLT_SERVICE_RESPONSE_ERROR,  verbose);
1742         return;
1743     }
1744
1745     if (req->apid[0]!='\0')
1746     {
1747         application = dlt_daemon_application_find(daemon, req->apid, verbose);
1748         if (application)
1749         {
1750             num_applications = 1;
1751             if (req->ctid[0]!='\0')
1752             {
1753                 context = dlt_daemon_context_find(daemon, req->apid, req->ctid, verbose);
1754
1755                 num_contexts = ((context)?1:0);
1756             }
1757             else
1758             {
1759                 num_contexts = application->num_contexts;
1760             }
1761         }
1762         else
1763         {
1764             num_applications = 0;
1765             num_contexts = 0;
1766         }
1767     }
1768     else
1769     {
1770         /* Request all applications and contexts */
1771         num_applications = daemon->num_applications;
1772         num_contexts = daemon->num_contexts;
1773     }
1774
1775     /* prepare payload of data */
1776
1777     /* Calculate maximum size for a response */
1778     resp.datasize = sizeof(uint32_t) /* SID */ + sizeof(int8_t) /* status*/ + sizeof(ID4) /* DLT_DAEMON_REMO_STRING */;
1779
1780     sizecont = sizeof(uint32_t) /* context_id */;
1781
1782     /* Add additional size for response of Mode 4, 6, 7 */
1783     if ((req->options==4) || (req->options==6) || (req->options==7))
1784     {
1785         sizecont += sizeof(int8_t); /* log level */
1786     }
1787
1788     /* Add additional size for response of Mode 5, 6, 7 */
1789     if ((req->options==5) || (req->options==6) || (req->options==7))
1790     {
1791         sizecont+= sizeof(int8_t); /* trace status */
1792     }
1793
1794     resp.datasize+= (num_applications * (sizeof(uint32_t) /* app_id */  + sizeof(uint16_t) /* count_con_ids */)) +
1795                     (num_contexts * sizecont);
1796
1797     resp.datasize+= sizeof(uint16_t) /* count_app_ids */;
1798
1799     /* Add additional size for response of Mode 7 */
1800     if (req->options==7)
1801     {
1802         if (req->apid[0]!='\0')
1803         {
1804             if (req->ctid[0]!='\0')
1805             {
1806                 /* One application, one context */
1807                 // context = dlt_daemon_context_find(daemon, req->apid, req->ctid, verbose);
1808                 if (context)
1809                 {
1810                     resp.datasize+=sizeof(uint16_t) /* len_context_description */;
1811                     if (context->context_description!=0)
1812                     {
1813                         resp.datasize+=strlen(context->context_description); /* context_description */
1814                     }
1815                 }
1816             }
1817             else
1818             {
1819                 /* One application, all contexts */
1820                 if ((daemon->applications) && (application))
1821                 {
1822                     /* Calculate start offset within contexts[] */
1823                     offset_base=0;
1824                     for (i=0; i<(application-(daemon->applications)); i++)
1825                     {
1826                         offset_base+=daemon->applications[i].num_contexts;
1827                     }
1828
1829                     /* Iterate over all contexts belonging to this application */
1830                     for (j=0;j<application->num_contexts;j++)
1831                     {
1832
1833                         context = &(daemon->contexts[offset_base+j]);
1834                         if (context)
1835                         {
1836                             resp.datasize+=sizeof(uint16_t) /* len_context_description */;
1837                             if (context->context_description!=0)
1838                             {
1839                                 resp.datasize+=strlen(context->context_description); /* context_description */
1840                             }
1841                         }
1842                     }
1843                 }
1844             }
1845
1846             /* Space for application description */
1847             if (application)
1848             {
1849                 resp.datasize+=sizeof(uint16_t) /* len_app_description */;
1850                 if (application->application_description!=0)
1851                 {
1852                     resp.datasize+=strlen(application->application_description); /* app_description */
1853                 }
1854             }
1855         }
1856         else
1857         {
1858             /* All applications, all contexts */
1859             for (i=0;i<daemon->num_contexts;i++)
1860             {
1861                 resp.datasize+=sizeof(uint16_t) /* len_context_description */;
1862                 if (daemon->contexts[i].context_description!=0)
1863                 {
1864                     resp.datasize+=strlen(daemon->contexts[i].context_description); /* context_description */
1865                 }
1866             }
1867
1868             for (i=0;i<daemon->num_applications;i++)
1869             {
1870                 resp.datasize+=sizeof(uint16_t) /* len_app_description */;
1871                 if (daemon->applications[i].application_description!=0)
1872                 {
1873                     resp.datasize+=strlen(daemon->applications[i].application_description); /* app_description */
1874                 }
1875             }
1876         }
1877     }
1878
1879     if (verbose)
1880     {
1881         sprintf(str,"Allocate %d bytes for response msg databuffer\n", resp.datasize);
1882         dlt_log(LOG_INFO, str);
1883     }
1884
1885     /* Allocate buffer for response message */
1886     resp.databuffer = (uint8_t *) malloc(resp.datasize);
1887     resp.databuffersize = resp.datasize;
1888
1889     if (resp.databuffer==0)
1890     {
1891         dlt_daemon_control_service_response(sock, daemon, DLT_SERVICE_ID_GET_LOG_INFO, DLT_SERVICE_RESPONSE_ERROR,  verbose);
1892         return;
1893     }
1894     memset(resp.databuffer,0,resp.datasize);
1895     /* Preparation finished */
1896
1897     /* Prepare response */
1898     sid = DLT_SERVICE_ID_GET_LOG_INFO;
1899     memcpy(resp.databuffer,&sid,sizeof(uint32_t));
1900     offset+=sizeof(uint32_t);
1901
1902     value = (((num_applications!=0)&&(num_contexts!=0))?req->options:8); /* 8 = no matching context found */
1903
1904     memcpy(resp.databuffer+offset,&value,sizeof(int8_t));
1905     offset+=sizeof(int8_t);
1906
1907     count_app_ids = num_applications;
1908
1909     if (count_app_ids!=0)
1910     {
1911         memcpy(resp.databuffer+offset,&count_app_ids,sizeof(uint16_t));
1912         offset+=sizeof(uint16_t);
1913
1914 #if (DLT_DEBUG_GETLOGINFO==1)
1915         sprintf(str,"#apid: %d \n", count_app_ids);
1916         dlt_log(LOG_DEBUG, str);
1917 #endif
1918
1919         for (i=0;i<count_app_ids;i++)
1920         {
1921             if (req->apid[0]!='\0')
1922             {
1923                 apid = req->apid;
1924             }
1925             else
1926             {
1927                 if (daemon->applications)
1928                 {
1929                     apid = daemon->applications[i].apid;
1930                 }
1931                 else
1932                 {
1933                     /* This should never occur! */
1934                     apid=0;
1935                 }
1936             }
1937
1938             application = dlt_daemon_application_find(daemon, apid, verbose);
1939
1940             if (application)
1941             {
1942                 /* Calculate start offset within contexts[] */
1943                 offset_base=0;
1944                 for (j=0; j<(application-(daemon->applications)); j++)
1945                 {
1946                     offset_base+=daemon->applications[j].num_contexts;
1947                 }
1948
1949                 dlt_set_id((char*)(resp.databuffer+offset),apid);
1950                 offset+=sizeof(ID4);
1951
1952 #if (DLT_DEBUG_GETLOGINFO==1)
1953                 dlt_print_id(buf, apid);
1954                 sprintf(str,"apid: %s\n",buf);
1955                 dlt_log(LOG_DEBUG, str);
1956 #endif
1957
1958                 if (req->apid[0]!='\0')
1959                 {
1960                     count_con_ids = num_contexts;
1961                 }
1962                 else
1963                 {
1964                     count_con_ids = application->num_contexts;
1965                 }
1966
1967                 memcpy(resp.databuffer+offset,&count_con_ids,sizeof(uint16_t));
1968                 offset+=sizeof(uint16_t);
1969
1970 #if (DLT_DEBUG_GETLOGINFO==1)
1971                 sprintf(str,"#ctid: %d \n", count_con_ids);
1972                 dlt_log(LOG_DEBUG, str);
1973 #endif
1974
1975                 for (j=0;j<count_con_ids;j++)
1976                 {
1977 #if (DLT_DEBUG_GETLOGINFO==1)
1978                     sprintf(str,"j: %d \n",j);
1979                     dlt_log(LOG_DEBUG, str);
1980 #endif
1981                     if (!((count_con_ids==1) && (req->apid[0]!='\0') && (req->ctid[0]!='\0')))
1982                     {
1983                         context = &(daemon->contexts[offset_base+j]);
1984                     }
1985                     /* else: context was already searched and found
1986                              (one application (found) with one context (found))*/
1987
1988                     if ((context) &&
1989                             ((req->ctid[0]=='\0') ||
1990                              ((req->ctid[0]!='\0') && (memcmp(context->ctid,req->ctid,DLT_ID_SIZE)==0)))
1991                        )
1992                     {
1993                         dlt_set_id((char*)(resp.databuffer+offset),context->ctid);
1994                         offset+=sizeof(ID4);
1995
1996 #if (DLT_DEBUG_GETLOGINFO==1)
1997                         dlt_print_id(buf, context->ctid);
1998                         sprintf(str,"ctid: %s \n",buf);
1999                         dlt_log(LOG_DEBUG, str);
2000 #endif
2001
2002                         /* Mode 4, 6, 7 */
2003                         if ((req->options==4) || (req->options==6) || (req->options==7))
2004                         {
2005                             ll=context->log_level;
2006                             memcpy(resp.databuffer+offset,&ll,sizeof(int8_t));
2007                             offset+=sizeof(int8_t);
2008                         }
2009
2010                         /* Mode 5, 6, 7 */
2011                         if ((req->options==5) || (req->options==6) || (req->options==7))
2012                         {
2013                             ts=context->trace_status;
2014                             memcpy(resp.databuffer+offset,&ts,sizeof(int8_t));
2015                             offset+=sizeof(int8_t);
2016                         }
2017
2018                         /* Mode 7 */
2019                         if (req->options==7)
2020                         {
2021                             if (context->context_description)
2022                             {
2023                                 len = strlen(context->context_description);
2024                                 memcpy(resp.databuffer+offset,&len,sizeof(uint16_t));
2025                                 offset+=sizeof(uint16_t);
2026                                 memcpy(resp.databuffer+offset,context->context_description,strlen(context->context_description));
2027                                 offset+=strlen(context->context_description);
2028                             }
2029                             else
2030                             {
2031                                 len = 0;
2032                                 memcpy(resp.databuffer+offset,&len,sizeof(uint16_t));
2033                                 offset+=sizeof(uint16_t);
2034                             }
2035                         }
2036
2037 #if (DLT_DEBUG_GETLOGINFO==1)
2038                         sprintf(str,"ll=%d ts=%d \n",(int32_t)ll,(int32_t)ts);
2039                         dlt_log(LOG_DEBUG, str);
2040 #endif
2041                     }
2042
2043 #if (DLT_DEBUG_GETLOGINFO==1)
2044                     dlt_log(LOG_DEBUG,"\n");
2045 #endif
2046                 }
2047
2048                 /* Mode 7 */
2049                 if (req->options==7)
2050                 {
2051                     if (application->application_description)
2052                     {
2053                         len = strlen(application->application_description);
2054                         memcpy(resp.databuffer+offset,&len,sizeof(uint16_t));
2055                         offset+=sizeof(uint16_t);
2056                         memcpy(resp.databuffer+offset,application->application_description,strlen(application->application_description));
2057                         offset+=strlen(application->application_description);
2058                     }
2059                     else
2060                     {
2061                         len = 0;
2062                         memcpy(resp.databuffer+offset,&len,sizeof(uint16_t));
2063                         offset+=sizeof(uint16_t);
2064                     }
2065                 }
2066             } /* if (application) */
2067         } /* for (i=0;i<count_app_ids;i++) */
2068     } /* if (count_app_ids!=0) */
2069
2070     dlt_set_id((char*)(resp.databuffer+offset),DLT_DAEMON_REMO_STRING);
2071
2072     /* send message */
2073     dlt_daemon_control_send_control_message(sock,daemon,&resp,"","",  verbose);
2074
2075     /* free message */
2076     dlt_message_free(&resp,0);
2077 }
2078
2079 int dlt_daemon_control_message_buffer_overflow(int sock, DltDaemon *daemon, unsigned int overflow_counter,char* apid, int verbose)
2080 {
2081     DltMessage msg;
2082         DltServiceMessageBufferOverflowResponse *resp;
2083
2084     PRINT_FUNCTION_VERBOSE(verbose);
2085
2086     if (daemon==0)
2087     {
2088         return -1;
2089     }
2090
2091     /* initialise new message */
2092     if (dlt_message_init(&msg,0)==-1)
2093     {
2094         dlt_daemon_control_service_response(sock, daemon, DLT_SERVICE_ID_MESSAGE_BUFFER_OVERFLOW, DLT_SERVICE_RESPONSE_ERROR,  verbose);
2095         return -1;
2096     }
2097
2098     /* prepare payload of data */
2099     msg.datasize = sizeof(DltServiceMessageBufferOverflowResponse);
2100     if (msg.databuffer && (msg.databuffersize < msg.datasize))
2101     {
2102         free(msg.databuffer);
2103         msg.databuffer=0;
2104     }
2105     if (msg.databuffer == 0){
2106         msg.databuffer = (uint8_t *) malloc(msg.datasize);
2107         msg.databuffersize = msg.datasize;
2108     }
2109     if (msg.databuffer==0)
2110     {
2111         if (sock!=DLT_DAEMON_STORE_TO_BUFFER)
2112         {
2113             dlt_daemon_control_service_response(sock, daemon, DLT_SERVICE_ID_MESSAGE_BUFFER_OVERFLOW, DLT_SERVICE_RESPONSE_ERROR,  verbose);
2114         }
2115         return -1;
2116     }
2117
2118     resp = (DltServiceMessageBufferOverflowResponse*) msg.databuffer;
2119     resp->service_id = DLT_SERVICE_ID_MESSAGE_BUFFER_OVERFLOW;
2120     resp->status = DLT_SERVICE_RESPONSE_OK;
2121     resp->overflow = daemon->message_buffer_overflow;
2122         resp->overflow_counter = overflow_counter;
2123
2124     /* send message */
2125     if(dlt_daemon_control_send_control_message(sock,daemon,&msg,apid,"",  verbose))
2126     {
2127         dlt_message_free(&msg,0);
2128         return -1;
2129     }
2130
2131     /* free message */
2132     dlt_message_free(&msg,0);
2133
2134     return 0;
2135 }
2136
2137 void dlt_daemon_control_service_response( int sock, DltDaemon *daemon, uint32_t service_id, int8_t status , int verbose)
2138 {
2139     DltMessage msg;
2140     DltServiceResponse *resp;
2141
2142     PRINT_FUNCTION_VERBOSE(verbose);
2143
2144     if (daemon==0)
2145     {
2146         return;
2147     }
2148
2149     /* initialise new message */
2150     if (dlt_message_init(&msg,0)==-1)
2151     {
2152                 return;
2153     }
2154
2155     /* prepare payload of data */
2156     msg.datasize = sizeof(DltServiceResponse);
2157     if (msg.databuffer && (msg.databuffersize < msg.datasize))
2158     {
2159         free(msg.databuffer);
2160         msg.databuffer=0;
2161     }
2162     if (msg.databuffer == 0){
2163         msg.databuffer = (uint8_t *) malloc(msg.datasize);
2164         msg.databuffersize = msg.datasize;
2165     }
2166     if (msg.databuffer==0)
2167     {
2168         return;
2169     }
2170
2171     resp = (DltServiceResponse*) msg.databuffer;
2172     resp->service_id = service_id;
2173     resp->status = status;
2174
2175     /* send message */
2176     dlt_daemon_control_send_control_message(sock,daemon,&msg,"","",  verbose);
2177
2178     /* free message */
2179     dlt_message_free(&msg,0);
2180 }
2181
2182 int dlt_daemon_control_send_control_message( int sock, DltDaemon *daemon, DltMessage *msg, char* appid, char* ctid, int verbose)
2183 {
2184     ssize_t ret;
2185     int32_t len;
2186
2187     PRINT_FUNCTION_VERBOSE(verbose);
2188
2189     if ((daemon==0) || (msg==0) || (appid==0) || (ctid==0))
2190     {
2191         return -1;
2192     }
2193
2194     /* prepare storage header */
2195     msg->storageheader = (DltStorageHeader*)msg->headerbuffer;
2196
2197     if (dlt_set_storageheader(msg->storageheader,daemon->ecuid)==-1)
2198     {
2199                 return -1;
2200     }
2201
2202     /* prepare standard header */
2203     msg->standardheader = (DltStandardHeader*)(msg->headerbuffer + sizeof(DltStorageHeader));
2204     msg->standardheader->htyp = DLT_HTYP_WEID | DLT_HTYP_WTMS | DLT_HTYP_UEH | DLT_HTYP_PROTOCOL_VERSION1 ;
2205
2206 #if (BYTE_ORDER==BIG_ENDIAN)
2207     msg->standardheader->htyp = ( msg->standardheader->htyp | DLT_HTYP_MSBF);
2208 #endif
2209
2210     msg->standardheader->mcnt = 0;
2211
2212     /* Set header extra parameters */
2213     dlt_set_id(msg->headerextra.ecu,daemon->ecuid);
2214
2215     //msg->headerextra.seid = 0;
2216
2217     msg->headerextra.tmsp = dlt_uptime();
2218
2219     dlt_message_set_extraparameters(msg, verbose);
2220
2221     /* prepare extended header */
2222     msg->extendedheader = (DltExtendedHeader*)(msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg->standardheader->htyp));
2223     msg->extendedheader->msin = DLT_MSIN_CONTROL_RESPONSE;
2224
2225     msg->extendedheader->noar = 1; /* number of arguments */
2226     if (strcmp(appid,"")==0)
2227     {
2228         dlt_set_id(msg->extendedheader->apid,DLT_DAEMON_CTRL_APID);       /* application id */
2229     }
2230     else
2231     {
2232         dlt_set_id(msg->extendedheader->apid, appid);
2233     }
2234     if (strcmp(ctid,"")==0)
2235     {
2236         dlt_set_id(msg->extendedheader->ctid,DLT_DAEMON_CTRL_CTID);       /* context id */
2237     }
2238     else
2239     {
2240         dlt_set_id(msg->extendedheader->ctid, ctid);
2241     }
2242
2243     /* prepare length information */
2244     msg->headersize = sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + sizeof(DltExtendedHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg->standardheader->htyp);
2245
2246     len=msg->headersize - sizeof(DltStorageHeader) + msg->datasize;
2247     if (len>UINT16_MAX)
2248     {
2249         dlt_log(LOG_CRIT,"Huge control message discarded!\n");
2250         return -1;
2251     }
2252
2253     msg->standardheader->len = DLT_HTOBE_16(((uint16_t)len));
2254
2255     if (sock!=DLT_DAEMON_STORE_TO_BUFFER)
2256     {
2257         /* Send message */
2258         if (isatty(sock))
2259         {
2260             DLT_DAEMON_SEM_LOCK();
2261
2262             /* Optional: Send serial header, if requested */
2263             if (daemon->sendserialheader)
2264             {
2265                 ret=write(sock,dltSerialHeader,sizeof(dltSerialHeader));
2266                 if (0 > ret)
2267                 {
2268                         dlt_log(LOG_CRIT,"dlt_daemon_control_send_control_message: write dltSerialHeader failed\n");
2269                         DLT_DAEMON_SEM_FREE();
2270                         return -1;
2271                 }
2272             }
2273
2274             /* Send data */
2275             ret=write(sock, msg->headerbuffer+sizeof(DltStorageHeader),msg->headersize-sizeof(DltStorageHeader));
2276             if (0 > ret)
2277             {
2278                     dlt_log(LOG_CRIT,"dlt_daemon_control_send_control_message: write msg->headerbuffer failed\n");
2279                     DLT_DAEMON_SEM_FREE();
2280                     return -1;
2281             }
2282             ret=write(sock, msg->databuffer,msg->datasize);
2283             if (0 > ret)
2284             {
2285                     dlt_log(LOG_CRIT,"dlt_daemon_control_send_control_message: write msg->databuffer failed\n");
2286                     DLT_DAEMON_SEM_FREE();
2287                     return -1;
2288             }
2289
2290             DLT_DAEMON_SEM_FREE();
2291         }
2292         else
2293         {
2294             DLT_DAEMON_SEM_LOCK();
2295
2296             /* Optional: Send serial header, if requested */
2297             if (daemon->sendserialheader)
2298             {
2299                 if (0 > send(sock, dltSerialHeader,sizeof(dltSerialHeader),0))
2300                     dlt_log(LOG_WARNING,"dlt_daemon_control_send_control_message: send serialheader failed\n");
2301
2302             }
2303
2304             /* Send data */
2305
2306             if ( 0 > send(sock, msg->headerbuffer+sizeof(DltStorageHeader),msg->headersize-sizeof(DltStorageHeader),0))
2307                 dlt_log(LOG_WARNING,"dlt_daemon_control_send_control_message: send DltStorageHeader failed\n");
2308
2309             if ( 0 > send(sock, msg->databuffer,msg->datasize,0))
2310                 dlt_log(LOG_WARNING,"dlt_daemon_control_send_control_message: send databuffer failed\n");
2311
2312             DLT_DAEMON_SEM_FREE();
2313         }
2314     }
2315     else
2316     {
2317         DLT_DAEMON_SEM_LOCK();
2318         /* Store message in history buffer */
2319         if (dlt_buffer_push3(&(daemon->client_ringbuffer),
2320                             msg->headerbuffer+sizeof(DltStorageHeader),msg->headersize-sizeof(DltStorageHeader),
2321                             msg->databuffer,msg->datasize,
2322                             0, 0
2323                            )<0)
2324                 {
2325                 DLT_DAEMON_SEM_FREE();
2326                         dlt_log(LOG_ERR,"Storage of message in history buffer failed! Message discarded.\n");
2327                         return -1;
2328                 }
2329         DLT_DAEMON_SEM_FREE();
2330     }
2331     return 0;
2332 }
2333
2334 void dlt_daemon_control_reset_to_factory_default(DltDaemon *daemon,const char *filename, const char *filename1, int verbose)
2335 {
2336     FILE *fd;
2337
2338     PRINT_FUNCTION_VERBOSE(verbose);
2339
2340     if ((daemon==0) || (filename==0) || (filename1==0) || (filename[0]=='\0') || (filename1[0]=='\0'))
2341     {
2342         return;
2343     }
2344
2345     /* Check for runtime cfg file and delete it, if available */
2346     fd=fopen(filename, "r");
2347
2348     if (fd!=0)
2349     {
2350         /* Close and delete file */
2351         fclose(fd);
2352         unlink(filename);
2353     }
2354
2355     fd=fopen(filename1, "r");
2356
2357     if (fd!=0)
2358     {
2359         /* Close and delete file */
2360         fclose(fd);
2361         unlink(filename1);
2362     }
2363
2364     daemon->default_log_level = DLT_DAEMON_INITIAL_LOG_LEVEL ;
2365     daemon->default_trace_status = DLT_DAEMON_INITIAL_TRACE_STATUS ;
2366
2367     daemon->message_buffer_overflow = DLT_MESSAGE_BUFFER_NO_OVERFLOW;
2368
2369     /* Reset all other things (log level, trace status, etc.
2370                                                    to default values             */
2371
2372     /* Inform user libraries about changed default log level/trace status */
2373     dlt_daemon_user_send_default_update(daemon, verbose);
2374 }
2375
2376 void dlt_daemon_user_send_default_update(DltDaemon *daemon, int verbose)
2377 {
2378     int32_t count;
2379     DltDaemonContext *context;
2380
2381     PRINT_FUNCTION_VERBOSE(verbose);
2382
2383     if (daemon==0)
2384     {
2385         return;
2386     }
2387
2388     for (count=0;count<daemon->num_contexts; count ++)
2389     {
2390         context = &(daemon->contexts[count]);
2391
2392         if (context)
2393         {
2394             if ((context->log_level == DLT_LOG_DEFAULT) ||
2395                     (context->trace_status == DLT_TRACE_STATUS_DEFAULT))
2396             {
2397                 if (context->user_handle >= DLT_FD_MINIMUM)
2398                 {
2399                     if (dlt_daemon_user_send_log_level(daemon, context, verbose)==-1)
2400                     {
2401                         return;
2402                     }
2403                 }
2404             }
2405         }
2406     }
2407 }
2408
2409 void dlt_daemon_user_send_all_log_state(DltDaemon *daemon, int verbose)
2410 {
2411     int32_t count;
2412     DltDaemonApplication *app;
2413
2414     PRINT_FUNCTION_VERBOSE(verbose);
2415
2416     if (daemon==0)
2417     {
2418         return;
2419     }
2420
2421     for (count=0;count<daemon->num_applications; count ++)
2422     {
2423         app = &(daemon->applications[count]);
2424
2425         if (app)
2426         {
2427                         if (app->user_handle >= DLT_FD_MINIMUM)
2428                         {
2429                                 if (dlt_daemon_user_send_log_state(daemon, app, verbose)==-1)
2430                                 {
2431                                         return;
2432                                 }
2433                         }
2434         }
2435     }
2436 }
2437
2438 void dlt_daemon_control_message_time(int sock, DltDaemon *daemon, int verbose)
2439 {
2440     DltMessage msg;
2441     ssize_t ret;
2442     int32_t len;
2443
2444     PRINT_FUNCTION_VERBOSE(verbose);
2445
2446     if (daemon==0)
2447     {
2448         return;
2449     }
2450
2451     if (sock==DLT_DAEMON_STORE_TO_BUFFER)
2452     {
2453         return;
2454     }
2455
2456     /* initialise new message */
2457     if (dlt_message_init(&msg,0)==-1)
2458     {
2459         return;
2460     }
2461
2462     /* send message */
2463
2464     /* prepare storage header */
2465     msg.storageheader = (DltStorageHeader*)msg.headerbuffer;
2466     dlt_set_storageheader(msg.storageheader,daemon->ecuid);
2467
2468     /* prepare standard header */
2469     msg.standardheader = (DltStandardHeader*)(msg.headerbuffer + sizeof(DltStorageHeader));
2470     msg.standardheader->htyp = DLT_HTYP_WEID | DLT_HTYP_WTMS | DLT_HTYP_UEH | DLT_HTYP_PROTOCOL_VERSION1 ;
2471
2472 #if (BYTE_ORDER==BIG_ENDIAN)
2473     msg.standardheader->htyp = ( msg.standardheader->htyp | DLT_HTYP_MSBF);
2474 #endif
2475
2476     msg.standardheader->mcnt = 0;
2477
2478     /* Set header extra parameters */
2479     dlt_set_id(msg.headerextra.ecu,daemon->ecuid);
2480     msg.headerextra.tmsp = dlt_uptime();
2481
2482     dlt_message_set_extraparameters(&msg, verbose);
2483
2484     /* prepare extended header */
2485     msg.extendedheader = (DltExtendedHeader*)(msg.headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp));
2486     msg.extendedheader->msin = DLT_MSIN_CONTROL_TIME;
2487
2488     msg.extendedheader->noar = 0;                  /* number of arguments */
2489     dlt_set_id(msg.extendedheader->apid,"");       /* application id */
2490     dlt_set_id(msg.extendedheader->ctid,"");       /* context id */
2491
2492     /* prepare length information */
2493     msg.headersize = sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + sizeof(DltExtendedHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp);
2494
2495     len=msg.headersize - sizeof(DltStorageHeader) + msg.datasize;
2496     if (len>UINT16_MAX)
2497     {
2498         dlt_log(LOG_CRIT,"Huge control message discarded!\n");
2499
2500         /* free message */
2501         dlt_message_free(&msg,0);
2502
2503         return;
2504     }
2505
2506     msg.standardheader->len = DLT_HTOBE_16(((uint16_t)len));
2507
2508     /* Send message */
2509     if (isatty(sock))
2510     {
2511         DLT_DAEMON_SEM_LOCK();
2512
2513         /* Optional: Send serial header, if requested */
2514         if (daemon->sendserialheader)
2515         {
2516             ret=write(sock,dltSerialHeader,sizeof(dltSerialHeader));
2517         }
2518
2519         /* Send data */
2520         ret=write(sock, msg.headerbuffer+sizeof(DltStorageHeader),msg.headersize-sizeof(DltStorageHeader));
2521         if(msg.datasize > 0)
2522         {
2523                 ret=write(sock, msg.databuffer,msg.datasize);
2524                 if (0 > ret){
2525                         dlt_log(LOG_CRIT,"dlt_daemon_control_message_time: Failed to write databuffer\n");
2526                         dlt_message_free(&msg,0);
2527                         DLT_DAEMON_SEM_FREE();
2528                         return;
2529                 }
2530         }
2531
2532         DLT_DAEMON_SEM_FREE();
2533     }
2534     else
2535     {
2536         DLT_DAEMON_SEM_LOCK();
2537
2538         /* Optional: Send serial header, if requested */
2539         if (daemon->sendserialheader)
2540         {
2541             if ( -1 == send(sock, dltSerialHeader,sizeof(dltSerialHeader),0) )
2542                 dlt_log(LOG_ERR,"dlt_daemon_control_message_time: Failed to send dltSerialHeader");
2543
2544         }
2545
2546         /* Send data */
2547         if (-1 == send(sock, msg.headerbuffer+sizeof(DltStorageHeader),msg.headersize-sizeof(DltStorageHeader),0))
2548             dlt_log(LOG_ERR,"dlt_daemon_control_message_time: Failed to send DltStorageHeader");
2549
2550         if(msg.datasize > 0)
2551         {
2552             if (-1 == send(sock, msg.databuffer,msg.datasize,0) )
2553                 dlt_log(LOG_ERR,"dlt_daemon_control_message_time: Failed to send databuffer");
2554         }
2555
2556         DLT_DAEMON_SEM_FREE();
2557     }
2558
2559     /* free message */
2560     dlt_message_free(&msg,0);
2561 }