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