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