Invalid Sock is set to -1 instead 0 (stdin). Consequent error handling in fseek failu...
[profile/ivi/dlt-daemon.git] / src / shared / dlt_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_common.c
19  * For further information see http://www.genivi.org/.
20  * @licence end@
21  */
22
23
24 /*******************************************************************************
25 **                                                                            **
26 **  SRC-MODULE: dlt_common.c                                                  **
27 **                                                                            **
28 **  TARGET    : linux                                                         **
29 **                                                                            **
30 **  PROJECT   : DLT                                                           **
31 **                                                                            **
32 **  AUTHOR    : Alexander Wenzel Alexander.AW.Wenzel@bmw.de                   **
33 **              Markus Klein                                                  **
34 **                                                                            **
35 **  PURPOSE   :                                                               **
36 **                                                                            **
37 **  REMARKS   :                                                               **
38 **                                                                            **
39 **  PLATFORM DEPENDANT [yes/no]: yes                                          **
40 **                                                                            **
41 **  TO BE CHANGED BY USER [yes/no]: no                                        **
42 **                                                                            **
43 *******************************************************************************/
44
45 /*******************************************************************************
46 **                      Author Identity                                       **
47 ********************************************************************************
48 **                                                                            **
49 ** Initials     Name                       Company                            **
50 ** --------     -------------------------  ---------------------------------- **
51 **  aw          Alexander Wenzel           BMW                                **
52 **  mk          Markus Klein               Fraunhofer ESK                     **
53 *******************************************************************************/
54
55 /*******************************************************************************
56 **                      Revision Control History                              **
57 *******************************************************************************/
58
59 /*
60  * $LastChangedRevision: 1670 $
61  * $LastChangedDate: 2011-04-08 15:12:06 +0200 (Fr, 08. Apr 2011) $
62  * $LastChangedBy$
63  Initials    Date         Comment
64  aw          13.01.2010   initial
65  */
66 #include <stdio.h>
67 #include <stdlib.h> /* for malloc(), free() */
68 #include <string.h> /* for strlen(), memcmp(), memmove() */
69 #include <time.h>   /* for localtime(), strftime() */
70 #include <limits.h> /* for NAME_MAX */
71
72 #include "dlt_common.h"
73 #include "dlt_common_cfg.h"
74
75 #include "dlt_version.h"
76
77 #if defined (__WIN32__) || defined (_MSC_VER)
78 #include <winsock2.h> /* for socket(), connect(), send(), and recv() */
79 #else
80 #include <sys/socket.h> /* for socket(), connect(), send(), and recv() */
81 #include <syslog.h>
82 #include <time.h> /* for clock_gettime() */
83 #endif
84
85 #if defined (_MSC_VER)
86 #include <io.h>
87 #else
88 #include <unistd.h>     /* for read(), close() */
89 #include <sys/time.h>   /* for gettimeofday() */
90 #endif
91
92 #if defined (__MSDOS__) || defined (_MSC_VER)
93 #pragma warning(disable : 4996) /* Switch off C4996 warnings */
94 #include <windows.h>
95 #include <winbase.h>
96 #endif
97
98 static char str[DLT_COMMON_BUFFER_LENGTH];
99
100 const char dltSerialHeader[DLT_ID_SIZE] = { 'D','L','S',1 };
101 char dltSerialHeaderChar[DLT_ID_SIZE] = { 'D','L','S',1 };
102
103 /* internal logging parameters */
104 static int logging_mode = 0;
105 static int logging_level = 6;
106 static char logging_filename[NAME_MAX + 1] = "";
107 static FILE *logging_handle = 0;
108
109 char *message_type[] = {"log","app_trace","nw_trace","control","","","",""};
110 char *log_info[] = {"","fatal","error","warn","info","debug","verbose","","","","","","","","",""};
111 char *trace_type[] = {"","variable","func_in","func_out","state","vfb","","","","","","","","","",""};
112 char *nw_trace_type[] = {"","ipc","can","flexray","most","vfb","","","","","","","","","",""};
113 char *control_type[] = {"","request","response","time","","","","","","","","","","","",""};
114 static char *service_id[] = {"","set_log_level","set_trace_status","get_log_info","get_default_log_level","store_config","reset_to_factory_default",
115                              "set_com_interface_status","set_com_interface_max_bandwidth","set_verbose_mode","set_message_filtering","set_timing_packets",
116                              "get_local_time","use_ecu_id","use_session_id","use_timestamp","use_extended_header","set_default_log_level","set_default_trace_status",
117                              "get_software_version","message_buffer_overflow"
118                             };
119 static char *return_type[] = {"ok","not_supported","error","","","","","","no_matching_context_id"};
120
121 /* internal function definitions */
122 int dlt_buffer_get(DltBuffer *buf,unsigned char *data, int max_size,int delete);
123 int dlt_buffer_reset(DltBuffer *buf);
124 int dlt_buffer_increase_size(DltBuffer *buf);
125 int dlt_buffer_minimize_size(DltBuffer *buf);
126 void dlt_buffer_write_block(DltBuffer *buf,int *write, const unsigned char *data,unsigned int size);
127 void dlt_buffer_read_block(DltBuffer *buf,int *read,unsigned char *data,unsigned int size);     
128
129 void dlt_print_hex(uint8_t *ptr,int size)
130 {
131     int num;
132
133     if (ptr==0)
134     {
135         return;
136     }
137
138     for (num=0;num<size;num++)
139     {
140         if (num>0)
141         {
142             printf(" ");
143         }
144
145         printf("%.2x",((uint8_t*)ptr)[num]);
146     }
147 }
148
149 int dlt_print_hex_string(char *text,int textlength,uint8_t *ptr,int size)
150 {
151     int num;
152
153     if ((ptr==0) || (text==0) || (textlength<=0) || (size<0))
154     {
155         return -1;
156     }
157
158     /* Length 3: AB_ , A is first digit of hex number, B is second digit of hex number, _ is space */
159     if (textlength<(size*3))
160     {
161         dlt_log(LOG_ERR, "String does not fit binary data!\n");
162         return -1;
163     }
164
165     for (num=0;num<size;num++)
166     {
167         if (num>0)
168         {
169             sprintf(text," ");
170             text++;
171         }
172
173         sprintf(text,"%.2x",((uint8_t*)ptr)[num]);
174         text+=2; /* 2 chars */
175     }
176
177     return 0;
178 }
179
180 int dlt_print_mixed_string(char *text,int textlength,uint8_t *ptr,int size,int html)
181 {
182     int required_size = 0;
183     int lines, rest, i;
184
185     if ((ptr==0) || (text==0) || (textlength<=0) || (size<0))
186     {
187         return -1;
188     }
189
190     /* Check maximum required size and do a length check */
191     if (html==0)
192     {
193         required_size=(DLT_COMMON_HEX_LINELEN+(2*DLT_COMMON_HEX_CHARS+(DLT_COMMON_HEX_CHARS-1))+DLT_COMMON_CHARLEN+DLT_COMMON_HEX_CHARS+DLT_COMMON_CHARLEN) *
194                       ((size/DLT_COMMON_HEX_CHARS) + 1);
195         /* Example: (8 chars line number + (2*16 chars + 15 spaces) + space + 16 ascii chars + CR) *
196            ((size/16) lines + extra line for the rest) */
197     }
198     else
199     {
200         required_size=(DLT_COMMON_HEX_LINELEN+(2*DLT_COMMON_HEX_CHARS+(DLT_COMMON_HEX_CHARS-1))+DLT_COMMON_CHARLEN+DLT_COMMON_HEX_CHARS+4*DLT_COMMON_CHARLEN) *
201                       ((size/DLT_COMMON_HEX_CHARS) + 1);
202         /* Example: (8 chars line number + (2*16 chars + 15 spaces) + space + 16 ascii chars + 4 [HTML CR: <BR>]) *
203            ((size/16) lines + extra line for the rest) */
204     }
205
206     if (textlength<required_size)
207     {
208         sprintf(str, "String does not fit mixed data (available=%d, required=%d) !\n", textlength, required_size);
209         dlt_log(LOG_ERR, str);
210         return -1;
211     }
212
213     /* print full lines */
214     for (lines=0; lines< (size / DLT_COMMON_HEX_CHARS); lines++)
215     {
216         /* Line number */
217         sprintf(text,"%.6x: ",lines * DLT_COMMON_HEX_CHARS);
218         text+=DLT_COMMON_HEX_LINELEN; /* 'XXXXXX: ' */
219
220         /* Hex-Output */
221         /* It is not required to decrement textlength, as it was already checked, that
222            there is enough space for the complete output */
223         dlt_print_hex_string(text,textlength,(uint8_t*)(ptr+(lines*DLT_COMMON_HEX_CHARS)),DLT_COMMON_HEX_CHARS);
224         text+=((2*DLT_COMMON_HEX_CHARS)+(DLT_COMMON_HEX_CHARS-1)); /* 32 characters + 15 spaces */
225
226         sprintf(text," ");
227         text+=DLT_COMMON_CHARLEN;
228
229         /* Char-Output */
230         /* It is not required to decrement textlength, as it was already checked, that
231            there is enough space for the complete output */
232         dlt_print_char_string(&text,textlength,(uint8_t*)(ptr+(lines*DLT_COMMON_HEX_CHARS)),DLT_COMMON_HEX_CHARS);
233
234         if (html==0)
235         {
236             sprintf(text,"\n");
237             text+=DLT_COMMON_CHARLEN;
238         }
239         else
240         {
241             sprintf(text,"<BR>");
242             text+=(4*DLT_COMMON_CHARLEN);
243         }
244     }
245
246     /* print partial line */
247     rest = size % DLT_COMMON_HEX_CHARS;
248
249     if (rest>0)
250     {
251         /* Line number */
252         sprintf(text,"%.6x: ", (size / DLT_COMMON_HEX_CHARS) * DLT_COMMON_HEX_CHARS);
253         text+=DLT_COMMON_HEX_LINELEN; /* 'XXXXXX: ' */
254
255         /* Hex-Output */
256         /* It is not required to decrement textlength, as it was already checked, that
257            there is enough space for the complete output */
258         dlt_print_hex_string(text,textlength,(uint8_t*)(ptr+ ((size / DLT_COMMON_HEX_CHARS) * DLT_COMMON_HEX_CHARS)),rest);
259         text+=2*rest+(rest-1);
260
261         for (i=0;i<(DLT_COMMON_HEX_CHARS-rest);i++)
262         {
263             sprintf(text," xx");
264             text+=(3*DLT_COMMON_CHARLEN);
265         }
266
267         sprintf(text," ");
268         text+=DLT_COMMON_CHARLEN;
269
270         /* Char-Output */
271         /* It is not required to decrement textlength, as it was already checked, that
272            there is enough space for the complete output */
273         dlt_print_char_string(&text,textlength,(uint8_t*)(ptr+ ((size / DLT_COMMON_HEX_CHARS) * DLT_COMMON_HEX_CHARS)),rest);
274     }
275
276     return 0;
277 }
278
279 int dlt_print_char_string(char **text,int textlength,uint8_t *ptr,int size)
280 {
281     int num;
282
283     if (text==0)
284     {
285         return -1;
286     }
287
288     if ((ptr==0) || (*text==0) || (textlength<=0) || (size<0))
289     {
290         return -1;
291     }
292
293     if (textlength< size)
294     {
295         dlt_log(LOG_ERR, "String does not fit character data!\n");
296         return -1;
297     }
298
299     for (num=0;num<size;num++)
300     {
301         if ( (((char*)ptr)[num]<DLT_COMMON_ASCII_CHAR_SPACE) || (((char*)ptr)[num]>DLT_COMMON_ASCII_CHAR_TILDE) )
302         {
303             sprintf(*text,".");
304         }
305         else
306         {
307             /* replace < with . */
308             if (((char*)ptr)[num]!=DLT_COMMON_ASCII_CHAR_LT)
309             {
310                 sprintf(*text,"%c",((char *)ptr)[num]);
311             }
312             else
313             {
314                 sprintf(*text,".");
315             }
316         }
317         (*text)++;
318     }
319
320     return 0;
321 }
322
323 void dlt_print_id(char *text,const char *id)
324 {
325     int i, len;
326
327     if (text==0)
328     {
329         return;
330     }
331
332     /* Initialize text */
333     for (i=0; i<DLT_ID_SIZE; i++)
334     {
335         text[i]='-';
336     }
337
338     text[DLT_ID_SIZE] = 0;
339
340     len = ((strlen(id)<=DLT_ID_SIZE)?strlen(id):DLT_ID_SIZE);
341
342     /* Check id*/
343     for (i=0; i<len; i++)
344         text[i] = id[i];
345 }
346
347 void dlt_set_id(char *id,const char *text)
348 {
349     id[0] = 0;
350     id[1] = 0;
351     id[2] = 0;
352     id[3] = 0;
353
354     if (text==0)
355     {
356         return;
357     }
358
359     if (text[0]!=0)
360     {
361         id[0] = text[0];
362     }
363     else
364     {
365         return;
366     }
367
368     if (text[1]!=0)
369     {
370         id[1] = text[1];
371     }
372     else
373     {
374         return;
375     }
376
377     if (text[2]!=0)
378     {
379         id[2] = text[2];
380     }
381     else
382     {
383         return;
384     }
385
386     if (text[3]!=0)
387     {
388         id[3] = text[3];
389     }
390     else
391     {
392         return;
393     }
394 }
395
396 void dlt_clean_string(char *text,int length)
397 {
398     int num;
399
400     if (text==0)
401     {
402         return;
403     }
404
405     for (num=0;num<length;num++)
406     {
407         if (text[num]=='\r' || text[num]=='\n')
408         {
409             text[num] = ' ';
410         }
411     }
412 }
413
414 int dlt_filter_init(DltFilter *filter,int verbose)
415 {
416     PRINT_FUNCTION_VERBOSE(verbose);
417
418     if (filter==0)
419     {
420         return -1;
421     }
422
423     filter->counter = 0;
424
425     return 0;
426 }
427
428 int dlt_filter_free(DltFilter *filter,int verbose)
429 {
430     PRINT_FUNCTION_VERBOSE(verbose);
431
432     if (filter==0)
433     {
434         return -1;
435     }
436
437     return 0;
438 }
439
440 int dlt_filter_load(DltFilter *filter,const char *filename,int verbose)
441 {
442     FILE *handle;
443     char str1[DLT_COMMON_BUFFER_LENGTH];
444     char apid[DLT_ID_SIZE],ctid[DLT_ID_SIZE];
445
446     PRINT_FUNCTION_VERBOSE(verbose);
447
448     if (filter==0)
449     {
450         return -1;
451     }
452
453     handle = fopen(filename,"r");
454     if (handle == 0)
455     {
456         sprintf(str,"Filter file %s cannot be opened!\n",filename);
457         dlt_log(LOG_ERR, str);
458         return -1;
459     }
460
461     /* Reset filters */
462     filter->counter=0;
463
464     while (!feof(handle))
465     {
466         str1[0]=0;
467         if (fscanf(handle,"%s",str1)!=1)
468         {
469             break;
470         }
471         if (str1[0]==0)
472         {
473             break;
474         }
475         printf(" %s",str1);
476         if (strcmp(str1,"----")==0)
477         {
478             dlt_set_id(apid,"");
479         }
480         else
481         {
482             dlt_set_id(apid,str1);
483         }
484
485         str1[0]=0;
486         if (fscanf(handle,"%s",str1)!=1)
487         {
488             break;
489         }
490         if (str1[0]==0)
491         {
492             break;
493         }
494         printf(" %s\r\n",str1);
495         if (strcmp(str1,"----")==0)
496         {
497             dlt_set_id(ctid,"");
498         }
499         else
500         {
501             dlt_set_id(ctid,str1);
502         }
503
504         if (filter->counter<DLT_FILTER_MAX)
505         {
506             dlt_filter_add(filter,apid,ctid,verbose);
507         }
508         else
509         {
510             sprintf(str, "Maximum number (%d) of allowed filters reached!\n", DLT_FILTER_MAX);
511             dlt_log(LOG_ERR, str);
512             return 0;
513         }
514     }
515
516     fclose(handle);
517
518     return 0;
519 }
520
521 int dlt_filter_save(DltFilter *filter,const char *filename,int verbose)
522 {
523     FILE *handle;
524     int num;
525     char buf[DLT_COMMON_BUFFER_LENGTH];
526
527     PRINT_FUNCTION_VERBOSE(verbose);
528
529     if (filter==0)
530     {
531         return -1;
532     }
533
534     handle = fopen(filename,"w");
535     if (handle == 0)
536     {
537         sprintf(str,"Filter file %s cannot be opened!\n",filename);
538         dlt_log(LOG_ERR, str);
539         return -1;
540     }
541
542     for (num=0;num<filter->counter;num++)
543     {
544         if (filter->apid[num][0]==0)
545         {
546             fprintf(handle,"---- ");
547         }
548         else
549         {
550             dlt_print_id(buf,filter->apid[num]);
551             fprintf(handle,"%s ",buf);
552         }
553         if (filter->ctid[num][0]==0)
554         {
555             fprintf(handle,"---- ");
556         }
557         else
558         {
559             dlt_print_id(buf,filter->ctid[num]);
560             fprintf(handle,"%s ",buf);
561         }
562     }
563
564     fclose(handle);
565
566     return 0;
567 }
568
569 int dlt_filter_find(DltFilter *filter,const char *apid,const char *ctid, int verbose)
570 {
571     int num;
572
573     PRINT_FUNCTION_VERBOSE(verbose);
574
575     if ((filter==0) || (apid==0))
576     {
577         return -1;
578     }
579
580     for (num=0; num<filter->counter; num++)
581     {
582         if (memcmp(filter->apid[num],apid,DLT_ID_SIZE)==0)
583         {
584             /* apid matches, now check for ctid */
585             if (ctid==0)
586             {
587                 /* check if empty ctid matches */                
588                 //if (memcmp(filter->ctid[num],"",DLT_ID_SIZE)==0)//coverity complains here about Out-of-bounds access.
589                 char empty_ctid[DLT_ID_SIZE]="";
590                 if (memcmp(filter->ctid[num],empty_ctid,DLT_ID_SIZE)==0)
591                 {
592                     return num;
593                 }
594             }
595             else
596             {
597                 if (memcmp(filter->ctid[num],ctid,DLT_ID_SIZE)==0)
598                 {
599                     return num;
600                 }
601             }
602         }
603     }
604
605     return -1; /* Not found */
606 }
607
608 int dlt_filter_add(DltFilter *filter,const char *apid,const char *ctid, int verbose)
609 {
610     PRINT_FUNCTION_VERBOSE(verbose);
611
612     if ((filter==0) || (apid==0))
613     {
614         return -1;
615     }
616
617     if (filter->counter >= DLT_FILTER_MAX)
618     {
619         dlt_log(LOG_ERR, "Maximum numbers of allowed filters reached!\n");
620         return -1;
621     }
622
623     /* add each filter (apid, ctid) only once to filter array */
624     if (dlt_filter_find(filter,apid,ctid,verbose)<0)
625     {
626         /* filter not found, so add it to filter array */
627         if (filter->counter<DLT_FILTER_MAX)
628         {
629             dlt_set_id(filter->apid[filter->counter],apid);
630             dlt_set_id(filter->ctid[filter->counter],(ctid?ctid:""));
631
632             filter->counter++;
633
634             return 0;
635         }
636     }
637
638     return -1;
639 }
640
641 int dlt_filter_delete(DltFilter *filter,const char *apid,const char *ctid, int verbose)
642 {
643     int j,k;
644     int found=0;
645
646     PRINT_FUNCTION_VERBOSE(verbose);
647
648     if ((filter==0) || (apid==0))
649     {
650         return -1;
651     }
652
653     if (filter->counter>0)
654     {
655         /* Get first occurence of apid and ctid in filter array */
656         for (j=0; j<filter->counter; j++)
657         {
658             if ((memcmp(filter->apid[j],apid,DLT_ID_SIZE)==0) &&
659                 (memcmp(filter->ctid[j],ctid,DLT_ID_SIZE)==0)
660                )
661
662             {
663                 found=1;
664                 break;
665             }
666         }
667
668         if (found)
669         {
670             /* j is index */
671             /* Copy from j+1 til end to j til end-1 */
672
673             dlt_set_id(filter->apid[j],"");
674             dlt_set_id(filter->ctid[j],"");
675
676             for (k=j; k<(filter->counter-1); k++)
677             {
678                 dlt_set_id(filter->apid[k],filter->apid[k+1]);
679                 dlt_set_id(filter->ctid[k],filter->ctid[k+1]);
680             }
681
682             filter->counter--;
683             return 0;
684         }
685     }
686
687     return -1;
688 }
689
690 int dlt_message_init(DltMessage *msg,int verbose)
691 {
692     PRINT_FUNCTION_VERBOSE(verbose);
693
694     if (msg==0)
695     {
696         return -1;
697     }
698
699     /* initalise structure parameters */
700     msg->headersize = 0;
701     msg->datasize = 0;
702
703     msg->databuffer = 0;
704     msg->databuffersize = 0;
705
706     msg->storageheader = 0;
707     msg->standardheader = 0;
708     msg->extendedheader = 0;
709
710     msg->found_serialheader = 0;
711
712     return 0;
713 }
714
715 int dlt_message_free(DltMessage *msg,int verbose)
716 {
717     PRINT_FUNCTION_VERBOSE(verbose);
718
719     if (msg==0)
720     {
721         return -1;
722     }
723     /* delete databuffer if exists */
724     if (msg->databuffer)
725     {
726         free(msg->databuffer);
727         msg->databuffer = 0;
728         msg->databuffersize = 0;
729     }
730
731     return 0;
732 }
733
734 int dlt_message_header(DltMessage *msg,char *text,int textlength,int verbose)
735 {
736     return dlt_message_header_flags(msg,text,textlength,DLT_HEADER_SHOW_ALL,verbose);
737 }
738
739 int dlt_message_header_flags(DltMessage *msg,char *text,int textlength,int flags, int verbose)
740 {
741     struct tm * timeinfo;
742     char buffer [DLT_COMMON_BUFFER_LENGTH];
743
744     PRINT_FUNCTION_VERBOSE(verbose);
745
746     if ((msg==0) || (text==0) || (textlength<=0))
747     {
748         return -1;
749     }
750
751     if ((flags<DLT_HEADER_SHOW_NONE) || (flags>DLT_HEADER_SHOW_ALL))
752     {
753         return -1;
754     }
755
756     text[0] = 0;
757
758     if ((flags & DLT_HEADER_SHOW_TIME) == DLT_HEADER_SHOW_TIME)
759     {
760         /* print received time */
761         timeinfo = localtime ((const time_t*)(&(msg->storageheader->seconds)));
762
763         if (timeinfo!=0)
764         {
765             strftime (buffer,sizeof(buffer),"%Y/%m/%d %H:%M:%S",timeinfo);
766             sprintf(text,"%s.%.6d ",buffer,msg->storageheader->microseconds);
767         }
768     }
769
770     if ((flags & DLT_HEADER_SHOW_TMSTP) == DLT_HEADER_SHOW_TMSTP)
771     {
772         /* print timestamp if available */
773         if ( DLT_IS_HTYP_WTMS(msg->standardheader->htyp) )
774         {
775             sprintf(text+strlen(text),"%10u ",msg->headerextra.tmsp);
776         }
777         else
778         {
779             sprintf(text+strlen(text),"---------- ");
780         }
781     }
782
783     if ((flags & DLT_HEADER_SHOW_MSGCNT) == DLT_HEADER_SHOW_MSGCNT)
784     {
785         /* print message counter */
786         sprintf(text+strlen(text),"%.3d ",msg->standardheader->mcnt);
787     }
788
789     if ((flags & DLT_HEADER_SHOW_ECUID) == DLT_HEADER_SHOW_ECUID)
790     {
791         /* print ecu id, use header extra if available, else storage header value */
792         if ( DLT_IS_HTYP_WEID(msg->standardheader->htyp) )
793         {
794             dlt_print_id(text+strlen(text),msg->headerextra.ecu);
795         }
796         else
797         {
798             dlt_print_id(text+strlen(text),msg->storageheader->ecu);
799         }
800     }
801
802     /* print app id and context id if extended header available, else '----' */#
803     if ((flags & DLT_HEADER_SHOW_APID) == DLT_HEADER_SHOW_APID)
804     {
805         sprintf(text+strlen(text)," ");
806         if ((DLT_IS_HTYP_UEH(msg->standardheader->htyp)) && (msg->extendedheader->apid[0]!=0))
807         {
808             dlt_print_id(text+strlen(text),msg->extendedheader->apid);
809         }
810         else
811         {
812             sprintf(text+strlen(text),"----");
813         }
814
815         sprintf(text+strlen(text)," ");
816     }
817
818     if ((flags & DLT_HEADER_SHOW_CTID) == DLT_HEADER_SHOW_CTID)
819     {
820         if ((DLT_IS_HTYP_UEH(msg->standardheader->htyp)) && (msg->extendedheader->ctid[0]!=0))
821         {
822             dlt_print_id(text+strlen(text),msg->extendedheader->ctid);
823         }
824         else
825         {
826             sprintf(text+strlen(text),"----");
827         }
828
829         sprintf(text+strlen(text)," ");
830     }
831
832     /* print info about message type and length */
833     if (DLT_IS_HTYP_UEH(msg->standardheader->htyp))
834     {
835         if ((flags & DLT_HEADER_SHOW_MSGTYPE) == DLT_HEADER_SHOW_MSGTYPE)
836         {
837             sprintf(text+strlen(text),"%s",message_type[DLT_GET_MSIN_MSTP(msg->extendedheader->msin)]);
838             sprintf(text+strlen(text)," ");
839         }
840
841         if ((flags & DLT_HEADER_SHOW_MSGSUBTYPE) == DLT_HEADER_SHOW_MSGSUBTYPE)
842         {
843             if ((DLT_GET_MSIN_MSTP(msg->extendedheader->msin))==DLT_TYPE_LOG)
844             {
845                 sprintf(text+strlen(text),"%s",log_info[DLT_GET_MSIN_MTIN(msg->extendedheader->msin)]);
846             }
847
848             if ((DLT_GET_MSIN_MSTP(msg->extendedheader->msin))==DLT_TYPE_APP_TRACE)
849             {
850                 sprintf(text+strlen(text),"%s",trace_type[DLT_GET_MSIN_MTIN(msg->extendedheader->msin)]);
851             }
852
853             if ((DLT_GET_MSIN_MSTP(msg->extendedheader->msin))==DLT_TYPE_NW_TRACE)
854             {
855                 sprintf(text+strlen(text),"%s",nw_trace_type[DLT_GET_MSIN_MTIN(msg->extendedheader->msin)]);
856             }
857
858             if ((DLT_GET_MSIN_MSTP(msg->extendedheader->msin))==DLT_TYPE_CONTROL)
859             {
860                 sprintf(text+strlen(text),"%s",control_type[DLT_GET_MSIN_MTIN(msg->extendedheader->msin)]);
861             }
862
863             sprintf(text+strlen(text)," ");
864         }
865
866         if ((flags & DLT_HEADER_SHOW_VNVSTATUS) == DLT_HEADER_SHOW_VNVSTATUS)
867         {
868             /* print verbose status pf message */
869             if (DLT_IS_MSIN_VERB(msg->extendedheader->msin))
870             {
871                 sprintf(text+strlen(text),"V");
872             }
873             else
874             {
875                 sprintf(text+strlen(text),"N");
876             }
877
878             sprintf(text+strlen(text)," ");
879         }
880
881         if ((flags & DLT_HEADER_SHOW_NOARG) == DLT_HEADER_SHOW_NOARG)
882         {
883             /* print number of arguments */
884             sprintf(text+strlen(text),"%d", msg->extendedheader->noar);
885         }
886
887     }
888     else
889     {
890         if ((flags & DLT_HEADER_SHOW_MSGTYPE) == DLT_HEADER_SHOW_MSGTYPE)
891         {
892             sprintf(text+strlen(text),"--- ");
893         }
894
895         if ((flags & DLT_HEADER_SHOW_MSGSUBTYPE) == DLT_HEADER_SHOW_MSGSUBTYPE)
896         {
897             sprintf(text+strlen(text),"--- ");
898         }
899
900         if ((flags & DLT_HEADER_SHOW_VNVSTATUS) == DLT_HEADER_SHOW_VNVSTATUS)
901         {
902             sprintf(text+strlen(text),"N ");
903         }
904
905         if ((flags & DLT_HEADER_SHOW_NOARG) == DLT_HEADER_SHOW_NOARG)
906         {
907             sprintf(text+strlen(text),"-");
908         }
909     }
910
911     return 0;
912 }
913
914 int dlt_message_payload(DltMessage *msg,char *text,int textlength,int type,int verbose)
915 {
916     uint32_t id=0,id_tmp=0;
917     uint8_t retval=0;
918
919     uint8_t *ptr;
920     int32_t datalength;
921
922     /* Pointer to ptr and datalength */
923     uint8_t **pptr;
924     int32_t *pdatalength;
925
926     int ret=0;
927
928     int num;
929     uint32_t type_info=0,type_info_tmp=0;
930
931     PRINT_FUNCTION_VERBOSE(verbose);
932
933     if ((msg==0) || (text==0))
934     {
935         return -1;
936     }
937
938     if (textlength<=0)
939     {
940         dlt_log(LOG_ERR, "String does not fit binary data!\n");
941         return -1;
942     }
943
944     /* start with empty string */
945     text[0] = 0;
946
947     /* print payload only as hex */
948     if (type==DLT_OUTPUT_HEX)
949     {
950         return dlt_print_hex_string(text,textlength,msg->databuffer,msg->datasize);
951     }
952
953     /* print payload as mixed */
954     if (type==DLT_OUTPUT_MIXED_FOR_PLAIN)
955     {
956         return dlt_print_mixed_string(text,textlength,msg->databuffer,msg->datasize,0);
957     }
958
959     if (type==DLT_OUTPUT_MIXED_FOR_HTML)
960     {
961         return dlt_print_mixed_string(text,textlength,msg->databuffer,msg->datasize,1);
962     }
963
964     ptr = msg->databuffer;
965     datalength = msg->datasize;
966
967     /* Pointer to ptr and datalength */
968     pptr = &ptr;
969     pdatalength = &datalength;
970
971     /* non-verbose mode */
972
973     /* print payload as hex */
974     if (DLT_MSG_IS_NONVERBOSE(msg))
975     {
976
977         DLT_MSG_READ_VALUE(id_tmp,ptr,datalength,uint32_t);
978         id=DLT_ENDIAN_GET_32(msg->standardheader->htyp, id_tmp);
979
980         if (textlength<((datalength*3)+20))
981         {
982             dlt_log(LOG_ERR, "String does not fit binary data!\n");
983             return -1;
984         }
985
986         /* process message id / service id */
987         if (DLT_MSG_IS_CONTROL(msg))
988         {
989             if (id > 0 && id <= DLT_SERVICE_ID_MESSAGE_BUFFER_OVERFLOW)
990             {
991                 sprintf(text+strlen(text),"%s",service_id[id]); /* service id */
992             }
993             else
994             {
995                 if (!(DLT_MSG_IS_CONTROL_TIME(msg)))
996                 {
997                     sprintf(text+strlen(text),"service(%u)",id); /* service id */
998                 }
999             }
1000
1001             if (datalength>0)
1002             {
1003                 sprintf(text+strlen(text),", ");
1004             }
1005         }
1006         else
1007         {
1008             sprintf(text+strlen(text),"%u, ",id); /* message id */
1009         }
1010
1011         /* process return value */
1012         if (DLT_MSG_IS_CONTROL_RESPONSE(msg))
1013         {
1014             if (datalength>0)
1015             {
1016                 DLT_MSG_READ_VALUE(retval,ptr,datalength,uint8_t); /* No endian conversion necessary */
1017                 if ( (retval<3) || (retval==8))
1018                 {
1019                     sprintf(text+strlen(text),"%s",return_type[retval]);
1020                 }
1021                 else
1022                 {
1023                     sprintf(text+strlen(text),"%.2x",retval);
1024                 }
1025
1026                 if (datalength>=1)
1027                 {
1028                     sprintf(text+strlen(text),", ");
1029                 }
1030             }
1031         }
1032
1033         if (type==DLT_OUTPUT_ASCII_LIMITED)
1034         {
1035             ret=dlt_print_hex_string(text+strlen(text),textlength-strlen(text),ptr,
1036                                      (datalength>DLT_COMMON_ASCII_LIMIT_MAX_CHARS?DLT_COMMON_ASCII_LIMIT_MAX_CHARS:datalength));
1037             if ((datalength>DLT_COMMON_ASCII_LIMIT_MAX_CHARS) &&
1038                     ((textlength-strlen(text))>4))
1039             {
1040                 sprintf(text+strlen(text)," ...");
1041             }
1042         }
1043         else
1044         {
1045             ret=dlt_print_hex_string(text+strlen(text),textlength-strlen(text),ptr,datalength);
1046         }
1047
1048         return ret;
1049     }
1050
1051     /* At this point, it is ensured that a extended header is available */
1052
1053     /* verbose mode */
1054     type_info=0;
1055     type_info_tmp=0;
1056
1057     for (num=0;num<(int)(msg->extendedheader->noar);num++)
1058     {
1059         if (num!=0)
1060         {
1061             sprintf(text+strlen(text)," ");
1062         }
1063
1064         /* first read the type info of the argument */
1065         DLT_MSG_READ_VALUE(type_info_tmp,ptr,datalength,uint32_t);
1066         type_info=DLT_ENDIAN_GET_32(msg->standardheader->htyp, type_info_tmp);
1067
1068         /* print out argument */
1069         if (dlt_message_argument_print(msg, type_info, pptr, pdatalength, text, textlength, -1, 0)==-1)
1070         {
1071             return -1;
1072         }
1073     }
1074
1075     return 0;
1076 }
1077
1078 int dlt_message_filter_check(DltMessage *msg,DltFilter *filter,int verbose)
1079 {
1080     /* check the filters if message is used */
1081     int num;
1082     int found = 0;
1083
1084     PRINT_FUNCTION_VERBOSE(verbose);
1085
1086     if ((msg==0) || (filter==0))
1087     {
1088         return -1;
1089     }
1090
1091     if ((filter->counter==0) || (!(DLT_IS_HTYP_UEH(msg->standardheader->htyp))))
1092     {
1093         /* no filter is set, or no extended header is available, so do as filter is matching */
1094         return 1;
1095     }
1096
1097     for (num=0;num<filter->counter;num++)
1098     {
1099         /* check each filter if it matches */
1100         if ((DLT_IS_HTYP_UEH(msg->standardheader->htyp)) &&
1101                 (filter->apid[num][0]==0 || memcmp(filter->apid[num],msg->extendedheader->apid,DLT_ID_SIZE)==0) &&
1102                 (filter->ctid[num][0]==0 || memcmp(filter->ctid[num],msg->extendedheader->ctid,DLT_ID_SIZE)==0) )
1103         {
1104             found = 1;
1105             break;
1106         }
1107     }
1108
1109     return found;
1110 }
1111
1112 int dlt_message_read(DltMessage *msg,uint8_t *buffer,unsigned int length,int resync, int verbose)
1113 {
1114     int extra_size = 0;
1115
1116     PRINT_FUNCTION_VERBOSE(verbose);
1117
1118     if ((msg==0) || (buffer==0) || (length<=0))
1119     {
1120         return -1;
1121     }
1122
1123     /* initialize resync_offset */
1124     msg->resync_offset=0;
1125
1126     /* check if message contains serial header, smaller than standard header */
1127     if (length<sizeof(dltSerialHeader))
1128     {
1129         /* dlt_log(LOG_ERR, "Length smaller than serial header!\n"); */
1130         return -1;
1131     }
1132
1133     if (memcmp(buffer,dltSerialHeader,sizeof(dltSerialHeader)) == 0)
1134     {
1135         /* serial header found */
1136         msg->found_serialheader = 1;
1137         buffer += sizeof(dltSerialHeader);
1138         length -= sizeof(dltSerialHeader);
1139     }
1140     else
1141     {
1142         /* serial header not found */
1143         msg->found_serialheader = 0;
1144         if (resync)
1145         {
1146             /* resync if necessary */
1147             msg->resync_offset=0;
1148
1149             do
1150             {
1151                 if (memcmp(buffer+msg->resync_offset,dltSerialHeader,sizeof(dltSerialHeader)) == 0)
1152                 {
1153                     /* serial header found */
1154                     msg->found_serialheader = 1;
1155                     buffer += sizeof(dltSerialHeader);
1156                     length -= sizeof(dltSerialHeader);
1157                     break;
1158                 }
1159
1160                 msg->resync_offset++;
1161             }
1162             while ((sizeof(dltSerialHeader)+msg->resync_offset)<=length);
1163
1164             /* Set new start offset */
1165             if (msg->resync_offset>0)
1166             {
1167                 /* Resyncing connection */
1168                 buffer+=msg->resync_offset;
1169                 length-=msg->resync_offset;
1170             }
1171         }
1172     }
1173
1174     /* check that standard header fits buffer */
1175     if (length<sizeof(DltStandardHeader))
1176     {
1177         /* dlt_log(LOG_ERR, "Length smaller than standard header!\n"); */
1178         return -1;
1179     }
1180     memcpy(msg->headerbuffer+sizeof(DltStorageHeader),buffer,sizeof(DltStandardHeader));
1181
1182     /* set ptrs to structures */
1183     msg->storageheader = (DltStorageHeader*) msg->headerbuffer;
1184     msg->standardheader = (DltStandardHeader*) (msg->headerbuffer + sizeof(DltStorageHeader));
1185
1186     /* calculate complete size of headers */
1187     extra_size = DLT_STANDARD_HEADER_EXTRA_SIZE(msg->standardheader->htyp)+(DLT_IS_HTYP_UEH(msg->standardheader->htyp) ? sizeof(DltExtendedHeader) : 0);
1188     msg->headersize = sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + extra_size;
1189     msg->datasize =  DLT_BETOH_16(msg->standardheader->len) - (msg->headersize - sizeof(DltStorageHeader));
1190
1191     if (verbose)
1192     {
1193         sprintf(str,"Buffer length: %d\n",length);
1194         dlt_log(LOG_INFO, str);
1195     }
1196     if (verbose)
1197     {
1198         sprintf(str,"Header Size: %d\n",msg->headersize);
1199         dlt_log(LOG_INFO, str);
1200     }
1201     if (verbose)
1202     {
1203         sprintf(str,"Data Size: %d\n",msg->datasize);
1204         dlt_log(LOG_INFO, str);
1205     }
1206
1207     /* check data size */
1208     if (msg->datasize < 0)
1209     {
1210         sprintf(str,"Plausibility check failed. Complete message size too short (%d)!\n",msg->datasize);
1211         dlt_log(LOG_ERR, str);
1212         return -1;
1213     }
1214
1215     /* load standard header extra parameters and Extended header if used */
1216     if (extra_size>0)
1217     {
1218         if (length  < (msg->headersize - sizeof(DltStorageHeader)))
1219         {
1220             return -1;
1221         }
1222
1223         memcpy(msg->headerbuffer+sizeof(DltStorageHeader)+sizeof(DltStandardHeader),buffer+sizeof(DltStandardHeader),extra_size);
1224
1225         /* set extended header ptr and get standard header extra parameters */
1226         if (DLT_IS_HTYP_UEH(msg->standardheader->htyp))
1227         {
1228             msg->extendedheader = (DltExtendedHeader*) (msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) +
1229                                   DLT_STANDARD_HEADER_EXTRA_SIZE(msg->standardheader->htyp));
1230         }
1231         else
1232         {
1233             msg->extendedheader = 0;
1234         }
1235
1236         dlt_message_get_extraparameters(msg,verbose);
1237     }
1238
1239     /* check if payload fits length */
1240     if (length  < (msg->headersize - sizeof(DltStorageHeader) + msg->datasize))
1241     {
1242         /* dlt_log(LOG_ERR,"length does not fit!\n"); */
1243         return -1;
1244     }
1245
1246     /* free last used memory for buffer */
1247     if (msg->databuffer)
1248     {
1249         if (msg->datasize>msg->databuffersize){
1250                 free(msg->databuffer);
1251                 msg->databuffer=(uint8_t *)malloc(msg->datasize);
1252                 msg->databuffersize = msg->datasize;
1253         }
1254     }else{
1255         /* get new memory for buffer */
1256         msg->databuffer = (uint8_t *)malloc(msg->datasize);
1257         msg->databuffersize = msg->datasize;
1258     }
1259     if (msg->databuffer == 0)
1260     {
1261         sprintf(str,"Cannot allocate memory for payload buffer of size %d!\n",msg->datasize);
1262         dlt_log(LOG_ERR, str);
1263         return -1;
1264     }
1265
1266     /* load payload data from buffer */
1267     memcpy(msg->databuffer,buffer+(msg->headersize-sizeof(DltStorageHeader)),msg->datasize);
1268
1269     return 0;
1270 }
1271
1272 int dlt_message_get_extraparameters(DltMessage *msg,int verbose)
1273 {
1274     PRINT_FUNCTION_VERBOSE(verbose);
1275
1276     if (msg==0)
1277     {
1278         return -1;
1279     }
1280
1281     if (DLT_IS_HTYP_WEID(msg->standardheader->htyp))
1282     {
1283         memcpy(msg->headerextra.ecu,msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader),DLT_ID_SIZE);
1284     }
1285
1286     if (DLT_IS_HTYP_WSID(msg->standardheader->htyp))
1287     {
1288         memcpy(&(msg->headerextra.seid),msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader)
1289                + (DLT_IS_HTYP_WEID(msg->standardheader->htyp) ? DLT_SIZE_WEID : 0), DLT_SIZE_WSID);
1290         msg->headerextra.seid = DLT_BETOH_32(msg->headerextra.seid);
1291     }
1292
1293     if (DLT_IS_HTYP_WTMS(msg->standardheader->htyp))
1294     {
1295         memcpy(&(msg->headerextra.tmsp),msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader)
1296                + (DLT_IS_HTYP_WEID(msg->standardheader->htyp) ? DLT_SIZE_WEID : 0)
1297                + (DLT_IS_HTYP_WSID(msg->standardheader->htyp) ? DLT_SIZE_WSID : 0),DLT_SIZE_WTMS);
1298         msg->headerextra.tmsp = DLT_BETOH_32(msg->headerextra.tmsp);
1299     }
1300
1301     return 0;
1302 }
1303
1304 int dlt_message_set_extraparameters(DltMessage *msg,int verbose)
1305 {
1306     PRINT_FUNCTION_VERBOSE(verbose);
1307
1308     if (msg==0)
1309     {
1310         return -1;
1311     }
1312
1313     if (DLT_IS_HTYP_WEID(msg->standardheader->htyp))
1314     {
1315         memcpy(msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader),msg->headerextra.ecu,DLT_ID_SIZE);
1316     }
1317
1318     if (DLT_IS_HTYP_WSID(msg->standardheader->htyp))
1319     {
1320         msg->headerextra.seid = DLT_HTOBE_32(msg->headerextra.seid);
1321         memcpy(msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader)
1322                + (DLT_IS_HTYP_WEID(msg->standardheader->htyp) ? DLT_SIZE_WEID : 0), &(msg->headerextra.seid),DLT_SIZE_WSID);
1323     }
1324
1325     if (DLT_IS_HTYP_WTMS(msg->standardheader->htyp))
1326     {
1327         msg->headerextra.tmsp = DLT_HTOBE_32(msg->headerextra.tmsp);
1328         memcpy(msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader)
1329                + (DLT_IS_HTYP_WEID(msg->standardheader->htyp) ? DLT_SIZE_WEID : 0)
1330                + (DLT_IS_HTYP_WSID(msg->standardheader->htyp) ? DLT_SIZE_WSID : 0), &(msg->headerextra.tmsp),DLT_SIZE_WTMS);
1331     }
1332
1333     return 0;
1334 }
1335
1336 int dlt_file_init(DltFile *file,int verbose)
1337 {
1338     PRINT_FUNCTION_VERBOSE(verbose);
1339
1340     if (file==0)
1341     {
1342         return -1;
1343     }
1344
1345     /* initalise structure parameters */
1346     file->handle = 0;
1347     file->counter = 0;
1348     file->counter_total = 0;
1349     file->index = 0;
1350
1351     file->filter = 0;
1352     file->filter_counter = 0;
1353     file->file_position = 0;
1354
1355     file->position = 0;
1356
1357     file->error_messages = 0;
1358
1359     return dlt_message_init(&(file->msg),verbose);
1360 }
1361
1362 int dlt_file_set_filter(DltFile *file,DltFilter *filter,int verbose)
1363 {
1364     PRINT_FUNCTION_VERBOSE(verbose);
1365
1366     if (file==0)
1367     {
1368         return -1;
1369     }
1370
1371     /* set filter */
1372     file->filter = filter;
1373
1374     return 0;
1375 }
1376
1377 int dlt_file_read_header(DltFile *file,int verbose)
1378 {
1379     PRINT_FUNCTION_VERBOSE(verbose);
1380
1381     if (file==0)
1382     {
1383         return -1;
1384     }
1385
1386     /* load header from file */
1387     if (fread(file->msg.headerbuffer,sizeof(DltStorageHeader)+sizeof(DltStandardHeader),1,file->handle)!=1)
1388     {
1389         if (!feof(file->handle))
1390         {
1391             dlt_log(LOG_ERR, "Cannot read header from file!\n");
1392         }
1393         return -1;
1394     }
1395
1396     /* set ptrs to structures */
1397     file->msg.storageheader = (DltStorageHeader*) file->msg.headerbuffer;
1398     file->msg.standardheader = (DltStandardHeader*) (file->msg.headerbuffer + sizeof(DltStorageHeader));
1399
1400     /* check id of storage header */
1401     if (dlt_check_storageheader(file->msg.storageheader)==0)
1402     {
1403         dlt_log(LOG_ERR, "DLT storage header pattern not found!\n");
1404         return -1;
1405     }
1406
1407     /* calculate complete size of headers */
1408     file->msg.headersize = sizeof(DltStorageHeader) + sizeof(DltStandardHeader) +
1409                            DLT_STANDARD_HEADER_EXTRA_SIZE(file->msg.standardheader->htyp) + (DLT_IS_HTYP_UEH(file->msg.standardheader->htyp) ? sizeof(DltExtendedHeader) : 0);
1410     file->msg.datasize = DLT_BETOH_16(file->msg.standardheader->len) + sizeof(DltStorageHeader) - file->msg.headersize;
1411     if (verbose)
1412     {
1413         sprintf(str,"Header Size: %d\n",file->msg.headersize);
1414         dlt_log(LOG_INFO, str);
1415     }
1416     if (verbose)
1417     {
1418         sprintf(str,"Data Size: %d\n",file->msg.datasize);
1419         dlt_log(LOG_INFO, str);
1420     }
1421
1422     /* check data size */
1423     if (file->msg.datasize < 0)
1424     {
1425         sprintf(str,"Plausibility check failed. Complete message size too short! (%d)\n", file->msg.datasize);
1426         dlt_log(LOG_ERR, str);
1427         return -1;
1428     }
1429
1430     return 0;
1431 }
1432
1433 int dlt_file_read_header_raw(DltFile *file,int resync,int verbose)
1434 {
1435     char dltSerialHeaderBuffer[DLT_ID_SIZE];
1436
1437     PRINT_FUNCTION_VERBOSE(verbose);
1438
1439     if (file==0)
1440     {
1441         return -1;
1442     }
1443
1444     /* check if serial header exists, ignore if found */
1445     if (fread(dltSerialHeaderBuffer,sizeof(dltSerialHeaderBuffer),1,file->handle)!=1)
1446     {
1447         /* cannot read serial header, not enough data available in file */
1448         if (!feof(file->handle))
1449         {
1450             dlt_log(LOG_ERR, "Cannot read header from file!\n");
1451         }
1452         return -1;
1453     }
1454     if (memcmp(dltSerialHeaderBuffer,dltSerialHeader,sizeof(dltSerialHeader)) == 0)
1455     {
1456         /* serial header found */
1457         /* nothing to do continue reading */
1458
1459     }
1460     else
1461     {
1462         /* serial header not found */
1463         if(resync)
1464         {
1465             /* increase error counter */
1466             file->error_messages++;
1467
1468             /* resync to serial header */
1469             do
1470             {
1471                 memmove(dltSerialHeaderBuffer,dltSerialHeaderBuffer+1,sizeof(dltSerialHeader)-1);
1472                 if (fread(dltSerialHeaderBuffer+3,1,1,file->handle)!=1)
1473                 {
1474                     /* cannot read any data, perhaps end of file reached */
1475                     return -1;
1476                 }
1477                 if (memcmp(dltSerialHeaderBuffer,dltSerialHeader,sizeof(dltSerialHeader)) == 0)
1478                 {
1479                     /* serial header synchronised */
1480                     break;
1481                 }
1482             } while(1);
1483         }
1484         else
1485         {
1486             /* go back to last file position */
1487             if (0 != fseek(file->handle,file->file_position,SEEK_SET))
1488                 return -1;
1489         }
1490     }
1491
1492     /* load header from file */
1493     if (fread(file->msg.headerbuffer+sizeof(DltStorageHeader),sizeof(DltStandardHeader),1,file->handle)!=1)
1494     {
1495         if (!feof(file->handle))
1496         {
1497             dlt_log(LOG_ERR, "Cannot read header from file!\n");
1498         }
1499         return -1;
1500     }
1501
1502     /* set ptrs to structures */
1503     file->msg.storageheader = (DltStorageHeader*) file->msg.headerbuffer; // this points now to a empty storage header (filled with '0')
1504     file->msg.standardheader = (DltStandardHeader*) (file->msg.headerbuffer + sizeof(DltStorageHeader));
1505
1506     /* Skip storage header field, fill this field with '0' */
1507     memset(file->msg.storageheader,0,sizeof(DltStorageHeader));
1508
1509     /* Set storage header */
1510     dlt_set_storageheader(file->msg.storageheader,DLT_COMMON_DUMMY_ECUID);
1511
1512     /* no check for storage header id*/
1513
1514     /* calculate complete size of headers */
1515     file->msg.headersize = sizeof(DltStorageHeader) + sizeof(DltStandardHeader) +
1516                            DLT_STANDARD_HEADER_EXTRA_SIZE(file->msg.standardheader->htyp) + (DLT_IS_HTYP_UEH(file->msg.standardheader->htyp) ? sizeof(DltExtendedHeader) : 0);
1517     file->msg.datasize = DLT_BETOH_16(file->msg.standardheader->len) + sizeof(DltStorageHeader) - file->msg.headersize;
1518     if (verbose)
1519     {
1520         sprintf(str,"Header Size: %d\n",file->msg.headersize);
1521         dlt_log(LOG_INFO, str);
1522     }
1523     if (verbose)
1524     {
1525         sprintf(str,"Data Size: %d\n",file->msg.datasize);
1526         dlt_log(LOG_INFO, str);
1527     }
1528
1529     /* check data size */
1530     if (file->msg.datasize < 0)
1531     {
1532         sprintf(str,"Plausibility check failed. Complete message size too short! (%d)\n", file->msg.datasize);
1533         dlt_log(LOG_ERR, str);
1534         return -1;
1535     }
1536
1537     return 0;
1538 }
1539
1540 int dlt_file_read_header_extended(DltFile *file, int verbose)
1541 {
1542     PRINT_FUNCTION_VERBOSE(verbose);
1543
1544     if (file==0)
1545     {
1546         return -1;
1547     }
1548
1549     /* load standard header extra parameters if used */
1550     if (DLT_STANDARD_HEADER_EXTRA_SIZE(file->msg.standardheader->htyp))
1551     {
1552         if (fread(file->msg.headerbuffer+sizeof(DltStorageHeader)+sizeof(DltStandardHeader),
1553                   DLT_STANDARD_HEADER_EXTRA_SIZE(file->msg.standardheader->htyp),
1554                   1,file->handle)!=1)
1555         {
1556             dlt_log(LOG_ERR, "Cannot read standard header extra parameters from file!\n");
1557             return -1;
1558         }
1559
1560         dlt_message_get_extraparameters(&(file->msg),verbose);
1561     }
1562
1563     /* load Extended header if used */
1564     if (DLT_IS_HTYP_UEH(file->msg.standardheader->htyp)==0)
1565     {
1566         /* there is nothing to be loaded */
1567         return 0;
1568     }
1569
1570     if (fread(file->msg.headerbuffer+sizeof(DltStorageHeader)+sizeof(DltStandardHeader)+DLT_STANDARD_HEADER_EXTRA_SIZE(file->msg.standardheader->htyp),
1571               (DLT_IS_HTYP_UEH(file->msg.standardheader->htyp) ? sizeof(DltExtendedHeader) : 0),
1572               1,file->handle)!=1)
1573     {
1574         dlt_log(LOG_ERR, "Cannot read extended header from file!\n");
1575         return -1;
1576     }
1577
1578     /* set extended header ptr */
1579     if (DLT_IS_HTYP_UEH(file->msg.standardheader->htyp))
1580     {
1581         file->msg.extendedheader = (DltExtendedHeader*) (file->msg.headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) +
1582                                    DLT_STANDARD_HEADER_EXTRA_SIZE(file->msg.standardheader->htyp));
1583     }
1584     else
1585     {
1586         file->msg.extendedheader = 0;
1587     }
1588
1589     return 0;
1590 }
1591
1592 int dlt_file_read_data(DltFile *file, int verbose)
1593 {
1594     PRINT_FUNCTION_VERBOSE(verbose);
1595
1596     if (file==0)
1597     {
1598         return -1;
1599     }
1600
1601     /* free last used memory for buffer */
1602     if (file->msg.databuffer && (file->msg.databuffersize < file->msg.datasize))
1603     {
1604         free(file->msg.databuffer);
1605         file->msg.databuffer=0;
1606     }
1607
1608     if (file->msg.databuffer == 0){
1609         /* get new memory for buffer */
1610         file->msg.databuffer = (uint8_t *)malloc(file->msg.datasize);
1611         file->msg.databuffersize = file->msg.datasize;
1612     }
1613
1614     if (file->msg.databuffer == 0)
1615     {
1616         sprintf(str,"Cannot allocate memory for payload buffer of size %d!\n",file->msg.datasize);
1617         dlt_log(LOG_ERR, str);
1618         return -1;
1619     }
1620
1621     /* load payload data from file */
1622     if (fread(file->msg.databuffer,file->msg.datasize,1,file->handle)!=1)
1623     {
1624         if (file->msg.datasize!=0)
1625         {
1626             sprintf(str,"Cannot read payload data from file of size %d!\n",file->msg.datasize);
1627             dlt_log(LOG_ERR, str);
1628             return -1;
1629         }
1630     }
1631
1632     return 0;
1633 }
1634
1635 int dlt_file_open(DltFile *file,const char *filename,int verbose)
1636 {
1637     PRINT_FUNCTION_VERBOSE(verbose);
1638
1639     if (file==0)
1640     {
1641         return -1;
1642     }
1643
1644     /* reset counters */
1645     file->counter = 0;
1646     file->counter_total = 0;
1647     file->position = 0;
1648     file->file_position = 0;
1649     file->file_length = 0;
1650     file->error_messages = 0;
1651
1652     if (file->handle)
1653     {
1654         fclose(file->handle);
1655     }
1656
1657     /* open dlt file */
1658     file->handle = fopen(filename,"rb");
1659     if (file->handle == 0)
1660     {
1661         snprintf(str, DLT_COMMON_BUFFER_LENGTH - 1 ,"File %s cannot be opened!\n",filename);
1662
1663         dlt_log(LOG_ERR, str);
1664         return -1;
1665     }
1666
1667     if (0 != fseek(file->handle,0,SEEK_END))
1668     {
1669         sprintf(str,"dlt_file_open: Seek failed to 0,SEEK_END");
1670         dlt_log(LOG_ERR, str);
1671         return -1;
1672     }
1673     file->file_length = ftell(file->handle);
1674
1675     if (0 != fseek(file->handle,0,SEEK_SET))
1676     {
1677         sprintf(str,"dlt_file_open: Seek failed to 0,SEEK_SET");
1678         dlt_log(LOG_ERR, str);
1679         return -1;
1680     }
1681
1682     if (verbose)
1683     {
1684         /* print file length */
1685         sprintf(str,"File is %lu bytes long\n",file->file_length);
1686         dlt_log(LOG_INFO, str);
1687     }
1688     return 0;
1689 }
1690
1691 int dlt_file_read(DltFile *file,int verbose)
1692 {
1693     long *ptr;
1694     int found = 0;
1695
1696     if (verbose)
1697     {
1698         sprintf(str,"%s: Message %d:\n",__func__, file->counter_total);
1699         dlt_log(LOG_INFO, str);
1700     }
1701
1702     if (file==0)
1703     {
1704         return -1;
1705     }
1706
1707     /* allocate new memory for index if number of messages exceeds a multiple of DLT_COMMON_INDEX_ALLOC (e.g.: 1000) */
1708     if (file->counter % DLT_COMMON_INDEX_ALLOC == 0)
1709     {
1710         ptr = (long *) malloc(((file->counter/DLT_COMMON_INDEX_ALLOC) + 1) * DLT_COMMON_INDEX_ALLOC * sizeof(long));
1711
1712         if (ptr==0)
1713         {
1714             return -1;
1715         }
1716
1717         if (file->index)
1718         {
1719             memcpy(ptr,file->index,file->counter * sizeof(long));
1720             free(file->index);
1721         }
1722         file->index = ptr;
1723     }
1724
1725     /* set to end of last succesful read message, because of conflicting calls to dlt_file_read and dlt_file_message */
1726     if (0 !=  fseek(file->handle,file->file_position,SEEK_SET))
1727     {
1728         sprintf(str,"Seek failed to file_position %ld \n",file->file_position);
1729         dlt_log(LOG_ERR, str);
1730         return -1;
1731     }
1732
1733     /* get file position at start of DLT message */
1734     if (verbose)
1735     {
1736         sprintf(str,"Position in file: %ld\n",file->file_position);
1737         dlt_log(LOG_INFO, str);
1738     }
1739
1740     /* read header */
1741     if (dlt_file_read_header(file,verbose)<0)
1742     {
1743         /* go back to last position in file */
1744         fseek(file->handle,file->file_position,SEEK_SET);
1745         return -1;
1746     }
1747
1748     if (file->filter)
1749     {
1750         /* read the extended header if filter is enabled and extended header exists */
1751         if (dlt_file_read_header_extended(file, verbose)<0)
1752         {
1753             /* go back to last position in file */
1754             if (0 != fseek(file->handle,file->file_position,SEEK_SET))
1755             {
1756                 sprintf(str,"Seek to last file pos failed!\n");
1757                 dlt_log(LOG_ERR, str);
1758             }
1759             return-1;
1760         }
1761
1762         /* check the filters if message is used */
1763         if (dlt_message_filter_check(&(file->msg),file->filter,verbose) == 1)
1764         {
1765             /* filter matched, consequently store current message */
1766             /* store index pointer to message position in DLT file */
1767             file->index[file->counter] = file->file_position;
1768             file->counter++;
1769             file->position = file->counter - 1;
1770
1771             found = 1;
1772         }
1773
1774         /* skip payload data */
1775         if (fseek(file->handle,file->msg.datasize,SEEK_CUR)!=0)
1776         {
1777             /* go back to last position in file */
1778             sprintf(str,"Seek failed to skip payload data of size %d!\n",file->msg.datasize);
1779             dlt_log(LOG_ERR, str);
1780
1781             if (0 != fseek(file->handle,file->file_position,SEEK_SET))
1782             {
1783                 sprintf(str,"Seek back also failed!\n");
1784                 dlt_log(LOG_ERR, str);
1785             }
1786
1787             return -1;
1788         }
1789     }
1790     else
1791     {
1792         /* filter is disabled */
1793         /* skip additional header parameters and payload data */
1794         if (fseek(file->handle,file->msg.headersize - sizeof(DltStorageHeader) - sizeof(DltStandardHeader) + file->msg.datasize,SEEK_CUR))
1795         {
1796
1797             sprintf(str,"Seek failed to skip extra header and payload data from file of size %d!\n",
1798                     file->msg.headersize - sizeof(DltStorageHeader) - sizeof(DltStandardHeader) + file->msg.datasize);
1799             dlt_log(LOG_ERR, str);
1800             /* go back to last position in file */
1801             if (fseek(file->handle,file->file_position,SEEK_SET))
1802             {
1803                 sprintf(str,"Seek back also failed!\n");
1804                 dlt_log(LOG_ERR, str);
1805             }
1806             return -1;
1807         }
1808
1809         /* store index pointer to message position in DLT file */
1810         file->index[file->counter] = file->file_position;
1811         file->counter++;
1812         file->position = file->counter - 1;
1813
1814         found = 1;
1815     }
1816
1817     /* increase total message counter */
1818     file->counter_total++;
1819
1820     /* store position to next message */
1821     file->file_position = ftell(file->handle);
1822
1823     return found;
1824 }
1825
1826 int dlt_file_read_raw(DltFile *file,int resync, int verbose)
1827 {
1828     int found = 0;
1829     long *ptr;
1830
1831     if (verbose)
1832     {
1833         sprintf(str,"%s: Message %d:\n",__func__, file->counter_total);
1834         dlt_log(LOG_INFO, str);
1835     }
1836
1837     if (file==0)
1838         return -1;
1839
1840     /* allocate new memory for index if number of messages exceeds a multiple of DLT_COMMON_INDEX_ALLOC (e.g.: 1000) */
1841     if (file->counter % DLT_COMMON_INDEX_ALLOC == 0)
1842     {
1843         ptr = (long *) malloc(((file->counter/DLT_COMMON_INDEX_ALLOC) + 1) * DLT_COMMON_INDEX_ALLOC * sizeof(long));
1844
1845         if (ptr==0)
1846         {
1847             return -1;
1848         }
1849
1850         if (file->index)
1851         {
1852             memcpy(ptr,file->index,file->counter * sizeof(long));
1853             free(file->index);
1854         }
1855         file->index = ptr;
1856     }
1857
1858     /* set to end of last successful read message, because of conflicting calls to dlt_file_read and dlt_file_message */
1859     if (0 != fseek(file->handle,file->file_position,SEEK_SET))
1860         return -1;
1861
1862     /* get file position at start of DLT message */
1863     if (verbose)
1864     {
1865         sprintf(str,"Position in file: %ld\n",file->file_position);
1866         dlt_log(LOG_INFO, str);
1867     }
1868
1869     /* read header */
1870     if (dlt_file_read_header_raw(file,resync,verbose)<0)
1871     {
1872         /* go back to last position in file */
1873         if (0!= fseek(file->handle,file->file_position,SEEK_SET))
1874         {
1875             sprintf(str,"dlt_file_read_raw, fseek failed 1\n");
1876             dlt_log(LOG_ERR, str);
1877         }
1878         return -1;
1879     }
1880
1881     /* read the extended header if filter is enabled and extended header exists */
1882     if (dlt_file_read_header_extended(file, verbose)<0)
1883     {
1884         /* go back to last position in file */
1885         if (0 != fseek(file->handle,file->file_position,SEEK_SET))
1886         {
1887             sprintf(str,"dlt_file_read_raw, fseek failed 2\n");
1888             dlt_log(LOG_ERR, str);
1889         }
1890         return-1;
1891     }
1892
1893     if (dlt_file_read_data(file,verbose)<0)
1894     {
1895         /* go back to last position in file */
1896         if (0 != fseek(file->handle,file->file_position,SEEK_SET))
1897         {
1898             sprintf(str,"dlt_file_read_raw, fseek failed 3\n");
1899             dlt_log(LOG_ERR, str);
1900         }
1901         return-1;
1902     }
1903
1904     /* store index pointer to message position in DLT file */
1905     file->index[file->counter] = file->file_position;
1906     file->counter++;
1907     file->position = file->counter - 1;
1908
1909     found = 1;
1910
1911     /* increase total message counter */
1912     file->counter_total++;
1913
1914     /* store position to next message */
1915     file->file_position = ftell(file->handle);
1916
1917     return found;
1918 }
1919
1920 int dlt_file_close(DltFile *file,int verbose)
1921 {
1922     PRINT_FUNCTION_VERBOSE(verbose);
1923
1924     if (file==0)
1925     {
1926         return -1;
1927     }
1928
1929     if (file->handle)
1930     {
1931         fclose(file->handle);
1932     }
1933
1934     file->handle = 0;
1935
1936     return 0;
1937 }
1938
1939 int dlt_file_message(DltFile *file,int index,int verbose)
1940 {
1941     PRINT_FUNCTION_VERBOSE(verbose);
1942
1943     if (file==0)
1944     {
1945         return -1;
1946     }
1947
1948     /* check if message is in range */
1949     if (index >= file->counter)
1950     {
1951         sprintf(str,"Message %d out of range!\r\n",index);
1952         dlt_log(LOG_ERR, str);
1953         return -1;
1954     }
1955
1956     /* seek to position in file */
1957     if (fseek(file->handle,file->index[index],SEEK_SET)!=0)
1958     {
1959         sprintf(str,"Seek to message %d to position %ld failed!\r\n",index,file->index[index]);
1960         dlt_log(LOG_ERR, str);
1961         return -1;
1962     }
1963
1964     /* read all header and payload */
1965     if (dlt_file_read_header(file,verbose)<0)
1966     {
1967         return -1;
1968     }
1969
1970     if (dlt_file_read_header_extended(file,verbose)<0)
1971     {
1972         return -1;
1973     }
1974
1975     if (dlt_file_read_data(file,verbose)<0)
1976     {
1977         return -1;
1978     }
1979
1980     /* set current position in file */
1981     file->position = index;
1982
1983     return 0;
1984 }
1985
1986 int dlt_file_free(DltFile *file,int verbose)
1987 {
1988     PRINT_FUNCTION_VERBOSE(verbose);
1989
1990     if (file==0)
1991     {
1992         return -1;
1993     }
1994
1995     /* delete index lost if exists */
1996     if (file->index)
1997     {
1998         free(file->index);
1999     }
2000     file->index = 0;
2001
2002     /* close file */
2003     if (file->handle)
2004     {
2005         fclose(file->handle);
2006     }
2007     file->handle = 0;
2008
2009     return dlt_message_free(&(file->msg),verbose);
2010 }
2011
2012 void dlt_log_set_level(int level)
2013 {
2014         logging_level = level;
2015 }
2016
2017 void dlt_log_set_filename(const char *filename)
2018 {
2019         strncpy(logging_filename,filename,NAME_MAX);
2020
2021 }
2022
2023 void dlt_log_init(int mode)
2024 {
2025     logging_mode = mode;
2026     
2027         if(logging_mode == 2)
2028         {
2029                 /* internal logging to file */
2030                 logging_handle = fopen(logging_filename,"w");
2031                 if (logging_handle == 0)
2032                 {
2033                         printf("Internal log file %s cannot be opened!\n",logging_filename);
2034                         return;
2035                 }
2036         }
2037 }
2038
2039 void dlt_log_free(void)
2040 {
2041         if(logging_mode == 2) {
2042                 fclose(logging_handle);
2043         }
2044 }
2045
2046 int dlt_log(int prio, char *s)
2047 {
2048     char logfmtstring[DLT_COMMON_BUFFER_LENGTH];
2049
2050     if (s==0)
2051     {
2052         return -1;
2053     }
2054         if(logging_level<prio)
2055         {
2056                 return 0;
2057         }
2058
2059     switch (prio)
2060     {
2061         case    LOG_EMERG:
2062         {
2063             strncpy(logfmtstring,"DLT| EMERGENCY: %s",sizeof(logfmtstring));
2064             break;
2065         }
2066         case    LOG_ALERT:
2067         {
2068             strncpy(logfmtstring,"DLT| ALERT:     %s",sizeof(logfmtstring));
2069             break;
2070         }
2071         case    LOG_CRIT:
2072         {
2073             strncpy(logfmtstring,"DLT| CRITICAL:  %s",sizeof(logfmtstring));
2074             break;
2075         }
2076         case    LOG_ERR:
2077         {
2078             strncpy(logfmtstring,"DLT| ERROR:     %s",sizeof(logfmtstring));
2079             break;
2080         }
2081         case    LOG_WARNING:
2082         {
2083             strncpy(logfmtstring,"DLT| WARNING:   %s",sizeof(logfmtstring));
2084             break;
2085         }
2086         case    LOG_NOTICE:
2087         {
2088             strncpy(logfmtstring,"DLT| NOTICE:    %s",sizeof(logfmtstring));
2089             break;
2090         }
2091         case    LOG_INFO:
2092         {
2093             strncpy(logfmtstring,"DLT| INFO:      %s",sizeof(logfmtstring));
2094             break;
2095         }
2096         case    LOG_DEBUG:
2097         {
2098             strncpy(logfmtstring,"DLT| DEBUG:     %s",sizeof(logfmtstring));
2099             break;
2100         }
2101         default:
2102         {
2103             strncpy(logfmtstring,"DLT|            %s",sizeof(logfmtstring));
2104             break;
2105         }
2106     }
2107
2108         switch(logging_mode)
2109         {
2110                 case 0:
2111                         /* log to stdout */
2112                         printf(logfmtstring, s);
2113                         break;
2114                 case 1:
2115                         /* log to syslog */
2116 #if !defined (__WIN32__) && !defined(_MSC_VER)
2117                         openlog("DLT",LOG_PID,LOG_DAEMON);
2118                         syslog(prio, logfmtstring, s);
2119                         closelog();
2120 #endif
2121                         break;
2122                 case 2:
2123                         /* log to file */
2124                         if(logging_handle) {
2125                                 fprintf(logging_handle,logfmtstring, s);
2126                                 fflush(logging_handle);
2127                         }
2128                         break;
2129         }
2130
2131     return 0;
2132 }
2133
2134 int dlt_receiver_init(DltReceiver *receiver,int fd, int buffersize)
2135 {
2136     if (receiver==0)
2137     {
2138         return -1;
2139     }
2140
2141     receiver->lastBytesRcvd = 0;
2142     receiver->bytesRcvd = 0;
2143     receiver->totalBytesRcvd = 0;
2144     receiver->buffersize = buffersize;
2145     receiver->fd = fd;
2146     receiver->buffer = (char*)malloc(receiver->buffersize);
2147
2148     if (receiver->buffer == 0)
2149     {
2150         receiver->buf = 0;
2151         return -1;
2152     }
2153     else
2154     {
2155         receiver->buf = receiver->buffer;
2156     }
2157
2158     return 0;
2159 }
2160
2161 int dlt_receiver_free(DltReceiver *receiver)
2162 {
2163
2164     if (receiver==0)
2165     {
2166         return -1;
2167     }
2168
2169     if (receiver->buffer)
2170     {
2171         free(receiver->buffer);
2172     }
2173
2174     receiver->buffer = 0;
2175     receiver->buf = 0;
2176
2177     return 0;
2178 }
2179
2180 #ifndef QT_VIEWER
2181 int dlt_receiver_receive_socket(DltReceiver *receiver)
2182 {
2183     if (receiver==0)
2184     {
2185         return -1;
2186     }
2187
2188     if (receiver->buffer==0)
2189     {
2190         return -1;
2191     }
2192
2193     receiver->buf = (char *)receiver->buffer;
2194     receiver->lastBytesRcvd = receiver->bytesRcvd;
2195
2196     /* wait for data from socket */
2197     if ((receiver->bytesRcvd = recv(receiver->fd, receiver->buf + receiver->lastBytesRcvd, receiver->buffersize - receiver->lastBytesRcvd , 0)) <= 0)
2198     {
2199         receiver->bytesRcvd = 0;
2200
2201         return receiver->bytesRcvd;
2202     } /* if */
2203
2204     receiver->totalBytesRcvd += receiver->bytesRcvd;
2205     receiver->bytesRcvd += receiver->lastBytesRcvd;
2206
2207     return receiver->bytesRcvd;
2208 }
2209 #endif
2210
2211 int dlt_receiver_receive_fd(DltReceiver *receiver)
2212 {
2213     if (receiver==0)
2214     {
2215         return -1;
2216     }
2217
2218     if (receiver->buffer==0)
2219     {
2220         return -1;
2221     }
2222
2223     receiver->buf = (char *)receiver->buffer;
2224     receiver->lastBytesRcvd = receiver->bytesRcvd;
2225
2226     /* wait for data from fd */
2227     if ((receiver->bytesRcvd = read(receiver->fd, receiver->buf + receiver->lastBytesRcvd, receiver->buffersize - receiver->lastBytesRcvd)) <= 0)
2228     {
2229         receiver->bytesRcvd = 0;
2230
2231         return receiver->bytesRcvd;
2232     } /* if */
2233
2234     receiver->totalBytesRcvd += receiver->bytesRcvd;
2235     receiver->bytesRcvd += receiver->lastBytesRcvd;
2236
2237     return receiver->bytesRcvd;
2238 }
2239
2240 int dlt_receiver_remove(DltReceiver *receiver,int size)
2241 {
2242     if (receiver==0)
2243     {
2244         return -1;
2245     }
2246
2247     if (receiver->buf==0)
2248     {
2249         return -1;
2250     }
2251
2252     if (size > receiver->bytesRcvd || size <= 0)
2253     {
2254         receiver->buf = receiver->buf + receiver->bytesRcvd;
2255         receiver->bytesRcvd=0;
2256         return -1;
2257     }
2258
2259     receiver->bytesRcvd = receiver->bytesRcvd - size;
2260     receiver->buf = receiver->buf + size;
2261
2262     return 0;
2263 }
2264
2265 int dlt_receiver_move_to_begin(DltReceiver *receiver)
2266 {
2267     if (receiver==0)
2268     {
2269         return -1;
2270     }
2271
2272     if ((receiver->buffer==0) || (receiver->buf==0))
2273     {
2274         return -1;
2275     }
2276
2277     if ((receiver->buffer!=receiver->buf) && (receiver->bytesRcvd!=0))
2278     {
2279         memmove(receiver->buffer,receiver->buf,receiver->bytesRcvd);
2280     }
2281
2282     return 0;
2283 }
2284
2285 int dlt_set_storageheader(DltStorageHeader *storageheader, const char *ecu)
2286 {
2287
2288 #if !defined(_MSC_VER)
2289     struct timeval tv;
2290 #endif
2291
2292     if (storageheader==0)
2293     {
2294         return -1;
2295     }
2296
2297     /* get time of day */
2298 #if defined(_MSC_VER)
2299     time(&(storageheader->seconds));
2300 #else
2301     gettimeofday(&tv, NULL);
2302 #endif
2303
2304     /* prepare storage header */
2305     storageheader->pattern[0] = 'D';
2306     storageheader->pattern[1] = 'L';
2307     storageheader->pattern[2] = 'T';
2308     storageheader->pattern[3] = 0x01;
2309
2310     dlt_set_id(storageheader->ecu,ecu);
2311
2312     /* Set current time */
2313 #if defined(_MSC_VER)
2314     storageheader->microseconds = 0;
2315 #else
2316     storageheader->seconds = (time_t)tv.tv_sec; /* value is long */
2317     storageheader->microseconds = (int32_t)tv.tv_usec; /* value is long */
2318 #endif
2319
2320     return 0;
2321 }
2322
2323 int dlt_check_storageheader(DltStorageHeader *storageheader)
2324 {
2325     if (storageheader==0)
2326     {
2327         return -1;
2328     }
2329
2330     return  ((storageheader->pattern[0] == 'D') &&
2331              (storageheader->pattern[1] == 'L') &&
2332              (storageheader->pattern[2] == 'T') &&
2333              (storageheader->pattern[3] == 1));
2334 }
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347 int dlt_buffer_init_static_server(DltBuffer *buf, const unsigned char *ptr, uint32_t size)
2348 {
2349         char str[256];
2350         DltBufferHead *head;
2351
2352         // Init parameters
2353         buf->shm = (unsigned char *)ptr;
2354         buf->min_size = size;
2355         buf->max_size = size;
2356         buf->step_size = 0;
2357         
2358         // Init pointers
2359         head = (DltBufferHead*)buf->shm;
2360         head->read = 0;
2361         head->write = 0;
2362         head->count = 0;
2363     buf->mem = (unsigned char *)(buf->shm + sizeof(DltBufferHead));
2364         buf->size = buf->min_size - sizeof(DltBufferHead);
2365
2366         // clear memory
2367         memset(buf->mem,0,buf->size);
2368     
2369         snprintf(str,sizeof(str),"Buffer: Size %d\n",buf->size);
2370         dlt_log(LOG_INFO, str);
2371
2372         return 0; /* OK */
2373 }
2374
2375 int dlt_buffer_init_static_client(DltBuffer *buf, const unsigned char *ptr, uint32_t size)
2376 {
2377         char str[256];
2378
2379         // Init parameters
2380         buf->shm = (unsigned char *)ptr;
2381         buf->min_size = size;
2382         buf->max_size = size;
2383         buf->step_size = 0;
2384         
2385         // Init pointers
2386     buf->mem = (unsigned char *)(buf->shm + sizeof(DltBufferHead));
2387     buf->size = buf->min_size - sizeof(DltBufferHead);
2388
2389         snprintf(str,sizeof(str),"Buffer: Size %d\n",buf->size);
2390         dlt_log(LOG_INFO, str);
2391
2392         return 0; /* OK */
2393 }
2394
2395 int dlt_buffer_init_dynamic(DltBuffer *buf, uint32_t min_size, uint32_t max_size,uint32_t step_size)
2396 {
2397     //Do not DLT_SEM_LOCK inside here!
2398         char str[256];
2399         DltBufferHead *head;
2400
2401         // Init parameters
2402         buf->min_size = min_size;
2403         buf->max_size = max_size;
2404         buf->step_size = step_size;
2405
2406         // allocat memory
2407         buf->shm = malloc(buf->min_size);
2408         if(buf->shm == NULL) {
2409                 snprintf(str,sizeof(str),"Buffer: Cannot allocate %d bytes\n",buf->min_size);
2410                 dlt_log(LOG_EMERG, str);
2411                 return -1;
2412         }
2413         
2414         // Init pointers
2415         head = (DltBufferHead*)buf->shm;
2416         head->read = 0;
2417         head->write = 0;
2418         head->count = 0;
2419     buf->mem = (unsigned char *)(buf->shm + sizeof(DltBufferHead));
2420     buf->size = buf->min_size - sizeof(DltBufferHead);
2421
2422         // clear memory
2423         memset(buf->mem,0,buf->size);
2424     
2425         //snprintf(str,sizeof(str),"Buffer: Size %d bytes\n",buf->size);
2426         //dlt_log(LOG_INFO, str);
2427
2428         return 0; /* OK */
2429 }
2430
2431 int dlt_buffer_free_static(DltBuffer *buf)
2432 {
2433         if(!buf->mem) {
2434                 // buffer not initialised
2435                 dlt_log(LOG_ERR,"Buffer: Buffer not initialised\n");
2436                 return -1; /* ERROR */
2437         }
2438
2439         return 0;
2440 }
2441
2442 int dlt_buffer_free_dynamic(DltBuffer *buf)
2443 {
2444         if(!buf->mem) {
2445                 // buffer not initialised
2446                 dlt_log(LOG_ERR,"Buffer: Buffer not initialised\n");
2447                 return -1; /* ERROR */
2448         }
2449
2450         free(buf->shm);
2451         
2452         return 0;
2453 }
2454
2455 void dlt_buffer_write_block(DltBuffer *buf,int *write, const unsigned char *data,unsigned int size)
2456 {
2457         if((int)(*write+size) <= buf->size) {
2458                 // write one block
2459                 memcpy(buf->mem+*write,data,size);
2460                 *write += size;
2461         }
2462         else {
2463                 // write two blocks
2464                 memcpy(buf->mem+*write, data, buf->size-*write);
2465                 memcpy(buf->mem, data+buf->size-*write, size-buf->size+*write);
2466                 *write += size-buf->size;
2467         }       
2468 }
2469
2470 void dlt_buffer_read_block(DltBuffer *buf,int *read,unsigned char *data,unsigned int size)
2471 {
2472         if((int)(*read+size) <= buf->size) {
2473                 // read one block
2474                 memcpy(data,buf->mem+*read,size);
2475                 *read += size;
2476         }
2477         else {
2478                 // read two blocks
2479                 memcpy(data, buf->mem+*read, buf->size-*read);
2480                 memcpy(data+buf->size-*read, buf->mem, size-buf->size+*read);
2481                 *read += size-buf->size;
2482         }       
2483 }       
2484
2485 int dlt_buffer_increase_size(DltBuffer *buf)
2486 {
2487         DltBufferHead *head,*new_head;
2488         unsigned char *new_ptr;
2489
2490         /* check size */
2491         if(buf->step_size==0) {
2492                 /* cannot increase size */
2493                 return -1;
2494         }
2495
2496         /* check size */
2497         if((buf->size + sizeof(DltBufferHead) + buf->step_size) > buf->max_size) {
2498                 /* max size reached, do not increase */
2499                 return -1;
2500         }
2501
2502         /* allocate new buffer */
2503         new_ptr = malloc(buf->size + sizeof(DltBufferHead) + buf->step_size);
2504         if(new_ptr == NULL) {
2505                 snprintf(str,sizeof(str),"Buffer: Cannot increase size because allocate %d bytes failed\n",buf->min_size);
2506                 dlt_log(LOG_WARNING, str);
2507                 return -1;
2508         }
2509                 
2510         /* copy data */
2511         head = (DltBufferHead*)buf->shm;
2512         new_head = (DltBufferHead*)new_ptr;
2513         if(head->read < head->write) {
2514                 memcpy(new_ptr+sizeof(DltBufferHead) , buf->mem+head->read , head->write-head->read);
2515                 new_head->read = 0;     
2516                 new_head->write = head->write-head->read;       
2517                 new_head->count = head->count;  
2518         }
2519         else {
2520                 memcpy(new_ptr+sizeof(DltBufferHead) , buf->mem+head->read , buf->size-head->read);
2521                 memcpy(new_ptr+sizeof(DltBufferHead)+buf->size-head->read , buf->mem , head->write);
2522                 new_head->read = 0;     
2523                 new_head->write = buf->size-head->read+head->write;     
2524                 new_head->count = head->count;                  
2525         }
2526         
2527         /* free old data */
2528         free(buf->shm);
2529         
2530         /* update data */
2531         buf->shm = new_ptr;
2532         buf->mem = new_ptr+sizeof(DltBufferHead);
2533         buf->size += buf->step_size;
2534         
2535         snprintf(str,sizeof(str),"Buffer: Size increased to %d bytes\n",buf->size+sizeof(DltBufferHead));
2536         dlt_log(LOG_INFO, str);
2537
2538         return 0; // OK         
2539 }
2540
2541 int dlt_buffer_minimize_size(DltBuffer *buf)
2542 {
2543         unsigned char *new_ptr;
2544
2545         if((buf->size + sizeof(DltBufferHead)) == buf->min_size)
2546         {
2547                 /* already minimized */
2548                 return 0;
2549         }
2550
2551         /* allocate new buffer */
2552         new_ptr = malloc(buf->min_size);
2553         if(new_ptr == NULL) {
2554                 snprintf(str,sizeof(str),"Buffer: Cannot set to min size of %d bytes\n",buf->min_size);
2555                 dlt_log(LOG_WARNING, str);
2556                 return -1;
2557         }
2558
2559         /* free old data */
2560         free(buf->shm);
2561         
2562         /* update data */
2563         buf->shm = new_ptr;
2564         buf->mem = new_ptr+sizeof(DltBufferHead);
2565         buf->size = buf->min_size - sizeof(DltBufferHead);
2566
2567         /* reset pointers and counters */       
2568         ((int*)(buf->shm))[0] = 0;  // pointer to write memory  
2569         ((int*)(buf->shm))[1] = 0;  // pointer to read memory
2570         ((int*)(buf->shm))[2] = 0;  // number of packets
2571
2572         // clear memory
2573         memset(buf->mem,0,buf->size);
2574
2575         dlt_log(LOG_INFO,"Buffer: Buffer minimized.\n");
2576
2577         return 0; /* OK */      
2578 }
2579
2580 int dlt_buffer_reset(DltBuffer *buf)
2581 {
2582         dlt_log(LOG_ERR,"Buffer: Buffer reset triggered.\n");
2583
2584         /* reset pointers and counters */       
2585         ((int*)(buf->shm))[0] = 0;  // pointer to write memory  
2586         ((int*)(buf->shm))[1] = 0;  // pointer to read memory
2587         ((int*)(buf->shm))[2] = 0;  // number of packets
2588
2589         // clear memory
2590         memset(buf->mem,0,buf->size);
2591
2592         return 0; /* OK */
2593 }
2594
2595 int dlt_buffer_push(DltBuffer *buf,const unsigned char *data,unsigned int size)
2596 {
2597         return dlt_buffer_push3(buf,data,size,0,0,0,0);
2598 }
2599
2600 int dlt_buffer_push3(DltBuffer *buf,const unsigned char *data1,unsigned int size1,const unsigned char *data2,unsigned int size2,const unsigned char *data3,unsigned int size3)
2601 {
2602         int free_size;  
2603         int write, read, count;
2604         DltBufferBlockHead head;
2605         
2606         if(!buf->mem) {
2607                 // buffer not initialised
2608                 dlt_log(LOG_ERR,"Buffer: Buffer not initialised\n");
2609                 return -1; /* ERROR */
2610         }
2611
2612         // get current write pointer
2613         write = ((int*)(buf->shm))[0];
2614         read = ((int*)(buf->shm))[1];
2615         count = ((int*)(buf->shm))[2];
2616
2617         // check pointers
2618         if((read>buf->size) || (write>buf->size))
2619         {
2620                 dlt_log(LOG_ERR,"Buffer: Pointer out of range\n");
2621                 dlt_buffer_reset(buf);
2622                 return -1; // ERROR             
2623         }
2624
2625         // calculate free size
2626         if(read>write)
2627                 free_size = read - write;
2628         else if(count && (write == read))
2629                 free_size = 0;  
2630         else
2631                 free_size = buf->size - write + read;
2632         
2633         // check size
2634         if(free_size < (int)(sizeof(DltBufferBlockHead)+size1+size2+size3)) {
2635                 // try to increase size if possible
2636                 if(dlt_buffer_increase_size(buf)) {
2637                         /* increase size is not possible */
2638                         dlt_log(LOG_ERR,"Buffer: Buffer is full\n");
2639                         return -1; // ERROR
2640                 }
2641                 // update pointers
2642                 write = ((int*)(buf->shm))[0];
2643                 read = ((int*)(buf->shm))[1];
2644         }
2645
2646         // set header
2647         strcpy(head.head,DLT_BUFFER_HEAD);
2648         head.status = 2;
2649         head.size = size1+size2+size3;
2650
2651         // write data
2652         dlt_buffer_write_block(buf,&write,(unsigned char*)&head,sizeof(DltBufferBlockHead));
2653         if(size1) dlt_buffer_write_block(buf,&write,data1,size1);
2654         if(size2) dlt_buffer_write_block(buf,&write,data2,size2);
2655         if(size3) dlt_buffer_write_block(buf,&write,data3,size3);
2656
2657         // update global shm pointers
2658         ((int*)(buf->shm))[0] = write; // set new write pointer         
2659         ((int*)(buf->shm))[2] += 1; // increase counter
2660
2661         return 0; // OK
2662         
2663 }
2664
2665 int dlt_buffer_get(DltBuffer *buf,unsigned char *data, int max_size,int delete)
2666 {
2667         int used_size;  
2668         int write, read, count;
2669         char head_compare[] = DLT_BUFFER_HEAD;
2670         DltBufferBlockHead head;
2671         
2672         if(!buf->mem) {
2673                 // shm not initialised
2674                 dlt_log(LOG_ERR,"Buffer: SHM not initialised\n");
2675                 return -1; /* ERROR */
2676         }
2677
2678         // get current write pointer
2679         write = ((int*)(buf->shm))[0];
2680         read = ((int*)(buf->shm))[1];
2681         count = ((int*)(buf->shm))[2];
2682
2683         // check pointers
2684         if((read>buf->size) || (write>buf->size) || (count<0))
2685         {
2686                 dlt_log(LOG_ERR,"Buffer: Pointer out of range\n");
2687                 dlt_buffer_reset(buf);
2688                 return -1; // ERROR             
2689         }
2690
2691         // check if data is in there
2692         if(count==0) {
2693                 if(write!=read)
2694                 {
2695                         dlt_log(LOG_ERR,"Buffer: SHM should be empty, but is not\n");
2696                         dlt_buffer_reset(buf);
2697                 }
2698                 return -1; // ERROR             
2699         }
2700
2701         // calculate used size
2702         if(write>read)
2703                 used_size = write - read;
2704         else    
2705                 used_size = buf->size - read + write;
2706
2707         // first check size
2708         if(used_size < (int)(sizeof(DltBufferBlockHead))) {
2709                 dlt_log(LOG_ERR,"Buffer: Size check 1 failed\n");
2710                 dlt_buffer_reset(buf);
2711                 return -1; // ERROR
2712         }
2713
2714         // read header
2715         dlt_buffer_read_block(buf,&read,(unsigned char*)&head,sizeof(DltBufferBlockHead));
2716
2717         // check header
2718         if(memcmp((unsigned char*)(head.head),head_compare,sizeof(head_compare))!=0)
2719         {
2720                 dlt_log(LOG_ERR,"Buffer: Header head check failed\n");
2721                 dlt_buffer_reset(buf);
2722                 return -1; // ERROR
2723         }
2724         if(head.status != 2)
2725         {
2726                 dlt_log(LOG_ERR,"Buffer: Header status check failed\n");
2727                 dlt_buffer_reset(buf);
2728                 return -1; // ERROR
2729         }
2730
2731         // second check size
2732         if(used_size < (int)(sizeof(DltBufferBlockHead)+head.size)) {
2733                 dlt_log(LOG_ERR,"Buffer: Size check 2 failed\n");
2734                 dlt_buffer_reset(buf);
2735                 return -1; // ERROR
2736         }
2737
2738         // third check size
2739         if(max_size && (head.size > max_size)) {
2740                 dlt_log(LOG_ERR,"Buffer: Size check 3 failed\n");
2741                 // nothing to do but data does not fit provided buffer
2742         }
2743
2744         if(data && max_size)
2745         {
2746                 // read data
2747                 dlt_buffer_read_block(buf,&read,data,head.size);
2748
2749                 if(delete)
2750                 {
2751                         // update buffer pointers
2752                         ((int*)(buf->shm))[1] = read; // set new read pointer   
2753                 }
2754         }
2755         else
2756         {
2757                 if(delete) {
2758                         if( (read+head.size) <= buf->size)
2759                                 ((int*)(buf->shm))[1] = read+head.size; // set new read pointer         
2760                         else
2761                                 ((int*)(buf->shm))[1] = read+head.size-buf->size; // set new read pointer               
2762                 }
2763         }
2764         if(delete) {
2765                 ((int*)(buf->shm))[2] -= 1; // decrease counter
2766         
2767                 if(((int*)(buf->shm))[2] == 0)
2768                 {
2769                         // try to minimize size
2770                         dlt_buffer_minimize_size(buf);
2771                 }
2772         }
2773         
2774         return head.size; // OK 
2775 }
2776
2777 int dlt_buffer_pull(DltBuffer *buf,unsigned char *data, int max_size)
2778 {
2779         return dlt_buffer_get(buf,data,max_size,1);
2780 }
2781
2782 int dlt_buffer_copy(DltBuffer *buf,unsigned char *data, int max_size)
2783 {
2784         return dlt_buffer_get(buf,data,max_size,0);
2785 }
2786
2787 int dlt_buffer_remove(DltBuffer *buf)
2788 {
2789         return dlt_buffer_get(buf,0,0,1);
2790 }
2791
2792 void dlt_buffer_info(DltBuffer *buf)
2793 {
2794         char str[256];
2795
2796         snprintf(str,sizeof(str),"Buffer: Available size: %d\n",buf->size);
2797         dlt_log(LOG_INFO, str);
2798         snprintf(str,sizeof(str),"Buffer: Buffer full start address: %lX\n",(unsigned long)buf->shm);
2799         dlt_log(LOG_INFO, str);
2800         snprintf(str,sizeof(str),"Buffer: Buffer start address: %lX\n",(unsigned long)buf->mem);
2801         dlt_log(LOG_INFO, str);
2802         
2803 }
2804
2805 void dlt_buffer_status(DltBuffer *buf)
2806 {
2807         int write, read, count;
2808         char str[256];
2809
2810         write = ((int*)(buf->shm))[0];
2811         read = ((int*)(buf->shm))[1];
2812         count = ((int*)(buf->shm))[2];
2813
2814         snprintf(str,sizeof(str),"Buffer: Write: %d\n",write);
2815         dlt_log(LOG_INFO, str);
2816         snprintf(str,sizeof(str),"Buffer: Read: %d\n",read);
2817         dlt_log(LOG_INFO, str);
2818         snprintf(str,sizeof(str),"Buffer: Count: %d\n",count);
2819         dlt_log(LOG_INFO, str); 
2820 }
2821
2822 int dlt_buffer_get_total_size(DltBuffer *buf)
2823 {
2824         return buf->max_size;   
2825 }
2826
2827 int dlt_buffer_get_used_size(DltBuffer *buf)
2828 {
2829         int write, read, count;
2830
2831         write = ((int*)(buf->shm))[0];
2832         read = ((int*)(buf->shm))[1];
2833         count = ((int*)(buf->shm))[2];
2834
2835         if(count == 0)
2836                 return 0;
2837                 
2838         if(write>read)
2839                 return (write - read);
2840         
2841         return (buf->size - read + write);      
2842 }
2843
2844 int dlt_buffer_get_message_count(DltBuffer *buf)
2845 {
2846         return ((int*)(buf->shm))[2];
2847 }
2848
2849 #if !defined (__WIN32__)
2850
2851 int dlt_setup_serial(int fd, speed_t speed)
2852 {
2853 #if !defined (__WIN32__) && !defined(_MSC_VER)
2854     struct termios config;
2855
2856     if (isatty(fd)==0)
2857     {
2858         return -1;
2859     }
2860
2861     if (tcgetattr(fd, &config) < 0)
2862     {
2863         return -1;
2864     }
2865
2866     /* Input flags - Turn off input processing
2867        convert break to null byte, no CR to NL translation,
2868        no NL to CR translation, don't mark parity errors or breaks
2869        no input parity check, don't strip high bit off,
2870        no XON/XOFF software flow control
2871     */
2872     config.c_iflag &= ~(IGNBRK | BRKINT | ICRNL |
2873                         INLCR | PARMRK | INPCK | ISTRIP | IXON);
2874
2875     /* Output flags - Turn off output processing
2876        no CR to NL translation, no NL to CR-NL translation,
2877        no NL to CR translation, no column 0 CR suppression,
2878        no Ctrl-D suppression, no fill characters, no case mapping,
2879        no local output processing
2880
2881        config.c_oflag &= ~(OCRNL | ONLCR | ONLRET |
2882                            ONOCR | ONOEOT| OFILL | OLCUC | OPOST);
2883     */
2884     config.c_oflag = 0;
2885
2886     /* No line processing:
2887        echo off, echo newline off, canonical mode off,
2888        extended input processing off, signal chars off
2889     */
2890     config.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG);
2891
2892     /* Turn off character processing
2893        clear current char size mask, no parity checking,
2894        no output processing, force 8 bit input
2895     */
2896     config.c_cflag &= ~(CSIZE | PARENB);
2897     config.c_cflag |= CS8;
2898
2899     /* One input byte is enough to return from read()
2900        Inter-character timer off
2901     */
2902     config.c_cc[VMIN]  = 1;
2903     config.c_cc[VTIME] = 0;
2904
2905     /* Communication speed (simple version, using the predefined
2906        constants)
2907     */
2908     if (cfsetispeed(&config, speed) < 0 || cfsetospeed(&config, speed) < 0)
2909     {
2910         return -1;
2911     }
2912
2913     /* Finally, apply the configuration
2914     */
2915     if (tcsetattr(fd, TCSAFLUSH, &config) < 0)
2916     {
2917         return -1;
2918     }
2919
2920     return 0;
2921 #else
2922     return -1;
2923 #endif
2924 }
2925
2926 speed_t dlt_convert_serial_speed(int baudrate)
2927 {
2928 #if !defined (__WIN32__) && !defined(_MSC_VER)
2929     speed_t ret;
2930
2931     switch (baudrate)
2932     {
2933     case  50:
2934     {
2935         ret = B50;
2936         break;
2937     }
2938     case  75:
2939     {
2940         ret = B75;
2941         break;
2942     }
2943     case  110:
2944     {
2945         ret = B110;
2946         break;
2947     }
2948     case  134:
2949     {
2950         ret = B134;
2951         break;
2952     }
2953     case  150:
2954     {
2955         ret = B150;
2956         break;
2957     }
2958     case  200:
2959     {
2960         ret = B200;
2961         break;
2962     }
2963     case  300:
2964     {
2965         ret = B300;
2966         break;
2967     }
2968     case  600:
2969     {
2970         ret = B600;
2971         break;
2972     }
2973     case  1200:
2974     {
2975         ret = B1200;
2976         break;
2977     }
2978     case  1800:
2979     {
2980         ret = B1800;
2981         break;
2982     }
2983     case  2400:
2984     {
2985         ret = B2400;
2986         break;
2987     }
2988     case  4800:
2989     {
2990         ret = B4800;
2991         break;
2992     }
2993     case  9600:
2994     {
2995         ret = B9600;
2996         break;
2997     }
2998     case  19200:
2999     {
3000         ret = B19200;
3001         break;
3002     }
3003     case  38400:
3004     {
3005         ret = B38400;
3006         break;
3007     }
3008     case  57600:
3009     {
3010         ret = B57600;
3011         break;
3012     }
3013     case  115200:
3014     {
3015         ret = B115200;
3016         break;
3017     }
3018     case 230400:
3019     {
3020         ret = B230400;
3021         break;
3022     }
3023     case 460800:
3024     {
3025         ret = B460800;
3026         break;
3027     }
3028     case  500000:
3029     {
3030         ret = B500000;
3031         break;
3032     }
3033     case  576000:
3034     {
3035         ret = B576000;
3036         break;
3037     }
3038     case  921600:
3039     {
3040         ret = B921600;
3041         break;
3042     }
3043     case  1000000:
3044     {
3045         ret = B1000000;
3046         break;
3047     }
3048     case  1152000:
3049     {
3050         ret = B1152000;
3051         break;
3052     }
3053     case  1500000:
3054     {
3055         ret = B1500000;
3056         break;
3057     }
3058     case  2000000:
3059     {
3060         ret = B2000000;
3061         break;
3062     }
3063     case  2500000:
3064     {
3065         ret = B2500000;
3066         break;
3067     }
3068     case  3000000:
3069     {
3070         ret = B3000000;
3071         break;
3072     }
3073     case  3500000:
3074     {
3075         ret = B3500000;
3076         break;
3077     }
3078     case  4000000:
3079     {
3080         ret = B4000000;
3081         break;
3082     }
3083     default:
3084     {
3085         ret = B115200;
3086         break;
3087     }
3088     }
3089
3090     return ret;
3091 #else
3092     return 0;
3093 #endif
3094 }
3095
3096 #endif
3097
3098 void dlt_get_version(char *buf)
3099 {
3100     sprintf(buf,"DLT Package Version: %s %s, Package Revision: %s, build on %s %s\n%s %s %s %s\n",
3101             _DLT_PACKAGE_VERSION, _DLT_PACKAGE_VERSION_STATE, _DLT_PACKAGE_REVISION, __DATE__ , __TIME__,_DLT_SYSTEMD_ENABLE,_DLT_SYSTEMD_WATCHDOG_ENABLE,_DLT_TEST_ENABLE,_DLT_SHM_ENABLE );
3102 }
3103
3104 void dlt_get_major_version(char *buf)
3105 {
3106         sprintf(buf,"%s",_DLT_PACKAGE_MAJOR_VERSION);
3107 }
3108
3109 void dlt_get_minor_version(char *buf)
3110 {
3111     sprintf(buf,"%s",_DLT_PACKAGE_MINOR_VERSION);
3112 }
3113
3114
3115 uint32_t dlt_uptime(void)
3116 {
3117
3118 #if defined (__WIN32__) || defined(_MSC_VER)
3119
3120     return (uint32_t)(GetTickCount()*10); /* GetTickCount() return DWORD */
3121
3122 #else
3123     struct timespec ts;
3124
3125     if (clock_gettime(CLOCK_MONOTONIC,&ts)==0)
3126     {        
3127         return ( (uint32_t)ts.tv_sec*10000 + (uint32_t)ts.tv_nsec/100000 );// in 0.1 ms = 100 us
3128     }
3129     else
3130     {
3131         return 0;
3132     }
3133
3134 #endif
3135
3136 }
3137
3138 int dlt_message_print_header(DltMessage *message, char *text, uint32_t size, int verbose)
3139 {
3140     if ((message==0) || (text==0))
3141     {
3142         return -1;
3143     }
3144
3145     dlt_message_header(message,text,size,verbose);
3146     printf("%s\n",text);
3147
3148     return 0;
3149 }
3150
3151 int dlt_message_print_hex(DltMessage *message, char *text, uint32_t size, int verbose)
3152 {
3153     if ((message==0) || (text==0))
3154     {
3155         return -1;
3156     }
3157
3158     dlt_message_header(message,text,size,verbose);
3159     printf("%s ",text);
3160     dlt_message_payload(message,text,size,DLT_OUTPUT_HEX,verbose);
3161     printf("[%s]\n",text);
3162
3163     return 0;
3164 }
3165
3166 int dlt_message_print_ascii(DltMessage *message, char *text, uint32_t size, int verbose)
3167 {
3168     if ((message==0) || (text==0))
3169     {
3170         return -1;
3171     }
3172
3173     dlt_message_header(message,text,size,verbose);
3174     printf("%s ",text);
3175     dlt_message_payload(message,text,size,DLT_OUTPUT_ASCII,verbose);
3176     printf("[%s]\n",text);
3177
3178     return 0;
3179 }
3180
3181 int dlt_message_print_mixed_plain(DltMessage *message, char *text, uint32_t size, int verbose)
3182 {
3183     if ((message==0) || (text==0))
3184     {
3185         return -1;
3186     }
3187
3188     dlt_message_header(message,text,size,verbose);
3189     printf("%s \n",text);
3190     dlt_message_payload(message,text,size,DLT_OUTPUT_MIXED_FOR_PLAIN,verbose);
3191     printf("[%s]\n",text);
3192
3193     return 0;
3194 }
3195
3196 int dlt_message_print_mixed_html(DltMessage *message, char *text, uint32_t size, int verbose)
3197 {
3198     if ((message==0) || (text==0))
3199     {
3200         return -1;
3201     }
3202
3203     dlt_message_header(message,text,size,verbose);
3204     printf("%s \n",text);
3205     dlt_message_payload(message,text,size,DLT_OUTPUT_MIXED_FOR_HTML,verbose);
3206     printf("[%s]\n",text);
3207
3208     return 0;
3209 }
3210
3211 int dlt_message_argument_print(DltMessage *msg,uint32_t type_info,uint8_t **ptr,int32_t *datalength,char *text,int textlength,int byteLength,int __attribute__((unused)) verbose)
3212 {
3213     int16_t length=0,length_tmp=0; /* the macro can set this variable to -1 */
3214     uint16_t length2=0,length2_tmp=0,length3=0,length3_tmp=0;
3215
3216     uint8_t value8u=0;
3217     uint16_t value16u=0,value16u_tmp=0;
3218     uint32_t value32u=0,value32u_tmp=0;
3219     uint64_t value64u=0,value64u_tmp=0;
3220
3221     int8_t  value8i=0;
3222     int16_t value16i=0,value16i_tmp=0;
3223     int32_t value32i=0,value32i_tmp=0;
3224     int64_t value64i=0,value64i_tmp=0;
3225
3226     float32_t value32f=0,value32f_tmp=0;
3227     int32_t value32f_tmp_int32i=0,value32f_tmp_int32i_swaped=0;
3228     float64_t value64f=0,value64f_tmp=0;
3229     int64_t value64f_tmp_int64i=0,value64f_tmp_int64i_swaped=0;
3230
3231     uint32_t quantisation_tmp=0;
3232
3233     if (type_info & DLT_TYPE_INFO_STRG)
3234     {
3235
3236         /* string type */
3237         if (byteLength<0)
3238         {
3239             DLT_MSG_READ_VALUE(length_tmp,*ptr,*datalength,uint16_t);
3240             if((*datalength)<0)
3241                 return -1;
3242             length=DLT_ENDIAN_GET_16(msg->standardheader->htyp, length_tmp);
3243         }
3244         else
3245         {
3246             length=(int16_t)byteLength;
3247         }
3248
3249         if (type_info & DLT_TYPE_INFO_VARI)
3250         {
3251             DLT_MSG_READ_VALUE(length2_tmp,*ptr,*datalength,uint16_t);
3252             if((*datalength)<0)
3253                 return -1;
3254             length2=DLT_ENDIAN_GET_16(msg->standardheader->htyp, length2_tmp);
3255             if((*datalength)<length2)
3256                 return -1;
3257             *ptr += length2;
3258             *datalength-=length2;
3259         }
3260
3261         DLT_MSG_READ_STRING((text+strlen(text)),*ptr,*datalength,length);
3262         if((*datalength)<0)
3263             return -1;
3264
3265     }
3266     else if (type_info & DLT_TYPE_INFO_BOOL)
3267     {
3268         /* Boolean type */
3269         if (type_info & DLT_TYPE_INFO_VARI)
3270         {
3271             DLT_MSG_READ_VALUE(length2_tmp,*ptr,*datalength,uint16_t);
3272             if((*datalength)<0)
3273                 return -1;
3274             length2=DLT_ENDIAN_GET_16(msg->standardheader->htyp, length2_tmp);
3275             if((*datalength)<length2)
3276                 return -1;
3277             *ptr += length2;
3278             *datalength-=length2;
3279         }
3280         value8u=0;
3281         DLT_MSG_READ_VALUE(value8u,*ptr,*datalength,uint8_t); /* No endian conversion necessary */
3282         if((*datalength)<0)
3283             return -1;
3284         sprintf(text+strlen(text),"%d",value8u);
3285     }
3286     else if ((type_info & DLT_TYPE_INFO_SINT) || (type_info & DLT_TYPE_INFO_UINT))
3287     {
3288         /* signed or unsigned argument received */
3289         if (type_info & DLT_TYPE_INFO_VARI)
3290         {
3291             DLT_MSG_READ_VALUE(length2_tmp,*ptr,*datalength,uint16_t);
3292             if((*datalength)<0)
3293                 return -1;
3294             length2=DLT_ENDIAN_GET_16(msg->standardheader->htyp, length2_tmp);
3295             DLT_MSG_READ_VALUE(length3_tmp,*ptr,*datalength,uint16_t);
3296             if((*datalength)<0)
3297                 return -1;
3298             length3=DLT_ENDIAN_GET_16(msg->standardheader->htyp, length3_tmp);
3299             if((*datalength)<length2)
3300                 return -1;
3301             *ptr += length2;
3302             *datalength-=length2;
3303             if((*datalength)<length3)
3304                 return -1;
3305             *ptr += length3;
3306             *datalength-=length3;
3307         }
3308         if (type_info & DLT_TYPE_INFO_FIXP)
3309         {
3310             //compiler warning: variable â€˜quantisation_tmp’ set but not used [-Wunused-but-set-variable], but: DLT_MSG_READ_VALUE wants a parameter, "0" does not work
3311             DLT_MSG_READ_VALUE(quantisation_tmp,*ptr,*datalength,uint32_t);
3312
3313             if((*datalength)<0)
3314                 return -1;
3315             switch (    type_info & DLT_TYPE_INFO_TYLE)
3316             {
3317                                 case DLT_TYLE_8BIT:
3318                                 case DLT_TYLE_16BIT:
3319                                 case DLT_TYLE_32BIT:
3320                                 {
3321                     if((*datalength)<4)
3322                         return -1;
3323                     *ptr += 4;
3324                                         *datalength-=4;
3325                                         break;
3326                                 }
3327                                 case DLT_TYLE_64BIT:
3328                                 {
3329                     if((*datalength)<8)
3330                         return -1;
3331                     *ptr += 8;
3332                                         *datalength-=8;
3333                                         break;
3334                                 }
3335                                 case DLT_TYLE_128BIT:
3336                                 {
3337                     if((*datalength)<16)
3338                         return -1;
3339                     *ptr += 16;
3340                                         *datalength-=16;
3341                                         break;
3342                                 }
3343                                 default:
3344                                 {
3345                                         return -1;
3346                                 }
3347             }
3348         }
3349         switch (        type_info & DLT_TYPE_INFO_TYLE)
3350         {
3351                         case DLT_TYLE_8BIT:
3352                         {
3353                                 if (type_info & DLT_TYPE_INFO_SINT)
3354                                 {
3355                                         value8i=0;
3356                                         DLT_MSG_READ_VALUE(value8i,*ptr,*datalength,int8_t); /* No endian conversion necessary */
3357                     if((*datalength)<0)
3358                         return -1;
3359                     sprintf(text+strlen(text),"%d",value8i);
3360                                 }
3361                                 else
3362                                 {
3363                                         value8u=0;
3364                                         DLT_MSG_READ_VALUE(value8u,*ptr,*datalength,uint8_t); /* No endian conversion necessary */
3365                     if((*datalength)<0)
3366                         return -1;
3367                     sprintf(text+strlen(text),"%d",value8u);
3368                                 }
3369                                 break;
3370                         }
3371                         case DLT_TYLE_16BIT:
3372                         {
3373                                 if (type_info & DLT_TYPE_INFO_SINT)
3374                                 {
3375                                         value16i=0;
3376                                         value16i_tmp=0;
3377                                         DLT_MSG_READ_VALUE(value16i_tmp,*ptr,*datalength,int16_t);
3378                     if((*datalength)<0)
3379                         return -1;
3380                     value16i=DLT_ENDIAN_GET_16(msg->standardheader->htyp, value16i_tmp);
3381                                         sprintf(text+strlen(text),"%hd",value16i);
3382                                 }
3383                                 else
3384                                 {
3385                                         value16u=0;
3386                                         value16u_tmp=0;
3387                                         DLT_MSG_READ_VALUE(value16u_tmp,*ptr,*datalength,uint16_t);
3388                     if((*datalength)<0)
3389                         return -1;
3390                     value16u=DLT_ENDIAN_GET_16(msg->standardheader->htyp, value16u_tmp);
3391                                         sprintf(text+strlen(text),"%hu",value16u);
3392                                 }
3393                                 break;
3394                         }
3395                         case DLT_TYLE_32BIT:
3396                         {
3397                                 if (type_info & DLT_TYPE_INFO_SINT)
3398                                 {
3399                                         value32i=0;
3400                                         value32i_tmp=0;
3401                                         DLT_MSG_READ_VALUE(value32i_tmp,*ptr,*datalength,int32_t);
3402                     if((*datalength)<0)
3403                         return -1;
3404                     value32i=DLT_ENDIAN_GET_32(msg->standardheader->htyp, (uint32_t)value32i_tmp);
3405                                         sprintf(text+strlen(text),"%d",value32i);
3406                                 }
3407                                 else
3408                                 {
3409                                         value32u=0;
3410                                         value32u_tmp=0;
3411                                         DLT_MSG_READ_VALUE(value32u_tmp,*ptr,*datalength,uint32_t);
3412                     if((*datalength)<0)
3413                         return -1;
3414                     value32u=DLT_ENDIAN_GET_32(msg->standardheader->htyp, value32u_tmp);
3415                                         sprintf(text+strlen(text),"%u",value32u);
3416                                 }
3417                                 break;
3418                         }
3419                         case DLT_TYLE_64BIT:
3420                         {
3421                                 if (type_info & DLT_TYPE_INFO_SINT)
3422                                 {
3423                                         value64i=0;
3424                                         value64i_tmp=0;
3425                                         DLT_MSG_READ_VALUE(value64i_tmp,*ptr,*datalength,int64_t);
3426                     if((*datalength)<0)
3427                         return -1;
3428                     value64i=DLT_ENDIAN_GET_64(msg->standardheader->htyp, (uint64_t)value64i_tmp);
3429         #if defined (__WIN32__) && !defined(_MSC_VER)
3430                                         sprintf(text+strlen(text),"%I64d",value64i);
3431         #else
3432                                         sprintf(text+strlen(text),"%lld",value64i);
3433         #endif
3434                                 }
3435                                 else
3436                                 {
3437                                         value64u=0;
3438                                         value64u_tmp=0;
3439                                         DLT_MSG_READ_VALUE(value64u_tmp,*ptr,*datalength,uint64_t);
3440                     if((*datalength)<0)
3441                         return -1;
3442                     value64u=DLT_ENDIAN_GET_64(msg->standardheader->htyp, value64u_tmp);
3443         #if defined (__WIN32__) && !defined(_MSC_VER)
3444                                         sprintf(text+strlen(text),"%I64u",value64u);
3445         #else
3446                                         sprintf(text+strlen(text),"%llu",value64u);
3447         #endif
3448                                 }
3449                                 break;
3450                         }
3451                         case DLT_TYLE_128BIT:
3452                         {
3453                                 if (*datalength>=16)
3454                                         dlt_print_hex_string(text+strlen(text),textlength,*ptr,16);
3455                 if((*datalength)<16)
3456                     return -1;
3457                 *ptr += 16;
3458                                 *datalength-=16;
3459                                 break;
3460                         }
3461                         default:
3462                         {
3463                                 return -1;
3464                         }
3465         }
3466     }
3467     else if (type_info & DLT_TYPE_INFO_FLOA)
3468     {
3469         /* float data argument */
3470         if (type_info & DLT_TYPE_INFO_VARI)
3471         {
3472             DLT_MSG_READ_VALUE(length2_tmp,*ptr,*datalength,uint16_t);
3473             if((*datalength)<0)
3474                 return -1;
3475             length2=DLT_ENDIAN_GET_16(msg->standardheader->htyp, length2_tmp);
3476             DLT_MSG_READ_VALUE(length3_tmp,*ptr,*datalength,uint16_t);
3477             if((*datalength)<0)
3478                 return -1;
3479             length3=DLT_ENDIAN_GET_16(msg->standardheader->htyp, length3_tmp);
3480             if((*datalength)<length2)
3481                 return -1;
3482             *ptr += length2;
3483             *datalength-=length2;
3484             if((*datalength)<length3)
3485                 return -1;
3486             *ptr += length3;
3487             *datalength-=length3;
3488         }
3489         switch (        type_info & DLT_TYPE_INFO_TYLE)
3490         {
3491                         case DLT_TYLE_8BIT:
3492                         {
3493                                 if (*datalength>=1)
3494                                         dlt_print_hex_string(text+strlen(text),textlength,*ptr,1);
3495                 if((*datalength)<1)
3496                     return -1;
3497                 *ptr += 1;
3498                                 *datalength-=1;
3499                                 break;
3500                         }
3501                         case DLT_TYLE_16BIT:
3502                         {
3503                                 if (*datalength>=2)
3504                                         dlt_print_hex_string(text+strlen(text),textlength,*ptr,2);
3505                 if((*datalength)<2)
3506                     return -1;
3507                 *ptr += 2;
3508                                 *datalength-=2;
3509                                 break;
3510                         }
3511                         case DLT_TYLE_32BIT:
3512                         {
3513                                 if (sizeof(float32_t)==4)
3514                                 {
3515                                         value32f=0;
3516                                         value32f_tmp=0;
3517                                         value32f_tmp_int32i=0;
3518                                         value32f_tmp_int32i_swaped=0;
3519                                         DLT_MSG_READ_VALUE(value32f_tmp,*ptr,*datalength,float32_t);
3520                     if((*datalength)<0)
3521                         return -1;
3522                     memcpy(&value32f_tmp_int32i,&value32f_tmp,sizeof(float32_t));
3523                                         value32f_tmp_int32i_swaped=DLT_ENDIAN_GET_32(msg->standardheader->htyp, (uint32_t)value32f_tmp_int32i);
3524                                         memcpy(&value32f,&value32f_tmp_int32i_swaped,sizeof(float32_t));
3525                                         sprintf(text+strlen(text),"%g",value32f);
3526                                 }
3527                                 else
3528                                 {
3529                                         dlt_log(LOG_ERR, "Invalid size of float32_t\n");
3530                                         return -1;
3531                                 }
3532                                 break;
3533                         }
3534                         case DLT_TYLE_64BIT:
3535                         {
3536                                 if (sizeof(float64_t)==8)
3537                                 {
3538                                         value64f=0;
3539                                         value64f_tmp=0;
3540                                         value64f_tmp_int64i=0;
3541                                         value64f_tmp_int64i_swaped=0;
3542                                         DLT_MSG_READ_VALUE(value64f_tmp,*ptr,*datalength,float64_t);
3543                     if((*datalength)<0)
3544                         return -1;
3545                     memcpy(&value64f_tmp_int64i,&value64f_tmp,sizeof(float64_t));
3546                                         value64f_tmp_int64i_swaped=DLT_ENDIAN_GET_64(msg->standardheader->htyp, (uint64_t)value64f_tmp_int64i);
3547                                         memcpy(&value64f,&value64f_tmp_int64i_swaped,sizeof(float64_t));
3548 #ifdef __arm__
3549                                         sprintf(text+strlen(text),"ILLEGAL");
3550 #else
3551                                         sprintf(text+strlen(text),"%g",value64f);
3552 #endif
3553                                 }
3554                                 else
3555                                 {
3556                                         dlt_log(LOG_ERR, "Invalid size of float64_t\n");
3557                                         return -1;
3558                                 }
3559                                 break;
3560                         }
3561                         case DLT_TYLE_128BIT:
3562                         {
3563                                 if (*datalength>=16)
3564                                         dlt_print_hex_string(text+strlen(text),textlength,*ptr,16);
3565                 if((*datalength)<16)
3566                     return -1;
3567                 *ptr += 16;
3568                                 *datalength-=16;
3569                                 break;
3570                         }
3571                         default:
3572                         {
3573                                 return -1;
3574                         }
3575         }
3576
3577     }
3578     else if (type_info & DLT_TYPE_INFO_RAWD)
3579     {
3580         /* raw data argument */
3581         DLT_MSG_READ_VALUE(length_tmp,*ptr,*datalength,uint16_t);
3582         if((*datalength)<0)
3583             return -1;
3584         length=DLT_ENDIAN_GET_16(msg->standardheader->htyp, length_tmp);
3585         if (type_info & DLT_TYPE_INFO_VARI)
3586         {
3587             DLT_MSG_READ_VALUE(length2_tmp,*ptr,*datalength,uint16_t);
3588             if((*datalength)<0)
3589                 return -1;
3590             length2=DLT_ENDIAN_GET_16(msg->standardheader->htyp, length2_tmp);
3591             if((*datalength)<length2)
3592                 return -1;
3593             *ptr += length2;
3594             *datalength-=length2;
3595         }
3596         if((*datalength)<length)
3597             return -1;
3598         dlt_print_hex_string(text+strlen(text),textlength,*ptr,length);
3599         *ptr+=length;
3600         *datalength-=length;
3601     }
3602     else if (type_info & DLT_TYPE_INFO_TRAI)
3603     {
3604         /* trace info argument */
3605         DLT_MSG_READ_VALUE(length_tmp,*ptr,*datalength,uint16_t);
3606         if((*datalength)<0)
3607             return -1;
3608         length=DLT_ENDIAN_GET_16(msg->standardheader->htyp, length_tmp);
3609         DLT_MSG_READ_STRING((text+strlen(text)),*ptr,*datalength,length);
3610         if((*datalength)<0)
3611             return -1;
3612     }
3613     else
3614     {
3615         return -1;
3616     }
3617
3618     if (*datalength<0)
3619     {
3620         dlt_log(LOG_ERR, "Payload of DLT message corrupted\n");
3621         return -1;
3622     }
3623
3624     return 0;
3625 }