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