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