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