LCOV - code coverage report
Current view: top level - shared - dlt_common.c (source / functions) Coverage Total Hit
Test: dlt_final_coverage.info Lines: 62.1 % 1619 1005
Test Date: 2025-03-25 20:53:42 Functions: 85.3 % 95 81

            Line data    Source code
       1              : /*
       2              :  * SPDX license identifier: MPL-2.0
       3              :  *
       4              :  * Copyright (C) 2011-2015, BMW AG
       5              :  *
       6              :  * This file is part of COVESA Project DLT - Diagnostic Log and Trace.
       7              :  *
       8              :  * This Source Code Form is subject to the terms of the
       9              :  * Mozilla Public License (MPL), v. 2.0.
      10              :  * If a copy of the MPL was not distributed with this file,
      11              :  * You can obtain one at http://mozilla.org/MPL/2.0/.
      12              :  *
      13              :  * For further information see http://www.covesa.org/.
      14              :  */
      15              : 
      16              : /*!
      17              :  * \author
      18              :  * Alexander Wenzel <alexander.aw.wenzel@bmw.de>
      19              :  * Markus Klein <Markus.Klein@esk.fraunhofer.de>
      20              :  * Mikko Rapeli <mikko.rapeli@bmw.de>
      21              :  *
      22              :  * \copyright Copyright © 2011-2015 BMW AG. \n
      23              :  * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/.
      24              :  *
      25              :  * \file dlt_common.c
      26              :  */
      27              : 
      28              : #include <stdio.h>
      29              : #include <stdlib.h>   /* for malloc(), free() */
      30              : #include <string.h>   /* for strlen(), memcmp(), memmove() */
      31              : #include <time.h>     /* for localtime_r(), strftime() */
      32              : #include <limits.h>   /* for NAME_MAX */
      33              : #include <inttypes.h> /* for PRI formatting macro */
      34              : #include <stdarg.h>   /* va_list, va_start */
      35              : #include <err.h>
      36              : 
      37              : #include <errno.h>
      38              : #include <sys/stat.h> /* for mkdir() */
      39              : #include <sys/wait.h>
      40              : 
      41              : #include "dlt_user_shared.h"
      42              : #include "dlt_common.h"
      43              : #include "dlt_common_cfg.h"
      44              : #include "dlt_multiple_files.h"
      45              : 
      46              : #include "dlt_version.h"
      47              : 
      48              : #if defined (__WIN32__) || defined (_MSC_VER)
      49              : #   include <winsock2.h> /* for socket(), connect(), send(), and recv() */
      50              : #else
      51              : #   include <sys/socket.h> /* for socket(), connect(), send(), and recv() */
      52              : #   include <syslog.h>
      53              : #   include <time.h> /* for clock_gettime() */
      54              : #endif
      55              : 
      56              : #if defined (_MSC_VER)
      57              : #   include <io.h>
      58              : #else
      59              : #   include <unistd.h>  /* for read(), close() */
      60              : #   include <fcntl.h>
      61              : #   include <sys/time.h> /* for gettimeofday() */
      62              : #endif
      63              : 
      64              : #if defined (__MSDOS__) || defined (_MSC_VER)
      65              : #   pragma warning(disable : 4996) /* Switch off C4996 warnings */
      66              : #   include <windows.h>
      67              : #   include <winbase.h>
      68              : #endif
      69              : 
      70              : const char dltSerialHeader[DLT_ID_SIZE] = { 'D', 'L', 'S', 1 };
      71              : char dltSerialHeaderChar[DLT_ID_SIZE] = { 'D', 'L', 'S', 1 };
      72              : 
      73              : #if defined DLT_DAEMON_USE_FIFO_IPC || defined DLT_LIB_USE_FIFO_IPC
      74              : char dltFifoBaseDir[DLT_PATH_MAX] = "/tmp";
      75              : #endif
      76              : 
      77              : #ifdef DLT_SHM_ENABLE
      78              : char dltShmName[NAME_MAX + 1] = "/dlt-shm";
      79              : #endif
      80              : 
      81              : static bool print_with_attributes = false;
      82              : 
      83              : char *message_type[] = { "log", "app_trace", "nw_trace", "control", "", "", "", "" };
      84              : char *log_info[] = { "", "fatal", "error", "warn", "info", "debug", "verbose", "", "", "", "", "", "", "", "", "" };
      85              : char *trace_type[] = { "", "variable", "func_in", "func_out", "state", "vfb", "", "", "", "", "", "", "", "", "", "" };
      86              : char *nw_trace_type[] = { "", "ipc", "can", "flexray", "most", "vfb", "", "", "", "", "", "", "", "", "", "" };
      87              : char *control_type[] = { "", "request", "response", "time", "", "", "", "", "", "", "", "", "", "", "", "" };
      88              : static char *service_id_name[] =
      89              : { "", "set_log_level", "set_trace_status", "get_log_info", "get_default_log_level", "store_config",
      90              :   "reset_to_factory_default",
      91              :   "set_com_interface_status", "set_com_interface_max_bandwidth", "set_verbose_mode",
      92              :   "set_message_filtering", "set_timing_packets",
      93              :   "get_local_time", "use_ecu_id", "use_session_id", "use_timestamp", "use_extended_header",
      94              :   "set_default_log_level", "set_default_trace_status",
      95              :   "get_software_version", "message_buffer_overflow" };
      96              : static char *return_type[] =
      97              : { "ok", "not_supported", "error", "perm_denied", "warning", "", "", "", "no_matching_context_id" };
      98              : 
      99              : /* internal function definitions */
     100              : int dlt_buffer_get(DltBuffer *buf, unsigned char *data, int max_size, int delete);
     101              : int dlt_buffer_reset(DltBuffer *buf);
     102              : int dlt_buffer_increase_size(DltBuffer *buf);
     103              : int dlt_buffer_minimize_size(DltBuffer *buf);
     104              : void dlt_buffer_write_block(DltBuffer *buf, int *write, const unsigned char *data, unsigned int size);
     105              : void dlt_buffer_read_block(DltBuffer *buf, int *read, unsigned char *data, unsigned int size);
     106              : 
     107              : #ifdef DLT_TRACE_LOAD_CTRL_ENABLE
     108              : static int32_t dlt_output_soft_limit_over_warning(
     109              :     DltTraceLoadSettings* tl_settings,
     110              :     DltLogInternal log_internal,
     111              :     void *log_params);
     112              : 
     113              : static int32_t dlt_output_hard_limit_warning(
     114              :     DltTraceLoadSettings* tl_settings,
     115              :     DltLogInternal log_internal,
     116              :     void *log_params);
     117              : 
     118              : static bool dlt_user_cleanup_window(DltTraceLoadStat *tl_stat);
     119              : 
     120              : static int32_t dlt_switch_slot_if_needed(
     121              :     DltTraceLoadSettings* tl_settings,
     122              :     DltLogInternal log_internal,
     123              :     void *log_internal_params,
     124              :     uint32_t timestamp);
     125              : 
     126              : static void dlt_record_trace_load(DltTraceLoadStat *const tl_stat, int32_t size);
     127              : static inline bool dlt_is_over_trace_load_soft_limit(DltTraceLoadSettings* tl_settings);
     128              : static inline bool dlt_is_over_trace_load_hard_limit(DltTraceLoadSettings* tl_settings, int size);
     129              : #endif
     130              : 
     131            0 : void dlt_print_hex(uint8_t *ptr, int size)
     132              : {
     133              :     int num;
     134              : 
     135            0 :     if (ptr == NULL)
     136              :         return;
     137              : 
     138            0 :     for (num = 0; num < size; num++) {
     139            0 :         if (num > 0)
     140            0 :             dlt_user_printf(" ");
     141              : 
     142            0 :         dlt_user_printf("%.2x", ((uint8_t *)ptr)[num]);
     143              :     }
     144              : }
     145              : 
     146         2733 : static DltReturnValue dlt_print_hex_string_delim(char *text, int textlength, uint8_t *ptr, int size, char delim)
     147              : {
     148              :     int num;
     149              : 
     150         2733 :     if ((ptr == NULL) || (text == NULL) || (textlength <= 0) || (size < 0) || (delim == '\0'))
     151              :         return DLT_RETURN_WRONG_PARAMETER;
     152              : 
     153              :     /* Length 3: AB_ , A is first digit of hex number, B is second digit of hex number, _ is space */
     154         2730 :     if (textlength < (size * 3)) {
     155            0 :         dlt_vlog(LOG_WARNING,
     156              :                  "String does not fit hex data (available=%d, required=%d) !\n",
     157              :                  textlength, size * 3);
     158            0 :         return DLT_RETURN_ERROR;
     159              :     }
     160              : 
     161        36449 :     for (num = 0; num < size; num++) {
     162        33719 :         if (num > 0) {
     163        31017 :             snprintf(text, 2, "%c", delim);
     164        31017 :             text++;
     165              :         }
     166              : 
     167        33719 :         snprintf(text, 3, "%.2x", ((uint8_t *)ptr)[num]);
     168        33719 :         text += 2; /* 2 chars */
     169              :     }
     170              : 
     171              :     return DLT_RETURN_OK;
     172              : }
     173              : 
     174         2724 : DltReturnValue dlt_print_hex_string(char *text, int textlength, uint8_t *ptr, int size)
     175              : {
     176         2724 :     return dlt_print_hex_string_delim(text, textlength, ptr, size, ' ');
     177              : }
     178              : 
     179         1062 : DltReturnValue dlt_print_mixed_string(char *text, int textlength, uint8_t *ptr, int size, int html)
     180              : {
     181              :     int required_size = 0;
     182              :     int lines, rest, i;
     183              : 
     184         1062 :     if ((ptr == NULL) || (text == NULL) || (textlength <= 0) || (size < 0))
     185              :         return DLT_RETURN_WRONG_PARAMETER;
     186              : 
     187              :     /* Check maximum required size and do a length check */
     188         1056 :     if (html == 0)
     189          528 :         required_size =
     190              :             (DLT_COMMON_HEX_LINELEN + (2 * DLT_COMMON_HEX_CHARS + (DLT_COMMON_HEX_CHARS - 1)) + DLT_COMMON_CHARLEN +
     191              :              DLT_COMMON_HEX_CHARS + DLT_COMMON_CHARLEN) *
     192          528 :             ((size / DLT_COMMON_HEX_CHARS) + 1);
     193              :     /* Example: (8 chars line number + (2*16 chars + 15 spaces) + space + 16 ascii chars + CR) *
     194              :      * ((size/16) lines + extra line for the rest) */
     195              :     else
     196          528 :         required_size =
     197              :             (DLT_COMMON_HEX_LINELEN + (2 * DLT_COMMON_HEX_CHARS + (DLT_COMMON_HEX_CHARS - 1)) + DLT_COMMON_CHARLEN +
     198              :              DLT_COMMON_HEX_CHARS + 4 * DLT_COMMON_CHARLEN) *
     199          528 :             ((size / DLT_COMMON_HEX_CHARS) + 1);
     200              : 
     201              :     /* Example: (8 chars line number + (2*16 chars + 15 spaces) + space + 16 ascii chars + 4 [HTML CR: <BR>]) *
     202              :      * ((size/16) lines + extra line for the rest) */
     203              : 
     204         1056 :     if (textlength < required_size) {
     205            0 :         dlt_vlog(LOG_WARNING,
     206              :                  "String does not fit mixed data (available=%d, required=%d) !\n",
     207              :                  textlength, required_size);
     208            0 :         return DLT_RETURN_ERROR;
     209              :     }
     210              : 
     211              :     /* print full lines */
     212         1728 :     for (lines = 0; lines < (size / DLT_COMMON_HEX_CHARS); lines++) {
     213              :         int ret = 0;
     214              :         /* Line number */
     215          672 :         ret = snprintf(text, DLT_COMMON_HEX_LINELEN + 1, "%.6x: ", (uint32_t)lines * DLT_COMMON_HEX_CHARS);
     216              : 
     217          672 :         if ((ret < 0) || (ret >= (DLT_COMMON_HEX_LINELEN + 1)))
     218            0 :             dlt_log(LOG_WARNING, "line was truncated\n");
     219              : 
     220          672 :         text += DLT_COMMON_HEX_LINELEN; /* 'XXXXXX: ' */
     221              : 
     222              :         /* Hex-Output */
     223              :         /* It is not required to decrement textlength, as it was already checked, that
     224              :          * there is enough space for the complete output */
     225          672 :         if (dlt_print_hex_string(text, textlength,
     226          672 :                 (uint8_t *)(ptr + (lines * DLT_COMMON_HEX_CHARS)),
     227              :                 DLT_COMMON_HEX_CHARS) < DLT_RETURN_OK)
     228              :             return DLT_RETURN_ERROR;
     229          672 :         text += ((2 * DLT_COMMON_HEX_CHARS) + (DLT_COMMON_HEX_CHARS - 1)); /* 32 characters + 15 spaces */
     230              : 
     231              :         snprintf(text, 2, " ");
     232          672 :         text += DLT_COMMON_CHARLEN;
     233              : 
     234              :         /* Char-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          672 :         if (dlt_print_char_string(&text, textlength,
     238              :                 (uint8_t *)(ptr + (lines * DLT_COMMON_HEX_CHARS)),
     239              :                 DLT_COMMON_HEX_CHARS) < DLT_RETURN_OK)
     240              :             return DLT_RETURN_ERROR;
     241              : 
     242          672 :         if (html == 0) {
     243          336 :             snprintf(text, 2, "\n");
     244          336 :             text += DLT_COMMON_CHARLEN;
     245              :         }
     246              :         else {
     247          336 :             snprintf(text, 5, "<BR>");
     248          336 :             text += (4 * DLT_COMMON_CHARLEN);
     249              :         }
     250              :     }
     251              : 
     252              :     /* print partial line */
     253         1056 :     rest = size % DLT_COMMON_HEX_CHARS;
     254              : 
     255         1056 :     if (rest > 0) {
     256              :         /* Line number */
     257              :         int ret = 0;
     258          984 :         ret = snprintf(text, 9, "%.6x: ", (uint32_t)(size / DLT_COMMON_HEX_CHARS) * DLT_COMMON_HEX_CHARS);
     259              : 
     260          984 :         if ((ret < 0) || (ret >= 9))
     261            0 :             dlt_log(LOG_WARNING, "line number was truncated");
     262              : 
     263          984 :         text += DLT_COMMON_HEX_LINELEN; /* 'XXXXXX: ' */
     264              : 
     265              :         /* Hex-Output */
     266              :         /* It is not required to decrement textlength, as it was already checked, that
     267              :          * there is enough space for the complete output */
     268          984 :         if (dlt_print_hex_string(text,
     269              :                              textlength,
     270          984 :                              (uint8_t *)(ptr + ((size / DLT_COMMON_HEX_CHARS) * DLT_COMMON_HEX_CHARS)),
     271              :                              rest) < DLT_RETURN_OK)
     272              :             return DLT_RETURN_ERROR;
     273          984 :         text += 2 * rest + (rest - 1);
     274              : 
     275         9450 :         for (i = 0; i < (DLT_COMMON_HEX_CHARS - rest); i++) {
     276         8466 :             snprintf(text, 4, " xx");
     277         8466 :             text += (3 * DLT_COMMON_CHARLEN);
     278              :         }
     279              : 
     280          984 :         snprintf(text, 2, " ");
     281          984 :         text += DLT_COMMON_CHARLEN;
     282              : 
     283              :         /* Char-Output */
     284              :         /* It is not required to decrement textlength, as it was already checked, that
     285              :          * there is enough space for the complete output */
     286          984 :         if (dlt_print_char_string(&text, textlength,
     287              :                               (uint8_t *)(ptr + ((size / DLT_COMMON_HEX_CHARS) * DLT_COMMON_HEX_CHARS)),
     288              :                               rest) < DLT_RETURN_OK)
     289              :             return DLT_RETURN_ERROR;
     290              :     }
     291              : 
     292              :     return DLT_RETURN_OK;
     293              : }
     294              : 
     295         1661 : DltReturnValue dlt_print_char_string(char **text, int textlength, uint8_t *ptr, int size)
     296              : {
     297              :     int num;
     298              : 
     299         1661 :     if ((text == NULL) || (ptr == NULL) || (*text == NULL) || (textlength <= 0) || (size < 0))
     300              :         return DLT_RETURN_WRONG_PARAMETER;
     301              : 
     302         1658 :     if (textlength < size) {
     303            0 :         dlt_vlog(LOG_WARNING,
     304              :                  "String does not fit character data (available=%d, required=%d) !\n",
     305              :                  textlength, size);
     306            0 :         return DLT_RETURN_WRONG_PARAMETER;
     307              :     }
     308              : 
     309        19729 :     for (num = 0; num < size; num++) {
     310        18071 :         if ((((char *)ptr)[num] < DLT_COMMON_ASCII_CHAR_SPACE) || (((char *)ptr)[num] > DLT_COMMON_ASCII_CHAR_TILDE)) {
     311        10240 :             snprintf(*text, 2, ".");
     312              :         }
     313              :         else {
     314              :             /* replace < with . */
     315         7831 :             if (((char *)ptr)[num] != DLT_COMMON_ASCII_CHAR_LT)
     316         7831 :                 snprintf(*text, 2, "%c", ((char *)ptr)[num]);
     317              :             else
     318            0 :                 snprintf(*text, 2, ".");
     319              :         }
     320              : 
     321        18071 :         (*text)++;
     322              :     }
     323              : 
     324              :     return DLT_RETURN_OK;
     325              : }
     326              : 
     327         5622 : size_t dlt_strnlen_s(const char* str, size_t maxsize)
     328              : {
     329         5622 :     if (str == NULL)
     330              :         return 0;
     331              : 
     332        24796 :     for (size_t i = 0; i < maxsize; ++i) {
     333        22517 :         if (str[i] == '\0')
     334         3342 :             return i;
     335              :     }
     336              :     return maxsize;
     337              : }
     338              : 
     339         5620 : void dlt_print_id(char *text, const char *id)
     340              : {
     341              :     /* check nullpointer */
     342         5620 :     if ((text == NULL) || (id == NULL))
     343              :         return;
     344              : 
     345              :     /* Initialize text */
     346              :     memset(text, '-', DLT_ID_SIZE);
     347              : 
     348         5617 :     text[DLT_ID_SIZE] = 0;
     349              : 
     350         5617 :     size_t len = dlt_strnlen_s(id, DLT_ID_SIZE);
     351              : 
     352              :     memcpy(text, id, len);
     353              : }
     354              : 
     355        86171 : void dlt_set_id(char *id, const char *text)
     356              : {
     357              :     /* check nullpointer */
     358        86171 :     if ((id == NULL) || (text == NULL))
     359              :         return;
     360              : 
     361        86168 :     id[0] = 0;
     362        86168 :     id[1] = 0;
     363        86168 :     id[2] = 0;
     364        79627 :     id[3] = 0;
     365              : 
     366        86168 :     if (text[0] != 0)
     367        53974 :         id[0] = text[0];
     368              :     else
     369              :         return;
     370              : 
     371        53974 :     if (text[1] != 0)
     372        53968 :         id[1] = text[1];
     373              :     else
     374              :         return;
     375              : 
     376        53968 :     if (text[2] != 0)
     377        53960 :         id[2] = text[2];
     378              :     else
     379              :         return;
     380              : 
     381        53960 :     if (text[3] != 0)
     382        53783 :         id[3] = text[3];
     383              :     else
     384              :         return;
     385              : }
     386              : 
     387         1159 : void dlt_clean_string(char *text, int length)
     388              : {
     389              :     int num;
     390              : 
     391         1159 :     if (text == NULL)
     392              :         return;
     393              : 
     394        10286 :     for (num = 0; num < length; num++)
     395         9127 :         if ((text[num] == '\r') || (text[num] == '\n'))
     396            0 :             text[num] = ' ';
     397              : }
     398              : 
     399            7 : DltReturnValue dlt_filter_init(DltFilter *filter, int verbose)
     400              : {
     401            7 :     PRINT_FUNCTION_VERBOSE(verbose);
     402              : 
     403            7 :     if (filter == NULL)
     404              :         return DLT_RETURN_WRONG_PARAMETER;
     405              : 
     406            7 :     filter->counter = 0;
     407              : 
     408            7 :     return DLT_RETURN_OK;
     409              : }
     410              : 
     411            1 : DltReturnValue dlt_filter_free(DltFilter *filter, int verbose)
     412              : {
     413            1 :     PRINT_FUNCTION_VERBOSE(verbose);
     414              : 
     415            1 :     if (filter == NULL)
     416            0 :         return DLT_RETURN_WRONG_PARAMETER;
     417              : 
     418              :     return DLT_RETURN_OK;
     419              : }
     420              : 
     421            6 : DltReturnValue dlt_filter_load(DltFilter *filter, const char *filename, int verbose)
     422              : {
     423            6 :     if ((filter == NULL) || (filename == NULL))
     424              :         return DLT_RETURN_WRONG_PARAMETER;
     425              : 
     426              :     FILE *handle;
     427              :     char str1[DLT_COMMON_BUFFER_LENGTH + 1];
     428              :     char apid[DLT_ID_SIZE], ctid[DLT_ID_SIZE];
     429              : 
     430            6 :     PRINT_FUNCTION_VERBOSE(verbose);
     431              : 
     432            6 :     handle = fopen(filename, "r");
     433              : 
     434            6 :     if (handle == NULL) {
     435            0 :         dlt_vlog(LOG_WARNING, "Filter file %s cannot be opened!\n", filename);
     436            0 :         return DLT_RETURN_ERROR;
     437              :     }
     438              : 
     439              :     #define FORMAT_STRING_(x) "%" #x "s"
     440              :     #define FORMAT_STRING(x) FORMAT_STRING_(x)
     441              : 
     442              :     /* Reset filters */
     443            6 :     filter->counter = 0;
     444              : 
     445           18 :     while (!feof(handle)) {
     446           18 :         str1[0] = 0;
     447              : 
     448           18 :         if (fscanf(handle, FORMAT_STRING(DLT_COMMON_BUFFER_LENGTH), str1) != 1)
     449              :             break;
     450              : 
     451           12 :         if (str1[0] == 0)
     452              :             break;
     453              : 
     454              :         printf(" %s", str1);
     455              : 
     456           12 :         if (strcmp(str1, "----") == 0)
     457            0 :             dlt_set_id(apid, "");
     458              :         else
     459           12 :             dlt_set_id(apid, str1);
     460              : 
     461           12 :         str1[0] = 0;
     462              : 
     463           12 :         if (fscanf(handle, FORMAT_STRING(DLT_COMMON_BUFFER_LENGTH), str1) != 1)
     464              :             break;
     465              : 
     466           12 :         if (str1[0] == 0)
     467              :             break;
     468              : 
     469              :         printf(" %s\r\n", str1);
     470              : 
     471           12 :         if (strcmp(str1, "----") == 0)
     472            0 :             dlt_set_id(ctid, "");
     473              :         else
     474           12 :             dlt_set_id(ctid, str1);
     475              : 
     476           12 :         if (filter->counter < DLT_FILTER_MAX)
     477           12 :             dlt_filter_add(filter, apid, ctid, 0, 0, INT32_MAX, verbose);
     478              :         else
     479            0 :             dlt_vlog(LOG_WARNING,
     480              :                      "Maximum number (%d) of allowed filters reached, ignoring rest of filters!\n",
     481              :                      DLT_FILTER_MAX);
     482              :     }
     483              : 
     484            6 :     fclose(handle);
     485              : 
     486            6 :     return DLT_RETURN_OK;
     487              : }
     488              : 
     489            0 : DltReturnValue dlt_filter_save(DltFilter *filter, const char *filename, int verbose)
     490              : {
     491            0 :     if ((filter == NULL) || (filename == NULL))
     492              :         return DLT_RETURN_WRONG_PARAMETER;
     493              : 
     494              :     FILE *handle;
     495              :     int num;
     496              :     char buf[DLT_COMMON_BUFFER_LENGTH];
     497              : 
     498            0 :     PRINT_FUNCTION_VERBOSE(verbose);
     499              : 
     500            0 :     handle = fopen(filename, "w");
     501              : 
     502            0 :     if (handle == NULL) {
     503            0 :         dlt_vlog(LOG_WARNING, "Filter file %s cannot be opened!\n", filename);
     504            0 :         return DLT_RETURN_ERROR;
     505              :     }
     506              : 
     507            0 :     for (num = 0; num < filter->counter; num++) {
     508            0 :         if (filter->apid[num][0] == 0) {
     509              :             fprintf(handle, "---- ");
     510              :         }
     511              :         else {
     512            0 :             dlt_print_id(buf, filter->apid[num]);
     513              :             fprintf(handle, "%s ", buf);
     514              :         }
     515              : 
     516            0 :         if (filter->ctid[num][0] == 0) {
     517              :             fprintf(handle, "---- ");
     518              :         }
     519              :         else {
     520            0 :             dlt_print_id(buf, filter->ctid[num]);
     521              :             fprintf(handle, "%s ", buf);
     522              :         }
     523              :     }
     524              : 
     525            0 :     fclose(handle);
     526              : 
     527            0 :     return DLT_RETURN_OK;
     528              : }
     529              : 
     530           12 : int dlt_filter_find(DltFilter *filter, const char *apid, const char *ctid, const int log_level,
     531              :                     const int32_t payload_min, const int32_t payload_max, int verbose)
     532              : {
     533              :     int num;
     534              : 
     535           12 :     PRINT_FUNCTION_VERBOSE(verbose);
     536              : 
     537           12 :     if ((filter == NULL) || (apid == NULL))
     538              :         return -1;
     539              : 
     540           18 :     for (num = 0; num < filter->counter; num++)
     541            6 :         if (memcmp(filter->apid[num], apid, DLT_ID_SIZE) == 0) {
     542              :             /* apid matches, now check for ctid */
     543            0 :             if (ctid == NULL) {
     544              :                 /* check if empty ctid matches */
     545              :                 /*if (memcmp(filter->ctid[num],"",DLT_ID_SIZE)==0)//coverity complains here about Out-of-bounds access. */
     546            0 :                 char empty_ctid[DLT_ID_SIZE] = "";
     547              : 
     548            0 :                 if (memcmp(filter->ctid[num], empty_ctid, DLT_ID_SIZE) == 0)
     549            0 :                     if ((filter->log_level[num] == log_level) || (filter->log_level[num] == 0))
     550            0 :                         if (filter->payload_min[num] <= payload_min)
     551            0 :                             if (filter->payload_max[num] >= payload_max)
     552            0 :                                 return num;
     553              :             }
     554            0 :             else if (memcmp(filter->ctid[num], ctid, DLT_ID_SIZE) == 0)
     555              :             {
     556            0 :                 if ((filter->log_level[num] == log_level) || (filter->log_level[num] == 0))
     557            0 :                     if (filter->payload_min[num] <= payload_min)
     558            0 :                         if (filter->payload_max[num] >= payload_max)
     559            0 :                             return num;
     560              :             }
     561              :         }
     562              : 
     563              :     return -1; /* Not found */
     564              : }
     565              : 
     566           12 : DltReturnValue dlt_filter_add(DltFilter *filter, const char *apid, const char *ctid, const int log_level,
     567              :                               const int32_t payload_min, const int32_t payload_max, int verbose)
     568              : {
     569           12 :     PRINT_FUNCTION_VERBOSE(verbose);
     570              : 
     571           12 :     if ((filter == NULL) || (apid == NULL))
     572              :         return DLT_RETURN_WRONG_PARAMETER;
     573              : 
     574           12 :     if (filter->counter >= DLT_FILTER_MAX) {
     575            0 :         dlt_vlog(LOG_WARNING,
     576              :                  "Maximum number (%d) of allowed filters reached, ignoring filter!\n",
     577              :                  DLT_FILTER_MAX);
     578            0 :         return DLT_RETURN_ERROR;
     579              :     }
     580              : 
     581              :     /* add each filter (apid, ctid, log_level, payload_min, payload_max) only once to filter array */
     582           12 :     if (dlt_filter_find(filter, apid, ctid, log_level, payload_min, payload_max, verbose) < 0) {
     583              :         /* filter not found, so add it to filter array */
     584           12 :         dlt_set_id(filter->apid[filter->counter], apid);
     585           12 :         dlt_set_id(filter->ctid[filter->counter], (ctid ? ctid : ""));
     586           12 :         filter->log_level[filter->counter] = log_level;
     587           12 :         filter->payload_min[filter->counter] = payload_min;
     588           12 :         filter->payload_max[filter->counter] = payload_max;
     589              : 
     590           12 :         filter->counter++;
     591              : 
     592           12 :         return DLT_RETURN_OK;
     593              :     }
     594              : 
     595              :     return DLT_RETURN_ERROR;
     596              : }
     597              : 
     598            0 : DltReturnValue dlt_filter_delete(DltFilter *filter, const char *apid, const char *ctid, const int log_level,
     599              :                                  const int32_t payload_min, const int32_t payload_max, int verbose)
     600              : {
     601              :     int j, k;
     602              :     int found = 0;
     603              : 
     604            0 :     PRINT_FUNCTION_VERBOSE(verbose);
     605              : 
     606            0 :     if ((filter == NULL) || (apid == NULL) || (ctid == NULL))
     607              :         return DLT_RETURN_WRONG_PARAMETER;
     608              : 
     609            0 :     if (filter->counter > 0) {
     610              :         /* Get first occurence of apid and ctid in filter array */
     611            0 :         for (j = 0; j < filter->counter; j++)
     612            0 :             if ((memcmp(filter->apid[j], apid, DLT_ID_SIZE) == 0) &&
     613            0 :                 (memcmp(filter->ctid[j], ctid, DLT_ID_SIZE) == 0) &&
     614            0 :                 ((filter->log_level[j] == log_level) || (filter->log_level[j] == 0)) &&
     615            0 :                 (filter->payload_min[j] == payload_min) &&
     616            0 :                 (filter->payload_max[j] == payload_max)
     617              :                 ) {
     618              :                 found = 1;
     619              :                 break;
     620              :             }
     621              : 
     622            0 :         if (found) {
     623              :             /* j is index */
     624              :             /* Copy from j+1 til end to j til end-1 */
     625              : 
     626            0 :             dlt_set_id(filter->apid[j], "");
     627            0 :             dlt_set_id(filter->ctid[j], "");
     628            0 :             filter->log_level[j] = 0;
     629            0 :             filter->payload_min[j] = 0;
     630            0 :             filter->payload_max[j] = INT32_MAX;
     631              : 
     632            0 :             for (k = j; k < (filter->counter - 1); k++) {
     633            0 :                 dlt_set_id(filter->apid[k], filter->apid[k + 1]);
     634            0 :                 dlt_set_id(filter->ctid[k], filter->ctid[k + 1]);
     635            0 :                 filter->log_level[k] = filter->log_level[k + 1];
     636            0 :                 filter->payload_min[k] = filter->payload_min[k + 1];
     637            0 :                 filter->payload_max[k] = filter->payload_max[k + 1];
     638              :             }
     639              : 
     640            0 :             filter->counter--;
     641            0 :             return DLT_RETURN_OK;
     642              :         }
     643              :     }
     644              : 
     645              :     return DLT_RETURN_ERROR;
     646              : }
     647              : 
     648         6109 : DltReturnValue dlt_message_init(DltMessage *msg, int verbose)
     649              : {
     650         6109 :     PRINT_FUNCTION_VERBOSE(verbose);
     651              : 
     652         6109 :     if (msg == NULL)
     653              :         return DLT_RETURN_WRONG_PARAMETER;
     654              : 
     655              :     /* initalise structure parameters */
     656         6107 :     msg->headersize = 0;
     657         6107 :     msg->datasize = 0;
     658              : 
     659         6107 :     msg->databuffer = NULL;
     660         6107 :     msg->databuffersize = 0;
     661              : 
     662         6107 :     msg->storageheader = NULL;
     663         6107 :     msg->standardheader = NULL;
     664         6107 :     msg->extendedheader = NULL;
     665              : 
     666         6107 :     msg->found_serialheader = 0;
     667              : 
     668         6107 :     return DLT_RETURN_OK;
     669              : }
     670              : 
     671          107 : DltReturnValue dlt_message_free(DltMessage *msg, int verbose)
     672              : {
     673          107 :     PRINT_FUNCTION_VERBOSE(verbose);
     674              : 
     675          107 :     if (msg == NULL)
     676              :         return DLT_RETURN_WRONG_PARAMETER;
     677              : 
     678              :     /* delete databuffer if exists */
     679          105 :     if (msg->databuffer) {
     680           82 :         free(msg->databuffer);
     681           82 :         msg->databuffer = NULL;
     682           82 :         msg->databuffersize = 0;
     683              :     }
     684              : 
     685              :     return DLT_RETURN_OK;
     686              : }
     687              : 
     688         2420 : DltReturnValue dlt_message_header(DltMessage *msg, char *text, size_t textlength, int verbose)
     689              : {
     690         2420 :     return dlt_message_header_flags(msg, text, textlength, DLT_HEADER_SHOW_ALL, verbose);
     691              : }
     692              : 
     693         5122 : DltReturnValue dlt_message_header_flags(DltMessage *msg, char *text, size_t textlength, int flags, int verbose)
     694              : {
     695              :     struct tm timeinfo;
     696              :     char buffer [DLT_COMMON_BUFFER_LENGTH];
     697              : 
     698         5122 :     PRINT_FUNCTION_VERBOSE(verbose);
     699              : 
     700         5122 :     if ((msg == NULL) || (text == NULL) || (textlength <= 0))
     701              :         return DLT_RETURN_WRONG_PARAMETER;
     702              : 
     703         4926 :     if ((DLT_IS_HTYP_UEH(msg->standardheader->htyp)) && (msg->extendedheader == NULL))
     704              :         return DLT_RETURN_WRONG_PARAMETER;
     705              : 
     706         4926 :     if ((flags < DLT_HEADER_SHOW_NONE) || (flags > DLT_HEADER_SHOW_ALL))
     707              :         return DLT_RETURN_WRONG_PARAMETER;
     708              : 
     709         4926 :     text[0] = 0;
     710              : 
     711         4926 :     if ((flags & DLT_HEADER_SHOW_TIME) == DLT_HEADER_SHOW_TIME) {
     712              :         /* print received time */
     713         2826 :         time_t tt = msg->storageheader->seconds;
     714         2826 :         tzset();
     715         2826 :         localtime_r(&tt, &timeinfo);
     716         2826 :         strftime (buffer, sizeof(buffer), "%Y/%m/%d %H:%M:%S", &timeinfo);
     717         2826 :         snprintf(text, textlength, "%s.%.6d ", buffer, msg->storageheader->microseconds);
     718              :     }
     719              : 
     720         4926 :     if ((flags & DLT_HEADER_SHOW_TMSTP) == DLT_HEADER_SHOW_TMSTP) {
     721              :         /* print timestamp if available */
     722         2826 :         if (DLT_IS_HTYP_WTMS(msg->standardheader->htyp))
     723          647 :             snprintf(text + strlen(text), textlength - strlen(text), "%10u ", msg->headerextra.tmsp);
     724              :         else
     725         2179 :             snprintf(text + strlen(text), textlength - strlen(text), "---------- ");
     726              :     }
     727              : 
     728         4926 :     if ((flags & DLT_HEADER_SHOW_MSGCNT) == DLT_HEADER_SHOW_MSGCNT)
     729              :         /* print message counter */
     730         2826 :         snprintf(text + strlen(text), textlength - strlen(text), "%.3d ", msg->standardheader->mcnt);
     731              : 
     732         4926 :     if ((flags & DLT_HEADER_SHOW_ECUID) == DLT_HEADER_SHOW_ECUID) {
     733              :         /* print ecu id, use header extra if available, else storage header value */
     734         2826 :         if (DLT_IS_HTYP_WEID(msg->standardheader->htyp))
     735          647 :             dlt_print_id(text + strlen(text), msg->headerextra.ecu);
     736              :         else
     737         2179 :             dlt_print_id(text + strlen(text), msg->storageheader->ecu);
     738              :     }
     739              : 
     740              :     /* print app id and context id if extended header available, else '----' */ #
     741              : 
     742         4926 :     if ((flags & DLT_HEADER_SHOW_APID) == DLT_HEADER_SHOW_APID) {
     743         2826 :         snprintf(text + strlen(text), textlength - strlen(text), " ");
     744              : 
     745         2826 :         if ((DLT_IS_HTYP_UEH(msg->standardheader->htyp)) && (msg->extendedheader->apid[0] != 0))
     746         1395 :             dlt_print_id(text + strlen(text), msg->extendedheader->apid);
     747              :         else
     748         1431 :             snprintf(text + strlen(text), textlength - strlen(text), "----");
     749              : 
     750         2826 :         snprintf(text + strlen(text), textlength - strlen(text), " ");
     751              :     }
     752              : 
     753         4926 :     if ((flags & DLT_HEADER_SHOW_CTID) == DLT_HEADER_SHOW_CTID) {
     754         2826 :         if ((DLT_IS_HTYP_UEH(msg->standardheader->htyp)) && (msg->extendedheader->ctid[0] != 0))
     755         1395 :             dlt_print_id(text + strlen(text), msg->extendedheader->ctid);
     756              :         else
     757         1431 :             snprintf(text + strlen(text), textlength - strlen(text), "----");
     758              : 
     759         2826 :         snprintf(text + strlen(text), textlength - strlen(text), " ");
     760              :     }
     761              : 
     762              :     /* print info about message type and length */
     763         4926 :     if (DLT_IS_HTYP_UEH(msg->standardheader->htyp)) {
     764         2435 :         if ((flags & DLT_HEADER_SHOW_MSGTYPE) == DLT_HEADER_SHOW_MSGTYPE) {
     765         1395 :             snprintf(text + strlen(text), textlength - strlen(text), "%s",
     766         1395 :                      message_type[DLT_GET_MSIN_MSTP(msg->extendedheader->msin)]);
     767         1395 :             snprintf(text + strlen(text), textlength - strlen(text), " ");
     768              :         }
     769              : 
     770         2435 :         if ((flags & DLT_HEADER_SHOW_MSGSUBTYPE) == DLT_HEADER_SHOW_MSGSUBTYPE) {
     771         1395 :             if ((DLT_GET_MSIN_MSTP(msg->extendedheader->msin)) == DLT_TYPE_LOG)
     772         1256 :                 snprintf(text + strlen(text), textlength - strlen(text), "%s",
     773         1256 :                          log_info[DLT_GET_MSIN_MTIN(msg->extendedheader->msin)]);
     774              : 
     775         1395 :             if ((DLT_GET_MSIN_MSTP(msg->extendedheader->msin)) == DLT_TYPE_APP_TRACE)
     776            0 :                 snprintf(text + strlen(text), textlength - strlen(text), "%s",
     777            0 :                          trace_type[DLT_GET_MSIN_MTIN(msg->extendedheader->msin)]);
     778              : 
     779         1395 :             if ((DLT_GET_MSIN_MSTP(msg->extendedheader->msin)) == DLT_TYPE_NW_TRACE)
     780            0 :                 snprintf(text + strlen(text), textlength - strlen(text), "%s",
     781            0 :                          nw_trace_type[DLT_GET_MSIN_MTIN(msg->extendedheader->msin)]);
     782              : 
     783         1395 :             if ((DLT_GET_MSIN_MSTP(msg->extendedheader->msin)) == DLT_TYPE_CONTROL)
     784          139 :                 snprintf(text + strlen(text), textlength - strlen(text), "%s",
     785          139 :                          control_type[DLT_GET_MSIN_MTIN(msg->extendedheader->msin)]);
     786              : 
     787         1395 :             snprintf(text + strlen(text), textlength - strlen(text), " ");
     788              :         }
     789              : 
     790         2435 :         if ((flags & DLT_HEADER_SHOW_VNVSTATUS) == DLT_HEADER_SHOW_VNVSTATUS) {
     791              :             /* print verbose status pf message */
     792         1395 :             if (DLT_IS_MSIN_VERB(msg->extendedheader->msin))
     793         1256 :                 snprintf(text + strlen(text), textlength - strlen(text), "V");
     794              :             else
     795          139 :                 snprintf(text + strlen(text), textlength - strlen(text), "N");
     796              : 
     797         1395 :             snprintf(text + strlen(text), textlength - strlen(text), " ");
     798              :         }
     799              : 
     800         2435 :         if ((flags & DLT_HEADER_SHOW_NOARG) == DLT_HEADER_SHOW_NOARG)
     801              :             /* print number of arguments */
     802         1395 :             snprintf(text + strlen(text), textlength - strlen(text), "%d", msg->extendedheader->noar);
     803              :     }
     804              :     else {
     805         2491 :         if ((flags & DLT_HEADER_SHOW_MSGTYPE) == DLT_HEADER_SHOW_MSGTYPE)
     806         1431 :             snprintf(text + strlen(text), textlength - strlen(text), "--- ");
     807              : 
     808         2491 :         if ((flags & DLT_HEADER_SHOW_MSGSUBTYPE) == DLT_HEADER_SHOW_MSGSUBTYPE)
     809         1431 :             snprintf(text + strlen(text), textlength - strlen(text), "--- ");
     810              : 
     811         2491 :         if ((flags & DLT_HEADER_SHOW_VNVSTATUS) == DLT_HEADER_SHOW_VNVSTATUS)
     812         1431 :             snprintf(text + strlen(text), textlength - strlen(text), "N ");
     813              : 
     814         2491 :         if ((flags & DLT_HEADER_SHOW_NOARG) == DLT_HEADER_SHOW_NOARG)
     815         1431 :             snprintf(text + strlen(text), textlength - strlen(text), "-");
     816              :     }
     817              : 
     818              :     return DLT_RETURN_OK;
     819              : }
     820              : 
     821         3131 : DltReturnValue dlt_message_payload(DltMessage *msg, char *text, size_t textlength, int type, int verbose)
     822              : {
     823              :     uint32_t id = 0, id_tmp = 0;
     824              :     uint8_t retval = 0;
     825              : 
     826              :     uint8_t *ptr;
     827              :     int32_t datalength;
     828              : 
     829              :     /* Pointer to ptr and datalength */
     830              :     uint8_t **pptr;
     831              :     int32_t *pdatalength;
     832              : 
     833              :     int ret = 0;
     834              : 
     835              :     int num;
     836              :     uint32_t type_info = 0, type_info_tmp = 0;
     837              :     int text_offset = 0;
     838              : 
     839         3131 :     PRINT_FUNCTION_VERBOSE(verbose);
     840              : 
     841         3131 :     if ((msg == NULL) || (msg->databuffer == NULL) || (text == NULL) ||
     842         3072 :         (type < DLT_OUTPUT_HEX) || (type > DLT_OUTPUT_ASCII_LIMITED))
     843              :         return DLT_RETURN_WRONG_PARAMETER;
     844              : 
     845         2941 :     if (textlength <= 0) {
     846           10 :         dlt_log(LOG_WARNING, "String does not fit binary data!\n");
     847           10 :         return DLT_RETURN_WRONG_PARAMETER;
     848              :     }
     849              : 
     850              :     /* start with empty string */
     851         2931 :     text[0] = 0;
     852              : 
     853              :     /* print payload only as hex */
     854         2931 :     if (type == DLT_OUTPUT_HEX)
     855          526 :         return dlt_print_hex_string(text, (int)textlength, msg->databuffer, (int)msg->datasize);
     856              : 
     857              :     /* print payload as mixed */
     858         2405 :     if (type == DLT_OUTPUT_MIXED_FOR_PLAIN)
     859          526 :         return dlt_print_mixed_string(text, (int)textlength, msg->databuffer, (int)msg->datasize, 0);
     860              : 
     861         1879 :     if (type == DLT_OUTPUT_MIXED_FOR_HTML)
     862          526 :         return dlt_print_mixed_string(text, (int)textlength, msg->databuffer, (int)msg->datasize, 1);
     863              : 
     864         1353 :     ptr = msg->databuffer;
     865         1353 :     datalength = (int32_t)msg->datasize;
     866              : 
     867              :     /* Pointer to ptr and datalength */
     868              :     pptr = &ptr;
     869              :     pdatalength = &datalength;
     870              : 
     871              :     /* non-verbose mode */
     872              : 
     873              :     /* print payload as hex */
     874         1353 :     if (DLT_MSG_IS_NONVERBOSE(msg)) {
     875              : 
     876          537 :         DLT_MSG_READ_VALUE(id_tmp, ptr, datalength, uint32_t);
     877          537 :         id = DLT_ENDIAN_GET_32(msg->standardheader->htyp, id_tmp);
     878              : 
     879          537 :         if (textlength < (((unsigned int)datalength * 3) + 20)) {
     880            0 :             dlt_vlog(LOG_WARNING,
     881              :                      "String does not fit binary data (available=%d, required=%d) !\n",
     882            0 :                      (int)textlength, (datalength * 3) + 20);
     883            0 :             return DLT_RETURN_ERROR;
     884              :         }
     885              : 
     886              :         /* process message id / service id */
     887          537 :         if (DLT_MSG_IS_CONTROL(msg)) {
     888           60 :             if ((id > 0) && (id < DLT_SERVICE_ID_LAST_ENTRY))
     889           57 :                 snprintf(text + strlen(text), textlength - strlen(text), "%s",
     890              :                          service_id_name[id]); /* service id */
     891            3 :             else if (!(DLT_MSG_IS_CONTROL_TIME(msg)))
     892            3 :                 snprintf(text + strlen(text), textlength - strlen(text), "service(%u)", id); /* service id */
     893              : 
     894           60 :             if (datalength > 0)
     895           60 :                 snprintf(text + strlen(text), textlength - strlen(text), ", ");
     896              :         }
     897              :         else {
     898          477 :             snprintf(text + strlen(text), textlength - strlen(text), "%u, ", id); /* message id */
     899              :         }
     900              : 
     901              :         /* process return value */
     902          537 :         if (DLT_MSG_IS_CONTROL_RESPONSE(msg)) {
     903            4 :             if (datalength > 0) {
     904            4 :                 DLT_MSG_READ_VALUE(retval, ptr, datalength, uint8_t); /* No endian conversion necessary */
     905              : 
     906            4 :                 if ((retval < DLT_SERVICE_RESPONSE_LAST) || (retval == 8))
     907            3 :                     snprintf(text + strlen(text), textlength - strlen(text), "%s", return_type[retval]);
     908              :                 else
     909            1 :                     snprintf(text + strlen(text), textlength - strlen(text), "%.2x", retval);
     910              : 
     911            4 :                 if (datalength >= 1)
     912            2 :                     snprintf(text + strlen(text), textlength - strlen(text), ", ");
     913              :             }
     914              :         }
     915              : 
     916          537 :         if (type == DLT_OUTPUT_ASCII_LIMITED) {
     917          122 :             ret = dlt_print_hex_string(text + strlen(text),
     918          122 :                                        (int)(textlength - strlen(
     919              :                                                  text)),
     920              :                                        ptr,
     921              :                                        (datalength >
     922          122 :                                         DLT_COMMON_ASCII_LIMIT_MAX_CHARS ? DLT_COMMON_ASCII_LIMIT_MAX_CHARS : datalength));
     923              : 
     924          122 :             if ((datalength > DLT_COMMON_ASCII_LIMIT_MAX_CHARS) &&
     925            6 :                 ((textlength - strlen(text)) > 4))
     926            6 :                 snprintf(text + strlen(text), textlength - strlen(text), " ...");
     927              :         }
     928              :         else {
     929          415 :             ret = dlt_print_hex_string(text + strlen(text), (int)(textlength - strlen(text)), ptr, datalength);
     930              :         }
     931              : 
     932          537 :         return ret;
     933              :     }
     934              : 
     935              :     /* At this point, it is ensured that a extended header is available */
     936              : 
     937              :     /* verbose mode */
     938              :     type_info = 0;
     939              :     type_info_tmp = 0;
     940              : 
     941         3361 :     for (num = 0; num < (int)(msg->extendedheader->noar); num++) {
     942         2545 :         if (num != 0) {
     943         1743 :             text_offset = (int)strlen(text);
     944         1743 :             snprintf(text + text_offset, textlength - (size_t)text_offset, " ");
     945              :         }
     946              : 
     947              :         /* first read the type info of the argument */
     948         2545 :         DLT_MSG_READ_VALUE(type_info_tmp, ptr, datalength, uint32_t);
     949         2545 :         type_info = DLT_ENDIAN_GET_32(msg->standardheader->htyp, type_info_tmp);
     950              : 
     951              :         /* print out argument */
     952         2545 :         text_offset = (int)strlen(text);
     953              : 
     954         2545 :         if (dlt_message_argument_print(msg, type_info, pptr, pdatalength,
     955         2545 :                                        (text + text_offset), (textlength - (size_t)text_offset), -1,
     956              :                                        0) == DLT_RETURN_ERROR)
     957              :             return DLT_RETURN_ERROR;
     958              :     }
     959              : 
     960              :     return DLT_RETURN_OK;
     961              : }
     962              : 
     963          742 : DltReturnValue dlt_message_filter_check(DltMessage *msg, DltFilter *filter, int verbose)
     964              : {
     965              :     /* check the filters if message is used */
     966              :     int num;
     967              :     DltReturnValue found = DLT_RETURN_OK;
     968              : 
     969          742 :     PRINT_FUNCTION_VERBOSE(verbose);
     970              : 
     971          742 :     if ((msg == NULL) || (filter == NULL))
     972              :         return DLT_RETURN_WRONG_PARAMETER;
     973              : 
     974          736 :     if ((filter->counter == 0) || (!(DLT_IS_HTYP_UEH(msg->standardheader->htyp))))
     975              :         /* no filter is set, or no extended header is available, so do as filter is matching */
     976              :         return DLT_RETURN_TRUE;
     977              : 
     978          936 :     for (num = 0; num < filter->counter; num++)
     979              :         /* check each filter if it matches */
     980          624 :         if ((DLT_IS_HTYP_UEH(msg->standardheader->htyp)) &&
     981          624 :             ((filter->apid[num][0] == 0) || (memcmp(filter->apid[num], msg->extendedheader->apid, DLT_ID_SIZE) == 0)) &&
     982            0 :             ((filter->ctid[num][0] == 0) || (memcmp(filter->ctid[num], msg->extendedheader->ctid, DLT_ID_SIZE) == 0)) &&
     983            0 :             ((filter->log_level[num] == 0) ||
     984            0 :              (filter->log_level[num] == DLT_GET_MSIN_MTIN(msg->extendedheader->msin))) &&
     985            0 :             ((filter->payload_min[num] == 0) || (filter->payload_min[num] <= msg->datasize)) &&
     986            0 :             ((filter->payload_max[num] == 0) || (filter->payload_max[num] >= msg->datasize))) {
     987              :             found = DLT_RETURN_TRUE;
     988              :             break;
     989              :         }
     990              : 
     991              :     return found;
     992              : }
     993              : 
     994         6677 : int dlt_message_read(DltMessage *msg, uint8_t *buffer, unsigned int length, int resync, int verbose)
     995              : {
     996              :     uint32_t extra_size = 0;
     997              : 
     998         6677 :     PRINT_FUNCTION_VERBOSE(verbose);
     999              : 
    1000         6677 :     if ((msg == NULL) || (buffer == NULL) || (length <= 0))
    1001              :         return DLT_MESSAGE_ERROR_UNKNOWN;
    1002              : 
    1003              :     /* initialize resync_offset */
    1004         6245 :     msg->resync_offset = 0;
    1005              : 
    1006              :     /* check if message contains serial header, smaller than standard header */
    1007         6245 :     if (length < sizeof(dltSerialHeader))
    1008              :         /* dlt_log(LOG_ERR, "Length smaller than serial header!\n"); */
    1009              :         return DLT_MESSAGE_ERROR_SIZE;
    1010              : 
    1011         6245 :     if (memcmp(buffer, dltSerialHeader, sizeof(dltSerialHeader)) == 0) {
    1012              :         /* serial header found */
    1013            0 :         msg->found_serialheader = 1;
    1014            0 :         buffer += sizeof(dltSerialHeader);
    1015            0 :         length -= (unsigned int)sizeof(dltSerialHeader);
    1016              :     }
    1017              :     else {
    1018              :         /* serial header not found */
    1019         6245 :         msg->found_serialheader = 0;
    1020              : 
    1021         6245 :         if (resync) {
    1022              :             /* resync if necessary */
    1023              :             msg->resync_offset = 0;
    1024              : 
    1025              :             do {
    1026            0 :                 if (memcmp(buffer + msg->resync_offset, dltSerialHeader, sizeof(dltSerialHeader)) == 0) {
    1027              :                     /* serial header found */
    1028            0 :                     msg->found_serialheader = 1;
    1029            0 :                     buffer += sizeof(dltSerialHeader);
    1030            0 :                     length -= (unsigned int)sizeof(dltSerialHeader);
    1031            0 :                     break;
    1032              :                 }
    1033              : 
    1034            0 :                 msg->resync_offset++;
    1035            0 :             } while ((sizeof(dltSerialHeader) + (size_t)msg->resync_offset) <= length);
    1036              : 
    1037              :             /* Set new start offset */
    1038            0 :             if (msg->resync_offset > 0) {
    1039              :                 /* Resyncing connection */
    1040            0 :                 buffer += msg->resync_offset;
    1041            0 :                 length -= (unsigned int)msg->resync_offset;
    1042              :             }
    1043              :         }
    1044              :     }
    1045              : 
    1046              :     /* check that standard header fits buffer */
    1047         6245 :     if (length < sizeof(DltStandardHeader))
    1048              :         /* dlt_log(LOG_ERR, "Length smaller than standard header!\n"); */
    1049              :         return DLT_MESSAGE_ERROR_SIZE;
    1050              : 
    1051         6245 :     memcpy(msg->headerbuffer + sizeof(DltStorageHeader), buffer, sizeof(DltStandardHeader));
    1052              : 
    1053              :     /* set ptrs to structures */
    1054         6245 :     msg->storageheader = (DltStorageHeader *)msg->headerbuffer;
    1055         6245 :     msg->standardheader = (DltStandardHeader *)(msg->headerbuffer + sizeof(DltStorageHeader));
    1056              : 
    1057              :     /* calculate complete size of headers */
    1058         6245 :     extra_size = (uint32_t) (DLT_STANDARD_HEADER_EXTRA_SIZE(msg->standardheader->htyp) +
    1059              :         (DLT_IS_HTYP_UEH(msg->standardheader->htyp) ? sizeof(DltExtendedHeader) : 0));
    1060         6245 :     msg->headersize = (uint32_t) (sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + extra_size);
    1061         6245 :     msg->datasize = (uint32_t) DLT_BETOH_16(msg->standardheader->len) - msg->headersize + (uint32_t) sizeof(DltStorageHeader);
    1062              : 
    1063              :     /* calculate complete size of payload */
    1064              :     int32_t temp_datasize;
    1065         6245 :     temp_datasize = DLT_BETOH_16(msg->standardheader->len) - (int32_t) msg->headersize + (int32_t) sizeof(DltStorageHeader);
    1066              : 
    1067              :     /* check data size */
    1068         6245 :     if (temp_datasize < 0) {
    1069            0 :         dlt_vlog(LOG_WARNING,
    1070              :                  "Plausibility check failed. Complete message size too short (%d)!\n",
    1071              :                  temp_datasize);
    1072            0 :         return DLT_MESSAGE_ERROR_CONTENT;
    1073              :     }
    1074              :     else {
    1075         6245 :         msg->datasize = (uint32_t) temp_datasize;
    1076              :     }
    1077              : 
    1078              :     /* check if verbose mode is on*/
    1079         6245 :     if (verbose) {
    1080            0 :         dlt_vlog(LOG_DEBUG, "BufferLength=%u, HeaderSize=%u, DataSize=%u\n",
    1081              :                  length, msg->headersize, msg->datasize);
    1082              :     }
    1083              : 
    1084              :     /* load standard header extra parameters and Extended header if used */
    1085         6245 :     if (extra_size > 0) {
    1086         6245 :         if (length < (msg->headersize - sizeof(DltStorageHeader)))
    1087              :             return DLT_MESSAGE_ERROR_SIZE;
    1088              : 
    1089         6245 :         memcpy(msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader),
    1090         6245 :                buffer + sizeof(DltStandardHeader), (size_t)extra_size);
    1091              : 
    1092              :         /* set extended header ptr and get standard header extra parameters */
    1093         6245 :         if (DLT_IS_HTYP_UEH(msg->standardheader->htyp))
    1094         6245 :             msg->extendedheader =
    1095         6245 :                 (DltExtendedHeader *)(msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) +
    1096         6245 :                                       DLT_STANDARD_HEADER_EXTRA_SIZE(msg->standardheader->htyp));
    1097              :         else
    1098            0 :             msg->extendedheader = NULL;
    1099              : 
    1100         6245 :         dlt_message_get_extraparameters(msg, verbose);
    1101              :     }
    1102              : 
    1103              :     /* check if payload fits length */
    1104         6245 :     if (length < (msg->headersize - sizeof(DltStorageHeader) + msg->datasize))
    1105              :         /* dlt_log(LOG_ERR,"length does not fit!\n"); */
    1106              :         return DLT_MESSAGE_ERROR_SIZE;
    1107              : 
    1108              :     /* free last used memory for buffer */
    1109         6042 :     if (msg->databuffer) {
    1110         6030 :         if (msg->datasize > msg->databuffersize) {
    1111            8 :             free(msg->databuffer);
    1112            8 :             msg->databuffer = (uint8_t *)malloc(msg->datasize);
    1113            8 :             msg->databuffersize = msg->datasize;
    1114              :         }
    1115              :     }
    1116              :     else {
    1117              :         /* get new memory for buffer */
    1118           12 :         msg->databuffer = (uint8_t *)malloc(msg->datasize);
    1119           12 :         msg->databuffersize = msg->datasize;
    1120              :     }
    1121              : 
    1122         6042 :     if (msg->databuffer == NULL) {
    1123            0 :         dlt_vlog(LOG_WARNING,
    1124              :                  "Cannot allocate memory for payload buffer of size %u!\n",
    1125              :                  msg->datasize);
    1126            0 :         return DLT_MESSAGE_ERROR_UNKNOWN;
    1127              :     }
    1128              : 
    1129              :     /* load payload data from buffer */
    1130         6042 :     memcpy(msg->databuffer, buffer + (msg->headersize - sizeof(DltStorageHeader)), msg->datasize);
    1131              : 
    1132         6042 :     return DLT_MESSAGE_ERROR_OK;
    1133              : }
    1134              : 
    1135         7222 : DltReturnValue dlt_message_get_extraparameters(DltMessage *msg, int verbose)
    1136              : {
    1137         7222 :     PRINT_FUNCTION_VERBOSE(verbose);
    1138              : 
    1139         7222 :     if (msg == NULL)
    1140              :         return DLT_RETURN_WRONG_PARAMETER;
    1141              : 
    1142         7220 :     if (DLT_IS_HTYP_WEID(msg->standardheader->htyp))
    1143         7026 :         memcpy(msg->headerextra.ecu,
    1144              :                msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader),
    1145              :                DLT_ID_SIZE);
    1146              : 
    1147         7220 :     if (DLT_IS_HTYP_WSID(msg->standardheader->htyp)) {
    1148         6732 :         memcpy(&(msg->headerextra.seid), msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader)
    1149         6732 :                + (DLT_IS_HTYP_WEID(msg->standardheader->htyp) ? DLT_SIZE_WEID : 0), DLT_SIZE_WSID);
    1150         6732 :         msg->headerextra.seid = DLT_BETOH_32(msg->headerextra.seid);
    1151              :     }
    1152              : 
    1153         7220 :     if (DLT_IS_HTYP_WTMS(msg->standardheader->htyp)) {
    1154        14052 :         memcpy(&(msg->headerextra.tmsp), msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader)
    1155         7026 :                + (DLT_IS_HTYP_WEID(msg->standardheader->htyp) ? DLT_SIZE_WEID : 0)
    1156         7026 :                + (DLT_IS_HTYP_WSID(msg->standardheader->htyp) ? DLT_SIZE_WSID : 0), DLT_SIZE_WTMS);
    1157         7026 :         msg->headerextra.tmsp = DLT_BETOH_32(msg->headerextra.tmsp);
    1158              :     }
    1159              : 
    1160              :     return DLT_RETURN_OK;
    1161              : }
    1162              : 
    1163         6247 : DltReturnValue dlt_message_set_extraparameters(DltMessage *msg, int verbose)
    1164              : {
    1165         6247 :     PRINT_FUNCTION_VERBOSE(verbose);
    1166              : 
    1167         6247 :     if (msg == NULL)
    1168              :         return DLT_RETURN_WRONG_PARAMETER;
    1169              : 
    1170         6245 :     if (DLT_IS_HTYP_WEID(msg->standardheader->htyp))
    1171         6049 :         memcpy(msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader),
    1172         6049 :                msg->headerextra.ecu,
    1173              :                DLT_ID_SIZE);
    1174              : 
    1175         6245 :     if (DLT_IS_HTYP_WSID(msg->standardheader->htyp)) {
    1176         5999 :         msg->headerextra.seid = DLT_HTOBE_32(msg->headerextra.seid);
    1177         5999 :         memcpy(msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader)
    1178         5999 :                + (DLT_IS_HTYP_WEID(msg->standardheader->htyp) ? DLT_SIZE_WEID : 0),
    1179         5999 :                &(msg->headerextra.seid),
    1180              :                DLT_SIZE_WSID);
    1181              :     }
    1182              : 
    1183         6245 :     if (DLT_IS_HTYP_WTMS(msg->standardheader->htyp)) {
    1184         6049 :         msg->headerextra.tmsp = DLT_HTOBE_32(msg->headerextra.tmsp);
    1185        12098 :         memcpy(msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader)
    1186         6049 :                + (DLT_IS_HTYP_WEID(msg->standardheader->htyp) ? DLT_SIZE_WEID : 0)
    1187         6049 :                + (DLT_IS_HTYP_WSID(msg->standardheader->htyp) ? DLT_SIZE_WSID : 0),
    1188         6049 :                &(msg->headerextra.tmsp),
    1189              :                DLT_SIZE_WTMS);
    1190              :     }
    1191              : 
    1192              :     return DLT_RETURN_OK;
    1193              : }
    1194              : 
    1195           54 : DltReturnValue dlt_file_init(DltFile *file, int verbose)
    1196              : {
    1197           54 :     PRINT_FUNCTION_VERBOSE(verbose);
    1198              : 
    1199           54 :     if (file == NULL)
    1200              :         return DLT_RETURN_WRONG_PARAMETER;
    1201              : 
    1202              :     /* initalise structure parameters */
    1203           54 :     file->handle = NULL;
    1204           54 :     file->counter = 0;
    1205           54 :     file->counter_total = 0;
    1206           54 :     file->index = NULL;
    1207              : 
    1208           54 :     file->filter = NULL;
    1209           54 :     file->filter_counter = 0;
    1210           54 :     file->file_position = 0;
    1211              : 
    1212           54 :     file->position = 0;
    1213              : 
    1214           54 :     file->error_messages = 0;
    1215              : 
    1216           54 :     return dlt_message_init(&(file->msg), verbose);
    1217              : }
    1218              : 
    1219            6 : DltReturnValue dlt_file_set_filter(DltFile *file, DltFilter *filter, int verbose)
    1220              : {
    1221            6 :     PRINT_FUNCTION_VERBOSE(verbose);
    1222              : 
    1223            6 :     if (file == NULL)
    1224              :         return DLT_RETURN_WRONG_PARAMETER;
    1225              : 
    1226              :     /* set filter */
    1227            6 :     file->filter = filter;
    1228              : 
    1229            6 :     return DLT_RETURN_OK;
    1230              : }
    1231              : 
    1232         6627 : DltReturnValue dlt_file_read_header(DltFile *file, int verbose)
    1233              : {
    1234         6627 :     PRINT_FUNCTION_VERBOSE(verbose);
    1235              : 
    1236         6627 :     if (file == NULL)
    1237              :         return DLT_RETURN_WRONG_PARAMETER;
    1238              : 
    1239              :     /* Loop until storage header is found */
    1240              :     while (1) {
    1241              :         /* load header from file */
    1242        13254 :         if (fread(file->msg.headerbuffer,
    1243              :                   sizeof(DltStorageHeader) + sizeof(DltStandardHeader), 1,
    1244              :                   file->handle) != 1) {
    1245           38 :             if (!feof(file->handle))
    1246            0 :                 dlt_log(LOG_WARNING, "Cannot read header from file!\n");
    1247              :             else
    1248           38 :                 dlt_log(LOG_DEBUG, "Reached end of file\n");
    1249              : 
    1250           38 :             return DLT_RETURN_ERROR;
    1251              :         }
    1252              : 
    1253              :         /* set ptrs to structures */
    1254         6589 :         file->msg.storageheader = (DltStorageHeader *)file->msg.headerbuffer;
    1255         6589 :         file->msg.standardheader = (DltStandardHeader *)(file->msg.headerbuffer +
    1256              :                                                          sizeof(DltStorageHeader));
    1257              : 
    1258              :         /* check id of storage header */
    1259         6589 :         if (dlt_check_storageheader(file->msg.storageheader) != DLT_RETURN_TRUE) {
    1260              :             /* Shift the position back to the place where it stared to read + 1 */
    1261            0 :             if (fseek(file->handle,
    1262              :                       (long) (1 - (sizeof(DltStorageHeader) + sizeof(DltStandardHeader))),
    1263              :                       SEEK_CUR) < 0) {
    1264            0 :                 dlt_log(LOG_WARNING, "DLT storage header pattern not found!\n");
    1265            0 :                 return DLT_RETURN_ERROR;
    1266              :             }
    1267              :         }
    1268              :         else {
    1269              :             /* storage header is found */
    1270              :             break;
    1271              :         }
    1272              :     }
    1273              : 
    1274              :     /* calculate complete size of headers */
    1275         6589 :     file->msg.headersize = (uint32_t) (sizeof(DltStorageHeader) + sizeof(DltStandardHeader) +
    1276         6589 :         DLT_STANDARD_HEADER_EXTRA_SIZE(file->msg.standardheader->htyp) +
    1277              :         (DLT_IS_HTYP_UEH(file->msg.standardheader->htyp) ? sizeof(DltExtendedHeader) : 0));
    1278              : 
    1279              :     /* calculate complete size of payload */
    1280              :     int32_t temp_datasize;
    1281         6589 :     temp_datasize = DLT_BETOH_16(file->msg.standardheader->len) + (int32_t) sizeof(DltStorageHeader) - (int32_t) file->msg.headersize;
    1282              : 
    1283              :     /* check data size */
    1284         6589 :     if (temp_datasize < 0) {
    1285            0 :         dlt_vlog(LOG_WARNING,
    1286              :                  "Plausibility check failed. Complete message size too short! (%d)\n",
    1287              :                  temp_datasize);
    1288            0 :         return DLT_RETURN_ERROR;
    1289              :     } else {
    1290         6589 :         file->msg.datasize = (uint32_t) temp_datasize;
    1291              :     }
    1292              : 
    1293              :     /* check if verbose mode is on */
    1294         6589 :     if (verbose) {
    1295            0 :         dlt_vlog(LOG_DEBUG, "HeaderSize=%u, DataSize=%u\n",
    1296              :                  file->msg.headersize, file->msg.datasize);
    1297              :     }
    1298              : 
    1299              :     return DLT_RETURN_OK;
    1300              : }
    1301              : 
    1302            0 : DltReturnValue dlt_file_read_header_raw(DltFile *file, int resync, int verbose)
    1303              : {
    1304              :     char dltSerialHeaderBuffer[DLT_ID_SIZE];
    1305              : 
    1306            0 :     PRINT_FUNCTION_VERBOSE(verbose);
    1307              : 
    1308            0 :     if (file == NULL)
    1309              :         return DLT_RETURN_WRONG_PARAMETER;
    1310              : 
    1311              :     /* check if serial header exists, ignore if found */
    1312            0 :     if (fread(dltSerialHeaderBuffer, sizeof(dltSerialHeaderBuffer), 1, file->handle) != 1) {
    1313              :         /* cannot read serial header, not enough data available in file */
    1314            0 :         if (!feof(file->handle))
    1315            0 :             dlt_log(LOG_WARNING, "Cannot read header from file!\n");
    1316              : 
    1317            0 :         return DLT_RETURN_ERROR;
    1318              :     }
    1319              : 
    1320            0 :     if (memcmp(dltSerialHeaderBuffer, dltSerialHeader, sizeof(dltSerialHeader)) == 0) {
    1321              :         /* serial header found */
    1322              :         /* nothing to do continue reading */
    1323              : 
    1324              :     }
    1325              :     else {
    1326              :         /* serial header not found */
    1327            0 :         if (resync) {
    1328              :             /* increase error counter */
    1329            0 :             file->error_messages++;
    1330              : 
    1331              :             /* resync to serial header */
    1332              :             do {
    1333              :                 memmove(dltSerialHeaderBuffer, dltSerialHeaderBuffer + 1, sizeof(dltSerialHeader) - 1);
    1334              : 
    1335            0 :                 if (fread(dltSerialHeaderBuffer + 3, 1, 1, file->handle) != 1)
    1336              :                     /* cannot read any data, perhaps end of file reached */
    1337              :                     return DLT_RETURN_ERROR;
    1338              : 
    1339            0 :                 if (memcmp(dltSerialHeaderBuffer, dltSerialHeader, sizeof(dltSerialHeader)) == 0)
    1340              :                     /* serial header synchronised */
    1341              :                     break;
    1342              :             } while (1);
    1343              :         }
    1344              :         else
    1345              :         /* go back to last file position */
    1346            0 :         if (0 != fseek(file->handle, file->file_position, SEEK_SET))
    1347              :         {
    1348              :             return DLT_RETURN_ERROR;
    1349              :         }
    1350              :     }
    1351              : 
    1352              :     /* load header from file */
    1353            0 :     if (fread(file->msg.headerbuffer + sizeof(DltStorageHeader), sizeof(DltStandardHeader), 1, file->handle) != 1) {
    1354            0 :         if (!feof(file->handle))
    1355            0 :             dlt_log(LOG_WARNING, "Cannot read header from file!\n");
    1356              : 
    1357            0 :         return DLT_RETURN_ERROR;
    1358              :     }
    1359              : 
    1360              :     /* set ptrs to structures */
    1361            0 :     file->msg.storageheader = (DltStorageHeader *)file->msg.headerbuffer; /* this points now to a empty storage header (filled with '0') */
    1362            0 :     file->msg.standardheader = (DltStandardHeader *)(file->msg.headerbuffer + sizeof(DltStorageHeader));
    1363              : 
    1364              :     /* Skip storage header field, fill this field with '0' */
    1365              :     memset(file->msg.storageheader, 0, sizeof(DltStorageHeader));
    1366              : 
    1367              :     /* Set storage header */
    1368            0 :     dlt_set_storageheader(file->msg.storageheader, DLT_COMMON_DUMMY_ECUID);
    1369              : 
    1370              :     /* no check for storage header id*/
    1371              : 
    1372              :     /* calculate complete size of headers */
    1373            0 :     file->msg.headersize = (uint32_t) (sizeof(DltStorageHeader) + sizeof(DltStandardHeader) +
    1374            0 :         DLT_STANDARD_HEADER_EXTRA_SIZE(file->msg.standardheader->htyp) +
    1375              :         (DLT_IS_HTYP_UEH(file->msg.standardheader->htyp) ? sizeof(DltExtendedHeader) : 0));
    1376              : 
    1377              :     /* calculate complete size of payload */
    1378              :     int32_t temp_datasize;
    1379            0 :     temp_datasize = DLT_BETOH_16(file->msg.standardheader->len) + (int32_t) sizeof(DltStorageHeader) - (int32_t) file->msg.headersize;
    1380              : 
    1381              :     /* check data size */
    1382            0 :     if (temp_datasize < 0) {
    1383            0 :         dlt_vlog(LOG_WARNING,
    1384              :                  "Plausibility check failed. Complete message size too short! (%d)\n",
    1385              :                  temp_datasize);
    1386            0 :         return DLT_RETURN_ERROR;
    1387              :     }
    1388              :     else {
    1389            0 :         file->msg.datasize = (uint32_t) temp_datasize;
    1390              :     }
    1391              : 
    1392              :     /* check if verbose mode is on */
    1393            0 :     if (verbose) {
    1394            0 :         dlt_vlog(LOG_DEBUG, "HeaderSize=%u, DataSize=%u\n",
    1395              :                  file->msg.headersize, file->msg.datasize);
    1396              :     }
    1397              : 
    1398              :     return DLT_RETURN_OK;
    1399              : }
    1400              : 
    1401         4505 : DltReturnValue dlt_file_read_header_extended(DltFile *file, int verbose)
    1402              : {
    1403         4505 :     PRINT_FUNCTION_VERBOSE(verbose);
    1404              : 
    1405         4505 :     if (file == NULL)
    1406              :         return DLT_RETURN_WRONG_PARAMETER;
    1407              : 
    1408              :     /* load standard header extra parameters if used */
    1409         4505 :     if (DLT_STANDARD_HEADER_EXTRA_SIZE(file->msg.standardheader->htyp)) {
    1410         1530 :         if (fread(file->msg.headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader),
    1411              :                   DLT_STANDARD_HEADER_EXTRA_SIZE(file->msg.standardheader->htyp),
    1412              :                   1, file->handle) != 1) {
    1413            0 :             dlt_log(LOG_WARNING, "Cannot read standard header extra parameters from file!\n");
    1414            0 :             return DLT_RETURN_ERROR;
    1415              :         }
    1416              : 
    1417          765 :         dlt_message_get_extraparameters(&(file->msg), verbose);
    1418              :     }
    1419              : 
    1420              :     /* load Extended header if used */
    1421         4505 :     if (DLT_IS_HTYP_UEH(file->msg.standardheader->htyp) == 0)
    1422              :         /* there is nothing to be loaded */
    1423              :         return DLT_RETURN_OK;
    1424              : 
    1425         2173 :     if (fread(file->msg.headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) +
    1426         2173 :               DLT_STANDARD_HEADER_EXTRA_SIZE(file->msg.standardheader->htyp),
    1427              :               (DLT_IS_HTYP_UEH(file->msg.standardheader->htyp) ? sizeof(DltExtendedHeader) : 0),
    1428              :               1, file->handle) != 1) {
    1429            0 :         dlt_log(LOG_WARNING, "Cannot read extended header from file!\n");
    1430            0 :         return DLT_RETURN_ERROR;
    1431              :     }
    1432              : 
    1433              :     /* set extended header ptr */
    1434         2173 :     if (DLT_IS_HTYP_UEH(file->msg.standardheader->htyp))
    1435         2173 :         file->msg.extendedheader =
    1436         2173 :             (DltExtendedHeader *)(file->msg.headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) +
    1437         2173 :                                   DLT_STANDARD_HEADER_EXTRA_SIZE(file->msg.standardheader->htyp));
    1438              :     else
    1439            0 :         file->msg.extendedheader = NULL;
    1440              : 
    1441              :     return DLT_RETURN_OK;
    1442              : }
    1443              : 
    1444         3875 : DltReturnValue dlt_file_read_data(DltFile *file, int verbose)
    1445              : {
    1446         3875 :     PRINT_FUNCTION_VERBOSE(verbose);
    1447              : 
    1448         3875 :     if (file == NULL)
    1449              :         return DLT_RETURN_WRONG_PARAMETER;
    1450              : 
    1451              :     /* free last used memory for buffer */
    1452         3875 :     if (file->msg.databuffer && (file->msg.databuffersize < file->msg.datasize)) {
    1453          129 :         free(file->msg.databuffer);
    1454          129 :         file->msg.databuffer = NULL;
    1455              :     }
    1456              : 
    1457         3875 :     if (file->msg.databuffer == NULL) {
    1458              :         /* get new memory for buffer */
    1459          168 :         file->msg.databuffer = (uint8_t *)malloc(file->msg.datasize);
    1460          168 :         file->msg.databuffersize = file->msg.datasize;
    1461              :     }
    1462              : 
    1463         3875 :     if (file->msg.databuffer == NULL) {
    1464            0 :         dlt_vlog(LOG_WARNING,
    1465              :                  "Cannot allocate memory for payload buffer of size %u!\n",
    1466              :                  file->msg.datasize);
    1467            0 :         return DLT_RETURN_ERROR;
    1468              :     }
    1469              : 
    1470              :     /* load payload data from file */
    1471         7750 :     if (fread(file->msg.databuffer, file->msg.datasize, 1, file->handle) != 1) {
    1472           52 :         if (file->msg.datasize != 0) {
    1473            0 :             dlt_vlog(LOG_WARNING,
    1474              :                      "Cannot read payload data from file of size %u!\n",
    1475              :                      file->msg.datasize);
    1476            0 :             return DLT_RETURN_ERROR;
    1477              :         }
    1478              :     }
    1479              : 
    1480              :     return DLT_RETURN_OK;
    1481              : }
    1482              : 
    1483           50 : DltReturnValue dlt_file_open(DltFile *file, const char *filename, int verbose)
    1484              : {
    1485           50 :     PRINT_FUNCTION_VERBOSE(verbose);
    1486              : 
    1487           50 :     if ((file == NULL) || (filename == NULL))
    1488              :         return DLT_RETURN_WRONG_PARAMETER;
    1489              : 
    1490              :     /* reset counters */
    1491           44 :     file->counter = 0;
    1492           44 :     file->counter_total = 0;
    1493           44 :     file->position = 0;
    1494           44 :     file->file_position = 0;
    1495           44 :     file->file_length = 0;
    1496           44 :     file->error_messages = 0;
    1497              : 
    1498           44 :     if (file->handle)
    1499            0 :         fclose(file->handle);
    1500              : 
    1501              :     /* open dlt file */
    1502           44 :     file->handle = fopen(filename, "rb");
    1503              : 
    1504           44 :     if (file->handle == NULL) {
    1505            1 :         dlt_vlog(LOG_WARNING, "File %s cannot be opened!\n", filename);
    1506            1 :         return DLT_RETURN_ERROR;
    1507              :     }
    1508              : 
    1509           43 :     if (0 != fseek(file->handle, 0, SEEK_END)) {
    1510            0 :         dlt_vlog(LOG_WARNING, "dlt_file_open: Seek failed to 0,SEEK_END");
    1511            0 :         return DLT_RETURN_ERROR;
    1512              :     }
    1513              : 
    1514           43 :     file->file_length = ftell(file->handle);
    1515              : 
    1516           43 :     if (0 != fseek(file->handle, 0, SEEK_SET)) {
    1517            0 :         dlt_vlog(LOG_WARNING, "dlt_file_open: Seek failed to 0,SEEK_SET");
    1518            0 :         return DLT_RETURN_ERROR;
    1519              :     }
    1520              : 
    1521           43 :     if (verbose)
    1522              :         /* print file length */
    1523            1 :         dlt_vlog(LOG_DEBUG, "File is %" PRIu64 "bytes long\n", file->file_length);
    1524              : 
    1525              :     return DLT_RETURN_OK;
    1526              : }
    1527              : 
    1528         2752 : DltReturnValue dlt_file_read(DltFile *file, int verbose)
    1529              : {
    1530              :     long *ptr;
    1531              :     int found = DLT_RETURN_OK;
    1532              : 
    1533         2752 :     if (file == NULL)
    1534              :         return DLT_RETURN_WRONG_PARAMETER;
    1535              : 
    1536         2752 :     if (verbose)
    1537            0 :         dlt_vlog(LOG_DEBUG, "%s: Message %d:\n", __func__, file->counter_total);
    1538              : 
    1539              :     /* allocate new memory for index if number of messages exceeds a multiple of DLT_COMMON_INDEX_ALLOC (e.g.: 1000) */
    1540         2752 :     if (file->counter % DLT_COMMON_INDEX_ALLOC == 0) {
    1541          350 :         ptr = (long *)malloc(((file->counter / DLT_COMMON_INDEX_ALLOC) + 1) * DLT_COMMON_INDEX_ALLOC * sizeof(long));
    1542              : 
    1543          350 :         if (ptr == NULL)
    1544              :             return DLT_RETURN_ERROR;
    1545              : 
    1546          350 :         if (file->index) {
    1547          312 :             memcpy(ptr, file->index, (size_t)(file->counter) * sizeof(long));
    1548          312 :             free(file->index);
    1549              :         }
    1550              : 
    1551          350 :         file->index = ptr;
    1552              :     }
    1553              : 
    1554              :     /* set to end of last succesful read message, because of conflicting calls to dlt_file_read and dlt_file_message */
    1555         2752 :     if (0 != fseek(file->handle, file->file_position, SEEK_SET)) {
    1556            0 :         dlt_vlog(LOG_WARNING, "Seek failed to file_position %" PRIu64 "\n",
    1557              :                  file->file_position);
    1558            0 :         return DLT_RETURN_ERROR;
    1559              :     }
    1560              : 
    1561              :     /* get file position at start of DLT message */
    1562         2752 :     if (verbose)
    1563            0 :         dlt_vlog(LOG_INFO, "Position in file: %" PRIu64 "\n", file->file_position);
    1564              : 
    1565              :     /* read header */
    1566         2752 :     if (dlt_file_read_header(file, verbose) < DLT_RETURN_OK) {
    1567              :         /* go back to last position in file */
    1568           38 :         if (0 != fseek(file->handle, file->file_position, SEEK_SET)) {
    1569            0 :             dlt_vlog(LOG_WARNING, "Seek failed to file_position %ld \n",
    1570              :                     file->file_position);
    1571              :         }
    1572           38 :         return DLT_RETURN_ERROR;
    1573              :     }
    1574              : 
    1575         2714 :     if (file->filter) {
    1576              :         /* read the extended header if filter is enabled and extended header exists */
    1577          630 :         if (dlt_file_read_header_extended(file, verbose) < DLT_RETURN_OK) {
    1578              :             /* go back to last position in file */
    1579            0 :             if (0 != fseek(file->handle, file->file_position, SEEK_SET))
    1580            0 :                 dlt_vlog(LOG_WARNING, "Seek to last file pos failed!\n");
    1581              : 
    1582            0 :             return DLT_RETURN_ERROR;
    1583              :         }
    1584              : 
    1585              :         /* check the filters if message is used */
    1586          630 :         if (dlt_message_filter_check(&(file->msg), file->filter, verbose) == DLT_RETURN_TRUE) {
    1587              :             /* filter matched, consequently store current message */
    1588              :             /* store index pointer to message position in DLT file */
    1589          318 :             file->index[file->counter] = file->file_position;
    1590          318 :             file->counter++;
    1591          318 :             file->position = file->counter - 1;
    1592              : 
    1593              :             found = DLT_RETURN_TRUE;
    1594              :         }
    1595              : 
    1596              :         /* skip payload data */
    1597          630 :         if (fseek(file->handle, file->msg.datasize, SEEK_CUR) != 0) {
    1598              :             /* go back to last position in file */
    1599            0 :             dlt_vlog(LOG_WARNING,
    1600              :                      "Seek failed to skip payload data of size %u!\n",
    1601              :                      file->msg.datasize);
    1602              : 
    1603            0 :             if (0 != fseek(file->handle, file->file_position, SEEK_SET))
    1604            0 :                 dlt_log(LOG_WARNING, "Seek back also failed!\n");
    1605              : 
    1606            0 :             return DLT_RETURN_ERROR;
    1607              :         }
    1608              :     }
    1609              :     else {
    1610              :         /* filter is disabled */
    1611              :         /* skip additional header parameters and payload data */
    1612         2084 :         if (fseek(file->handle,
    1613         2084 :                   (long) (file->msg.headersize - sizeof(DltStorageHeader) - sizeof(DltStandardHeader) + file->msg.datasize),
    1614              :                   SEEK_CUR)) {
    1615              : 
    1616            0 :             dlt_vlog(LOG_WARNING,
    1617              :                      "Seek failed to skip extra header and payload data from file of size %u!\n",
    1618            0 :                      file->msg.headersize - (int32_t)sizeof(DltStorageHeader) -
    1619            0 :                      (int32_t)sizeof(DltStandardHeader) + file->msg.datasize);
    1620              : 
    1621              :             /* go back to last position in file */
    1622            0 :             if (fseek(file->handle, file->file_position, SEEK_SET))
    1623            0 :                 dlt_log(LOG_WARNING, "Seek back also failed!\n");
    1624              : 
    1625            0 :             return DLT_RETURN_ERROR;
    1626              :         }
    1627              : 
    1628              :         /* store index pointer to message position in DLT file */
    1629         2084 :         file->index[file->counter] = file->file_position;
    1630         2084 :         file->counter++;
    1631         2084 :         file->position = file->counter - 1;
    1632              : 
    1633              :         found = DLT_RETURN_TRUE;
    1634              :     }
    1635              : 
    1636              :     /* increase total message counter */
    1637         2714 :     file->counter_total++;
    1638              : 
    1639              :     /* store position to next message */
    1640         2714 :     file->file_position = ftell(file->handle);
    1641              : 
    1642         2714 :     return found;
    1643              : }
    1644              : 
    1645            0 : DltReturnValue dlt_file_read_raw(DltFile *file, int resync, int verbose)
    1646              : {
    1647              :     int found = DLT_RETURN_OK;
    1648              :     long *ptr;
    1649              : 
    1650            0 :     if (verbose)
    1651            0 :         dlt_vlog(LOG_DEBUG, "%s: Message %d:\n", __func__, file->counter_total);
    1652              : 
    1653            0 :     if (file == NULL)
    1654              :         return DLT_RETURN_WRONG_PARAMETER;
    1655              : 
    1656              :     /* allocate new memory for index if number of messages exceeds a multiple of DLT_COMMON_INDEX_ALLOC (e.g.: 1000) */
    1657            0 :     if (file->counter % DLT_COMMON_INDEX_ALLOC == 0) {
    1658            0 :         ptr = (long *)malloc(((file->counter / DLT_COMMON_INDEX_ALLOC) + 1) * DLT_COMMON_INDEX_ALLOC * sizeof(long));
    1659              : 
    1660            0 :         if (ptr == NULL)
    1661              :             return DLT_RETURN_ERROR;
    1662              : 
    1663            0 :         if (file->index) {
    1664            0 :             memcpy(ptr, file->index, (size_t)(file->counter) * sizeof(long));
    1665            0 :             free(file->index);
    1666              :         }
    1667              : 
    1668            0 :         file->index = ptr;
    1669              :     }
    1670              : 
    1671              :     /* set to end of last successful read message, because of conflicting calls to dlt_file_read and dlt_file_message */
    1672            0 :     if (0 != fseek(file->handle, file->file_position, SEEK_SET))
    1673              :         return DLT_RETURN_ERROR;
    1674              : 
    1675              :     /* get file position at start of DLT message */
    1676            0 :     if (verbose)
    1677            0 :         dlt_vlog(LOG_DEBUG, "Position in file: %" PRIu64 "\n", file->file_position);
    1678              : 
    1679              :     /* read header */
    1680            0 :     if (dlt_file_read_header_raw(file, resync, verbose) < DLT_RETURN_OK) {
    1681              :         /* go back to last position in file */
    1682            0 :         if (0 != fseek(file->handle, file->file_position, SEEK_SET))
    1683            0 :             dlt_log(LOG_WARNING, "dlt_file_read_raw, fseek failed 1\n");
    1684              : 
    1685            0 :         return DLT_RETURN_ERROR;
    1686              :     }
    1687              : 
    1688              :     /* read the extended header if filter is enabled and extended header exists */
    1689            0 :     if (dlt_file_read_header_extended(file, verbose) < DLT_RETURN_OK) {
    1690              :         /* go back to last position in file */
    1691            0 :         if (0 != fseek(file->handle, file->file_position, SEEK_SET))
    1692            0 :             dlt_log(LOG_WARNING, "dlt_file_read_raw, fseek failed 2\n");
    1693              : 
    1694            0 :         return DLT_RETURN_ERROR;
    1695              :     }
    1696              : 
    1697            0 :     if (dlt_file_read_data(file, verbose) < DLT_RETURN_OK) {
    1698              :         /* go back to last position in file */
    1699            0 :         if (0 != fseek(file->handle, file->file_position, SEEK_SET))
    1700            0 :             dlt_log(LOG_WARNING, "dlt_file_read_raw, fseek failed 3\n");
    1701              : 
    1702            0 :         return DLT_RETURN_ERROR;
    1703              :     }
    1704              : 
    1705              :     /* store index pointer to message position in DLT file */
    1706            0 :     file->index[file->counter] = file->file_position;
    1707            0 :     file->counter++;
    1708            0 :     file->position = file->counter - 1;
    1709              : 
    1710              :     found = DLT_RETURN_TRUE;
    1711              : 
    1712              :     /* increase total message counter */
    1713            0 :     file->counter_total++;
    1714              : 
    1715              :     /* store position to next message */
    1716            0 :     file->file_position = ftell(file->handle);
    1717              : 
    1718            0 :     return found;
    1719              : }
    1720              : 
    1721            0 : DltReturnValue dlt_file_close(DltFile *file, int verbose)
    1722              : {
    1723            0 :     PRINT_FUNCTION_VERBOSE(verbose);
    1724              : 
    1725            0 :     if (file == NULL)
    1726              :         return DLT_RETURN_WRONG_PARAMETER;
    1727              : 
    1728            0 :     if (file->handle)
    1729            0 :         fclose(file->handle);
    1730              : 
    1731            0 :     file->handle = NULL;
    1732              : 
    1733            0 :     return DLT_RETURN_OK;
    1734              : }
    1735              : 
    1736         3770 : DltReturnValue dlt_file_message(DltFile *file, int index, int verbose)
    1737              : {
    1738         3770 :     PRINT_FUNCTION_VERBOSE(verbose);
    1739              : 
    1740         3770 :     if (file == NULL)
    1741              :         return DLT_RETURN_WRONG_PARAMETER;
    1742              : 
    1743              :     /* check if message is in range */
    1744         3770 :     if (index < 0 || index >= file->counter) {
    1745            0 :         dlt_vlog(LOG_WARNING, "Message %d out of range!\r\n", index);
    1746            0 :         return DLT_RETURN_WRONG_PARAMETER;
    1747              :     }
    1748              : 
    1749              :     /* seek to position in file */
    1750         3770 :     if (fseek(file->handle, file->index[index], SEEK_SET) != 0) {
    1751            0 :         dlt_vlog(LOG_WARNING, "Seek to message %d to position %ld failed!\r\n",
    1752            0 :                  index, file->index[index]);
    1753            0 :         return DLT_RETURN_ERROR;
    1754              :     }
    1755              : 
    1756              :     /* read all header and payload */
    1757         3770 :     if (dlt_file_read_header(file, verbose) < DLT_RETURN_OK)
    1758              :         return DLT_RETURN_ERROR;
    1759              : 
    1760         3770 :     if (dlt_file_read_header_extended(file, verbose) < DLT_RETURN_OK)
    1761              :         return DLT_RETURN_ERROR;
    1762              : 
    1763         3770 :     if (dlt_file_read_data(file, verbose) < DLT_RETURN_OK)
    1764              :         return DLT_RETURN_ERROR;
    1765              : 
    1766              :     /* set current position in file */
    1767         3770 :     file->position = index;
    1768              : 
    1769         3770 :     return DLT_RETURN_OK;
    1770              : }
    1771              : 
    1772           51 : DltReturnValue dlt_file_free(DltFile *file, int verbose)
    1773              : {
    1774           51 :     PRINT_FUNCTION_VERBOSE(verbose);
    1775              : 
    1776           51 :     if (file == NULL)
    1777              :         return DLT_RETURN_WRONG_PARAMETER;
    1778              : 
    1779              :     /* delete index lost if exists */
    1780           51 :     if (file->index)
    1781           36 :         free(file->index);
    1782              : 
    1783           51 :     file->index = NULL;
    1784              : 
    1785              :     /* close file */
    1786           51 :     if (file->handle)
    1787           41 :         fclose(file->handle);
    1788              : 
    1789           51 :     file->handle = NULL;
    1790              : 
    1791           51 :     return dlt_message_free(&(file->msg), verbose);
    1792              : }
    1793              : 
    1794              : #if defined DLT_DAEMON_USE_FIFO_IPC || defined DLT_LIB_USE_FIFO_IPC
    1795        21222 : void dlt_log_set_fifo_basedir(const char *pipe_dir)
    1796              : {
    1797              :     strncpy(dltFifoBaseDir, pipe_dir, DLT_PATH_MAX);
    1798        21222 :     dltFifoBaseDir[DLT_PATH_MAX - 1] = 0;
    1799        21213 : }
    1800              : #endif
    1801              : 
    1802              : #ifdef DLT_SHM_ENABLE
    1803              : void dlt_log_set_shm_name(const char *env_shm_name)
    1804              : {
    1805              :     strncpy(dltShmName, env_shm_name, NAME_MAX);
    1806              :     dltShmName[NAME_MAX] = 0;
    1807              : }
    1808              : #endif
    1809              : 
    1810            0 : void dlt_print_with_attributes(bool state)
    1811              : {
    1812            0 :     print_with_attributes = state;
    1813            0 : }
    1814              : 
    1815        21255 : DltReturnValue dlt_receiver_init(DltReceiver *receiver, int fd, DltReceiverType type, int buffersize)
    1816              : {
    1817        21255 :     if (NULL == receiver)
    1818              :         return DLT_RETURN_WRONG_PARAMETER;
    1819              : 
    1820        21255 :     receiver->fd = fd;
    1821        21255 :     receiver->type = type;
    1822              : 
    1823              :     /** Reuse the receiver buffer if it exists and the buffer size
    1824              :       * is not changed. If not, free the old one and allocate a new buffer.
    1825              :       */
    1826        21255 :     if ((NULL != receiver->buffer) && ( buffersize != receiver->buffersize)) {
    1827            0 :        free(receiver->buffer);
    1828            0 :        receiver->buffer = NULL;
    1829              :     }
    1830              : 
    1831        21255 :     if (NULL == receiver->buffer) {
    1832        21255 :         receiver->lastBytesRcvd = 0;
    1833        21255 :         receiver->bytesRcvd = 0;
    1834        21255 :         receiver->totalBytesRcvd = 0;
    1835        21255 :         receiver->buf = NULL;
    1836        21255 :         receiver->backup_buf = NULL;
    1837        21255 :         receiver->buffer = (char *)calloc(1, (size_t)buffersize);
    1838        21255 :         receiver->buffersize = (uint32_t)buffersize;
    1839              :     }
    1840              : 
    1841        21255 :     if (NULL == receiver->buffer) {
    1842            0 :         dlt_log(LOG_ERR, "allocate memory for receiver buffer failed.\n");
    1843            0 :         return DLT_RETURN_ERROR;
    1844              :     }
    1845              :     else {
    1846        21255 :         receiver->buf = receiver->buffer;
    1847              :     }
    1848              : 
    1849        21255 :     return DLT_RETURN_OK;
    1850              : }
    1851              : 
    1852            9 : DltReturnValue dlt_receiver_init_global_buffer(DltReceiver *receiver, int fd, DltReceiverType type, char **buffer)
    1853              : {
    1854            9 :     if (receiver == NULL)
    1855              :         return DLT_RETURN_WRONG_PARAMETER;
    1856              : 
    1857            9 :     if (*buffer == NULL) {
    1858              :         /* allocating the buffer once and using it for all application receivers
    1859              :          * by keeping allocated buffer in app_recv_buffer global handle
    1860              :          */
    1861            9 :         *buffer = (char *)malloc(DLT_RECEIVE_BUFSIZE);
    1862              : 
    1863            9 :         if (*buffer == NULL)
    1864              :             return DLT_RETURN_ERROR;
    1865              :     }
    1866              : 
    1867            9 :     receiver->lastBytesRcvd = 0;
    1868            9 :     receiver->bytesRcvd = 0;
    1869            9 :     receiver->totalBytesRcvd = 0;
    1870            9 :     receiver->buffersize = DLT_RECEIVE_BUFSIZE;
    1871            9 :     receiver->fd = fd;
    1872            9 :     receiver->type = type;
    1873            9 :     receiver->buffer = *buffer;
    1874            9 :     receiver->backup_buf = NULL;
    1875            9 :     receiver->buf = receiver->buffer;
    1876              : 
    1877            9 :     return DLT_RETURN_OK;
    1878              : }
    1879              : 
    1880        21254 : DltReturnValue dlt_receiver_free(DltReceiver *receiver)
    1881              : {
    1882              : 
    1883        21254 :     if (receiver == NULL)
    1884              :         return DLT_RETURN_WRONG_PARAMETER;
    1885              : 
    1886        21254 :     if (receiver->buffer)
    1887        21252 :         free(receiver->buffer);
    1888              : 
    1889        21254 :     if (receiver->backup_buf)
    1890            0 :         free(receiver->backup_buf);
    1891              : 
    1892        21254 :     receiver->buffer = NULL;
    1893        21254 :     receiver->buf = NULL;
    1894        21254 :     receiver->backup_buf = NULL;
    1895              : 
    1896        21254 :     return DLT_RETURN_OK;
    1897              : }
    1898              : 
    1899            9 : DltReturnValue dlt_receiver_free_global_buffer(DltReceiver *receiver)
    1900              : {
    1901              : 
    1902            9 :     if (receiver == NULL)
    1903              :         return DLT_RETURN_WRONG_PARAMETER;
    1904              : 
    1905            9 :     if (receiver->backup_buf)
    1906            0 :         free(receiver->backup_buf);
    1907              : 
    1908            9 :     receiver->buffer = NULL;
    1909            9 :     receiver->buf = NULL;
    1910            9 :     receiver->backup_buf = NULL;
    1911              : 
    1912            9 :     return DLT_RETURN_OK;
    1913              : }
    1914              : 
    1915         1803 : int dlt_receiver_receive(DltReceiver *receiver)
    1916              : {
    1917              :     socklen_t addrlen;
    1918              : 
    1919         1803 :     if (receiver == NULL)
    1920              :         return -1;
    1921              : 
    1922         1803 :     if (receiver->buffer == NULL)
    1923              :         return -1;
    1924              : 
    1925         1802 :     receiver->buf = (char *)receiver->buffer;
    1926         1802 :     receiver->lastBytesRcvd = receiver->bytesRcvd;
    1927              : 
    1928         1802 :     if ((receiver->lastBytesRcvd) && (receiver->backup_buf != NULL)) {
    1929            0 :         memcpy(receiver->buf, receiver->backup_buf, (size_t)receiver->lastBytesRcvd);
    1930            0 :         free(receiver->backup_buf);
    1931            0 :         receiver->backup_buf = NULL;
    1932              :     }
    1933              : 
    1934         1802 :     if (receiver->type == DLT_RECEIVE_SOCKET)
    1935              :         /* wait for data from socket */
    1936          426 :         receiver->bytesRcvd = recv(receiver->fd,
    1937          426 :                                    receiver->buf + receiver->lastBytesRcvd,
    1938          426 :                                    receiver->buffersize - (uint32_t) receiver->lastBytesRcvd,
    1939              :                                    0);
    1940         1376 :     else if (receiver->type == DLT_RECEIVE_FD)
    1941              :         /* wait for data from fd */
    1942         1376 :         receiver->bytesRcvd = read(receiver->fd,
    1943         1376 :                                    receiver->buf + receiver->lastBytesRcvd,
    1944         1376 :                                    receiver->buffersize - (uint32_t) receiver->lastBytesRcvd);
    1945              : 
    1946              :     else { /* receiver->type == DLT_RECEIVE_UDP_SOCKET */
    1947              :         /* wait for data from UDP socket */
    1948            0 :         addrlen = sizeof(receiver->addr);
    1949            0 :         receiver->bytesRcvd = recvfrom(receiver->fd,
    1950            0 :                                        receiver->buf + receiver->lastBytesRcvd,
    1951            0 :                                        receiver->buffersize - receiver->lastBytesRcvd,
    1952              :                                        0,
    1953            0 :                                        (struct sockaddr *)&(receiver->addr),
    1954              :                                        &addrlen);
    1955              :     }
    1956              : 
    1957         1802 :     if (receiver->bytesRcvd <= 0) {
    1958            6 :         receiver->bytesRcvd = 0;
    1959            6 :         return receiver->bytesRcvd;
    1960              :     } /* if */
    1961              : 
    1962         1796 :     receiver->totalBytesRcvd += receiver->bytesRcvd;
    1963         1796 :     receiver->bytesRcvd += receiver->lastBytesRcvd;
    1964              : 
    1965         1796 :     return receiver->bytesRcvd;
    1966              : }
    1967              : 
    1968         6099 : DltReturnValue dlt_receiver_remove(DltReceiver *receiver, int size)
    1969              : {
    1970         6099 :     if (receiver == NULL)
    1971              :         return DLT_RETURN_WRONG_PARAMETER;
    1972              : 
    1973         6142 :     if (receiver->buf == NULL)
    1974              :         return DLT_RETURN_ERROR;
    1975              : 
    1976         6142 :     if ((size > receiver->bytesRcvd) || (size <= 0)) {
    1977            0 :         receiver->buf = receiver->buf + receiver->bytesRcvd;
    1978            0 :         receiver->bytesRcvd = 0;
    1979            0 :         return DLT_RETURN_WRONG_PARAMETER;
    1980              :     }
    1981              : 
    1982         6142 :     receiver->bytesRcvd = receiver->bytesRcvd - size;
    1983          263 :     receiver->buf = receiver->buf + size;
    1984              : 
    1985         6099 :     return DLT_RETURN_OK;
    1986              : }
    1987              : 
    1988         1797 : DltReturnValue dlt_receiver_move_to_begin(DltReceiver *receiver)
    1989              : {
    1990         1797 :     if (receiver == NULL)
    1991              :         return DLT_RETURN_WRONG_PARAMETER;
    1992              : 
    1993         1797 :     if ((receiver->buffer == NULL) || (receiver->buf == NULL))
    1994              :         return DLT_RETURN_ERROR;
    1995              : 
    1996         1797 :     if ((receiver->buffer != receiver->buf) && (receiver->bytesRcvd != 0)) {
    1997            0 :         receiver->backup_buf = calloc((size_t)(receiver->bytesRcvd + 1), sizeof(char));
    1998              : 
    1999            0 :         if (receiver->backup_buf == NULL)
    2000            0 :             dlt_vlog(LOG_WARNING,
    2001              :                      "Can't allocate memory for backup buf, there will be atleast"
    2002              :                      "one corrupted message for fd[%d] \n", receiver->fd);
    2003              :         else
    2004            0 :             memcpy(receiver->backup_buf, receiver->buf, (size_t)receiver->bytesRcvd);
    2005              :     }
    2006              : 
    2007              :     return DLT_RETURN_OK;
    2008              : }
    2009              : 
    2010          133 : int dlt_receiver_check_and_get(DltReceiver *receiver,
    2011              :                                void *dest,
    2012              :                                unsigned int to_get,
    2013              :                                unsigned int flags)
    2014              : {
    2015          133 :     size_t min_size = (size_t)to_get;
    2016              :     uint8_t *src = NULL;
    2017              : 
    2018          133 :     if (flags & DLT_RCV_SKIP_HEADER)
    2019           88 :         min_size += sizeof(DltUserHeader);
    2020              : 
    2021          133 :     if (!receiver ||
    2022          133 :         (receiver->bytesRcvd < (int32_t) min_size) ||
    2023          133 :         !receiver->buf ||
    2024              :         !dest)
    2025              :         return DLT_RETURN_WRONG_PARAMETER;
    2026              : 
    2027              :     src = (uint8_t *)receiver->buf;
    2028              : 
    2029          133 :     if (flags & DLT_RCV_SKIP_HEADER)
    2030           88 :         src += sizeof(DltUserHeader);
    2031              : 
    2032              :     memcpy(dest, src, to_get);
    2033              : 
    2034          133 :     if (flags & DLT_RCV_REMOVE) {
    2035            0 :         if (dlt_receiver_remove(receiver, (int)min_size) != DLT_RETURN_OK) {
    2036            0 :             dlt_log(LOG_WARNING, "Can't remove bytes from receiver\n");
    2037            0 :             return DLT_RETURN_ERROR;
    2038              :         }
    2039              :     }
    2040              : 
    2041          133 :     return to_get;
    2042              : }
    2043              : 
    2044        12105 : DltReturnValue dlt_set_storageheader(DltStorageHeader *storageheader, const char *ecu)
    2045              : {
    2046              : 
    2047              : #if !defined(_MSC_VER)
    2048              :     struct timeval tv;
    2049              : #endif
    2050              : 
    2051        12105 :     if ((storageheader == NULL) || (ecu == NULL))
    2052              :         return DLT_RETURN_WRONG_PARAMETER;
    2053              : 
    2054              :     /* get time of day */
    2055              : #if defined(_MSC_VER)
    2056              :     time(&(storageheader->seconds));
    2057              : #else
    2058        12105 :     gettimeofday(&tv, NULL);
    2059              : #endif
    2060              : 
    2061              :     /* prepare storage header */
    2062        12105 :     storageheader->pattern[0] = 'D';
    2063        12105 :     storageheader->pattern[1] = 'L';
    2064        12105 :     storageheader->pattern[2] = 'T';
    2065        12105 :     storageheader->pattern[3] = 0x01;
    2066              : 
    2067        12105 :     dlt_set_id(storageheader->ecu, ecu);
    2068              : 
    2069              :     /* Set current time */
    2070              : #if defined(_MSC_VER)
    2071              :     storageheader->microseconds = 0;
    2072              : #else
    2073        12105 :     storageheader->seconds = (uint32_t) tv.tv_sec; /* value is long */
    2074        12105 :     storageheader->microseconds = (int32_t) tv.tv_usec; /* value is long */
    2075              : #endif
    2076              : 
    2077        12105 :     return DLT_RETURN_OK;
    2078              : }
    2079              : 
    2080            9 : DltReturnValue dlt_check_rcv_data_size(int received, int required)
    2081              : {
    2082              :     int _ret = DLT_RETURN_OK;
    2083            9 :     if (received < required) {
    2084            1 :         dlt_vlog(LOG_WARNING, "%s: Received data not complete\n", __func__);
    2085              :         _ret = DLT_RETURN_ERROR;
    2086              :     }
    2087              : 
    2088            9 :     return _ret;
    2089              : }
    2090              : 
    2091         6589 : DltReturnValue dlt_check_storageheader(DltStorageHeader *storageheader)
    2092              : {
    2093         6589 :     if (storageheader == NULL)
    2094              :         return DLT_RETURN_WRONG_PARAMETER;
    2095              : 
    2096        13178 :     return ((storageheader->pattern[0] == 'D') &&
    2097         6589 :             (storageheader->pattern[1] == 'L') &&
    2098         6589 :             (storageheader->pattern[2] == 'T') &&
    2099         6589 :             (storageheader->pattern[3] == 1))
    2100        13178 :            ? DLT_RETURN_TRUE : DLT_RETURN_OK;
    2101              : }
    2102              : 
    2103            0 : DltReturnValue dlt_buffer_init_static_server(DltBuffer *buf, const unsigned char *ptr, uint32_t size)
    2104              : {
    2105            0 :     if ((buf == NULL) || (ptr == NULL))
    2106              :         return DLT_RETURN_WRONG_PARAMETER;
    2107              : 
    2108              :     DltBufferHead *head;
    2109              : 
    2110              :     /* Init parameters */
    2111            0 :     buf->shm = (unsigned char *)ptr;
    2112            0 :     buf->min_size = size;
    2113            0 :     buf->max_size = size;
    2114            0 :     buf->step_size = 0;
    2115              : 
    2116              :     /* Init pointers */
    2117              :     head = (DltBufferHead *)buf->shm;
    2118            0 :     head->read = 0;
    2119            0 :     head->write = 0;
    2120            0 :     head->count = 0;
    2121            0 :     buf->mem = (unsigned char *)(buf->shm + sizeof(DltBufferHead));
    2122            0 :     buf->size = (unsigned int) buf->min_size - (unsigned int) sizeof(DltBufferHead);
    2123              : 
    2124              :     /* clear memory */
    2125            0 :     memset(buf->mem, 0, buf->size);
    2126              : 
    2127            0 :     dlt_vlog(LOG_DEBUG,
    2128              :              "%s: Buffer: Size %u, Start address %lX\n",
    2129            0 :              __func__, buf->size, (unsigned long)buf->mem);
    2130              : 
    2131            0 :     return DLT_RETURN_OK; /* OK */
    2132              : }
    2133              : 
    2134            0 : DltReturnValue dlt_buffer_init_static_client(DltBuffer *buf, const unsigned char *ptr, uint32_t size)
    2135              : {
    2136            0 :     if ((buf == NULL) || (ptr == NULL))
    2137              :         return DLT_RETURN_WRONG_PARAMETER;
    2138              : 
    2139              :     /* Init parameters */
    2140            0 :     buf->shm = (unsigned char *)ptr;
    2141            0 :     buf->min_size = size;
    2142            0 :     buf->max_size = size;
    2143            0 :     buf->step_size = 0;
    2144              : 
    2145              :     /* Init pointers */
    2146            0 :     buf->mem = (unsigned char *)(buf->shm + sizeof(DltBufferHead));
    2147            0 :     buf->size = (uint32_t)(buf->min_size - sizeof(DltBufferHead));
    2148              : 
    2149            0 :     dlt_vlog(LOG_DEBUG,
    2150              :              "%s: Buffer: Size %u, Start address %lX\n",
    2151              :              __func__, buf->size, (unsigned long)buf->mem);
    2152              : 
    2153            0 :     return DLT_RETURN_OK; /* OK */
    2154              : }
    2155              : 
    2156        21343 : DltReturnValue dlt_buffer_init_dynamic(DltBuffer *buf, uint32_t min_size, uint32_t max_size, uint32_t step_size)
    2157              : {
    2158              :     /*Do not DLT_SEM_LOCK inside here! */
    2159              :     DltBufferHead *head;
    2160              : 
    2161              :     /* catch null pointer */
    2162        21343 :     if (buf == NULL)
    2163              :         return DLT_RETURN_WRONG_PARAMETER;
    2164              : 
    2165              :     /* catch 0 logical errors */
    2166        21335 :     if ((min_size == 0) || (max_size == 0) || (step_size == 0))
    2167              :         return DLT_RETURN_WRONG_PARAMETER;
    2168              : 
    2169        21328 :     if (min_size > max_size)
    2170              :         return DLT_RETURN_WRONG_PARAMETER;
    2171              : 
    2172        21328 :     if (step_size > max_size)
    2173              :         return DLT_RETURN_WRONG_PARAMETER;
    2174              : 
    2175              :     /* Init parameters */
    2176        21328 :     buf->min_size = min_size;
    2177        21328 :     buf->max_size = max_size;
    2178        21328 :     buf->step_size = step_size;
    2179              : 
    2180              :     /* allocat memory */
    2181        21328 :     buf->shm = malloc(buf->min_size);
    2182              : 
    2183        21328 :     if (buf->shm == NULL) {
    2184            0 :         dlt_vlog(LOG_EMERG,
    2185              :                  "%s: Buffer: Cannot allocate %u bytes\n",
    2186              :                  __func__, buf->min_size);
    2187            0 :         return DLT_RETURN_ERROR;
    2188              :     }
    2189              : 
    2190              :     /* Init pointers */
    2191              :     head = (DltBufferHead *)buf->shm;
    2192        21328 :     head->read = 0;
    2193        21328 :     head->write = 0;
    2194        21328 :     head->count = 0;
    2195        21328 :     buf->mem = (unsigned char *)(buf->shm + sizeof(DltBufferHead));
    2196              : 
    2197        21328 :     if (buf->min_size < (uint32_t)sizeof(DltBufferHead)) {
    2198            0 :         dlt_vlog(LOG_ERR,
    2199              :                  "%s: min_size is too small [%u]\n",
    2200              :                  __func__, buf->min_size);
    2201            0 :         return DLT_RETURN_WRONG_PARAMETER;
    2202              :     }
    2203              : 
    2204        21328 :     buf->size = (uint32_t) (buf->min_size - sizeof(DltBufferHead));
    2205              : 
    2206        21328 :     dlt_vlog(LOG_DEBUG,
    2207              :              "%s: Buffer: Size %u, Start address %lX\n",
    2208              :              __func__, buf->size, (unsigned long)buf->mem);
    2209              : 
    2210              :     /* clear memory */
    2211        21328 :     memset(buf->mem, 0, (size_t)buf->size);
    2212              : 
    2213        21328 :     return DLT_RETURN_OK; /* OK */
    2214              : }
    2215              : 
    2216            0 : DltReturnValue dlt_buffer_free_static(DltBuffer *buf)
    2217              : {
    2218              :     /* catch null pointer */
    2219            0 :     if (buf == NULL)
    2220              :         return DLT_RETURN_WRONG_PARAMETER;
    2221              : 
    2222            0 :     if (buf->mem == NULL) {
    2223              :         /* buffer not initialized */
    2224            0 :         dlt_vlog(LOG_WARNING, "%s: Buffer: Buffer not initialized\n", __func__);
    2225            0 :         return DLT_RETURN_ERROR; /* ERROR */
    2226              :     }
    2227              : 
    2228              :     return DLT_RETURN_OK;
    2229              : }
    2230              : 
    2231        21318 : DltReturnValue dlt_buffer_free_dynamic(DltBuffer *buf)
    2232              : {
    2233              :     /* catch null pointer */
    2234        21318 :     if (buf == NULL)
    2235              :         return DLT_RETURN_WRONG_PARAMETER;
    2236              : 
    2237        21317 :     if (buf->shm == NULL) {
    2238              :         /* buffer not initialized */
    2239            0 :         dlt_vlog(LOG_WARNING, "%s: Buffer: Buffer not initialized\n", __func__);
    2240            0 :         return DLT_RETURN_ERROR; /* ERROR */
    2241              :     }
    2242              : 
    2243        21317 :     free(buf->shm);
    2244        21317 :     buf->shm = NULL;
    2245        21317 :     buf->mem = NULL;
    2246              : 
    2247        21317 :     return DLT_RETURN_OK;
    2248              : }
    2249              : 
    2250        41029 : void dlt_buffer_write_block(DltBuffer *buf, int *write, const unsigned char *data, unsigned int size)
    2251              : {
    2252              :     /* catch null pointer */
    2253        41029 :     if ((buf != NULL) && (write != NULL) && (data != NULL)) {
    2254        40010 :         if (size <= buf->size){
    2255        40010 :             if (( (unsigned int) (*write ) + size) <= buf->size) {
    2256              :                 /* write one block */
    2257        40009 :                 memcpy(buf->mem + *write, data, size);
    2258        40009 :                 *write += (int) size;
    2259              :             }
    2260              :             else {
    2261              :                 /* when (*write) = buf->size, write only the second block
    2262              :                 * and update write position correspondingly.
    2263              :                 */
    2264            1 :                 if((unsigned int) (*write) <= buf->size) {
    2265              :                     /* write two blocks */
    2266            1 :                     memcpy(buf->mem + *write, data, buf->size - (unsigned int) (*write));
    2267            1 :                     memcpy(buf->mem, data + buf->size - *write, size - buf->size + (unsigned int) (*write));
    2268            1 :                     *write += (int) (size - buf->size);
    2269              :                 }
    2270              :             }
    2271              :         }
    2272              :         else {
    2273            0 :             dlt_vlog(LOG_WARNING, "%s: Write error: ring buffer to small\n", __func__);
    2274              :         }
    2275              :     }
    2276              :     else {
    2277         1019 :         dlt_vlog(LOG_WARNING, "%s: Wrong parameter: Null pointer\n", __func__);
    2278              :     }
    2279        41029 : }
    2280              : 
    2281           53 : void dlt_buffer_read_block(DltBuffer *buf, int *read, unsigned char *data, unsigned int size)
    2282              : {
    2283              :     /* catch nullpointer */
    2284           53 :     if ((buf != NULL) && (read != NULL) && (data != NULL)) {
    2285           37 :         if (((unsigned int)(*read) + size) <= buf->size) {
    2286              :             /* read one block */
    2287           35 :             memcpy(data, buf->mem + *read, size);
    2288           35 :             *read += (int)size;
    2289              :         }
    2290              :         else {
    2291              :             /* when (*read) = buf->size, read only the second block
    2292              :             * and update read position correspondingly.
    2293              :             */
    2294            2 :             if ((unsigned int)(*read) <= buf->size) {
    2295              :                 /* read two blocks */
    2296            1 :                 memcpy(data, buf->mem + *read, buf->size - (unsigned int)(*read));
    2297            1 :                 memcpy(data + buf->size - *read, buf->mem, size - buf->size + (unsigned int)(*read));
    2298            1 :                 *read += (int) (size - buf->size);
    2299              :             }
    2300              :         }
    2301              :     }
    2302              :     else {
    2303           16 :         dlt_vlog(LOG_WARNING, "%s: Wrong parameter: Null pointer\n", __func__);
    2304              :     }
    2305           53 : }
    2306              : 
    2307          857 : int dlt_buffer_check_size(DltBuffer *buf, int needed)
    2308              : {
    2309          857 :     if (buf == NULL)
    2310              :         return DLT_RETURN_WRONG_PARAMETER;
    2311              : 
    2312          857 :     if ((buf->size + sizeof(DltBufferHead) + (size_t) needed) > buf->max_size)
    2313            0 :         return DLT_RETURN_ERROR;
    2314              : 
    2315              :     return DLT_RETURN_OK;
    2316              : }
    2317              : 
    2318            7 : int dlt_buffer_increase_size(DltBuffer *buf)
    2319              : {
    2320              :     DltBufferHead *head, *new_head;
    2321              :     unsigned char *new_ptr;
    2322              : 
    2323              :     /* catch null pointer */
    2324            7 :     if (buf == NULL) {
    2325            1 :         dlt_vlog(LOG_WARNING, "%s: Wrong parameter: Null pointer\n", __func__);
    2326            1 :         return DLT_RETURN_WRONG_PARAMETER;
    2327              :     }
    2328              : 
    2329              :     /* check size */
    2330            6 :     if (buf->step_size == 0)
    2331              :         /* cannot increase size */
    2332              :         return DLT_RETURN_ERROR;
    2333              : 
    2334              :     /* check size */
    2335            6 :     if ((buf->size + sizeof(DltBufferHead) + buf->step_size) > buf->max_size)
    2336              :         /* max size reached, do not increase */
    2337              :         return DLT_RETURN_ERROR;
    2338              : 
    2339              :     /* allocate new buffer */
    2340            6 :     new_ptr = malloc(buf->size + sizeof(DltBufferHead) + buf->step_size);
    2341              : 
    2342            6 :     if (new_ptr == NULL) {
    2343            0 :         dlt_vlog(LOG_WARNING,
    2344              :                  "%s: Buffer: Cannot increase size because allocate %u bytes failed\n",
    2345              :                  __func__, buf->min_size);
    2346            0 :         return DLT_RETURN_ERROR;
    2347              :     }
    2348              : 
    2349              :     /* copy data */
    2350            6 :     head = (DltBufferHead *)buf->shm;
    2351              :     new_head = (DltBufferHead *)new_ptr;
    2352              : 
    2353            6 :     if (head->read < head->write) {
    2354            4 :         memcpy(new_ptr + sizeof(DltBufferHead), buf->mem + head->read, (size_t)(head->write - head->read));
    2355            4 :         new_head->read = 0;
    2356            4 :         new_head->write = head->write - head->read;
    2357            4 :         new_head->count = head->count;
    2358              :     }
    2359              :     else {
    2360            2 :         memcpy(new_ptr + sizeof(DltBufferHead), buf->mem + head->read, buf->size - (uint32_t)(head->read));
    2361            2 :         memcpy(new_ptr + sizeof(DltBufferHead) + buf->size - head->read, buf->mem, (size_t)head->write);
    2362            2 :         new_head->read = 0;
    2363            2 :         new_head->write = (int)(buf->size) + head->write - head->read;
    2364            2 :         new_head->count = head->count;
    2365              :     }
    2366              : 
    2367              :     /* free old data */
    2368            6 :     free(buf->shm);
    2369              : 
    2370              :     /* update data */
    2371            6 :     buf->shm = new_ptr;
    2372            6 :     buf->mem = new_ptr + sizeof(DltBufferHead);
    2373            6 :     buf->size += buf->step_size;
    2374              : 
    2375            6 :     dlt_vlog(LOG_DEBUG,
    2376              :              "%s: Buffer: Size increased to %u bytes with start address %lX\n",
    2377              :              __func__,
    2378              :              buf->size + (int32_t)sizeof(DltBufferHead),
    2379              :              (unsigned long)buf->mem);
    2380              : 
    2381            6 :     return DLT_RETURN_OK; /* OK */
    2382              : }
    2383              : 
    2384            8 : int dlt_buffer_minimize_size(DltBuffer *buf)
    2385              : {
    2386              :     unsigned char *new_ptr;
    2387              : 
    2388              :     /* catch null pointer */
    2389            8 :     if (buf == NULL) {
    2390            1 :         dlt_vlog(LOG_WARNING, "%s: Wrong parameter: Null pointer\n", __func__);
    2391            1 :         return DLT_RETURN_WRONG_PARAMETER;
    2392              :     }
    2393              : 
    2394            7 :     if ((buf->size + sizeof(DltBufferHead)) == buf->min_size)
    2395              :         /* already minimized */
    2396              :         return DLT_RETURN_OK;
    2397              : 
    2398              :     /* allocate new buffer */
    2399            0 :     new_ptr = malloc(buf->min_size);
    2400              : 
    2401            0 :     if (new_ptr == NULL) {
    2402            0 :         dlt_vlog(LOG_WARNING,
    2403              :                  "%s: Buffer: Cannot set to min size of %u bytes\n",
    2404              :                  __func__, buf->min_size);
    2405            0 :         return DLT_RETURN_ERROR;
    2406              :     }
    2407              : 
    2408              :     /* free old data */
    2409            0 :     free(buf->shm);
    2410              : 
    2411              :     /* update data */
    2412            0 :     buf->shm = new_ptr;
    2413            0 :     buf->mem = new_ptr + sizeof(DltBufferHead);
    2414            0 :     buf->size = (uint32_t)(buf->min_size - sizeof(DltBufferHead));
    2415              : 
    2416              :     /* reset pointers and counters */
    2417            0 :     ((int *)(buf->shm))[0] = 0;  /* pointer to write memory */
    2418            0 :     ((int *)(buf->shm))[1] = 0;  /* pointer to read memory */
    2419            0 :     ((int *)(buf->shm))[2] = 0;  /* number of packets */
    2420              : 
    2421            0 :     dlt_vlog(LOG_DEBUG,
    2422              :              "%s: Buffer: Buffer minimized to Size %u bytes with start address %lX\n",
    2423              :              __func__, buf->size, (unsigned long)buf->mem);
    2424              : 
    2425              :     /* clear memory */
    2426            0 :     memset(buf->mem, 0, buf->size);
    2427              : 
    2428            0 :     return DLT_RETURN_OK; /* OK */
    2429              : }
    2430              : 
    2431            9 : int dlt_buffer_reset(DltBuffer *buf)
    2432              : {
    2433              :     /* catch null pointer */
    2434            9 :     if (buf == NULL) {
    2435            1 :         dlt_vlog(LOG_WARNING, "%s: Wrong parameter: Null pointer\n", __func__);
    2436            1 :         return DLT_RETURN_WRONG_PARAMETER;
    2437              :     }
    2438              : 
    2439            8 :     dlt_vlog(LOG_WARNING,
    2440              :              "%s: Buffer: Buffer reset triggered. Size: %u, Start address: %lX\n",
    2441            8 :              __func__, buf->size, (unsigned long)buf->mem);
    2442              : 
    2443              :     /* reset pointers and counters */
    2444            8 :     ((int *)(buf->shm))[0] = 0;  /* pointer to write memory */
    2445            8 :     ((int *)(buf->shm))[1] = 0;  /* pointer to read memory */
    2446            8 :     ((int *)(buf->shm))[2] = 0;  /* number of packets */
    2447              : 
    2448              :     /* clear memory */
    2449            8 :     memset(buf->mem, 0, buf->size);
    2450              : 
    2451            8 :     return DLT_RETURN_OK; /* OK */
    2452              : }
    2453              : 
    2454         7516 : DltReturnValue dlt_buffer_push(DltBuffer *buf, const unsigned char *data, unsigned int size)
    2455              : {
    2456         7516 :     return dlt_buffer_push3(buf, data, size, 0, 0, 0, 0);
    2457              : }
    2458              : 
    2459        15284 : int dlt_buffer_push3(DltBuffer *buf,
    2460              :                      const unsigned char *data1,
    2461              :                      unsigned int size1,
    2462              :                      const unsigned char *data2,
    2463              :                      unsigned int size2,
    2464              :                      const unsigned char *data3,
    2465              :                      unsigned int size3)
    2466              : {
    2467              :     int free_size;
    2468              :     int write, read, count;
    2469              :     DltBufferBlockHead head;
    2470              : 
    2471              :     /* catch null pointer */
    2472        15284 :     if (buf == NULL)
    2473              :         return DLT_RETURN_WRONG_PARAMETER;
    2474              : 
    2475        15216 :     if (buf->shm == NULL) {
    2476              :         /* buffer not initialised */
    2477            0 :         dlt_vlog(LOG_ERR, "%s: Buffer: Buffer not initialized\n", __func__);
    2478            0 :         return DLT_RETURN_ERROR; /* ERROR */
    2479              :     }
    2480              : 
    2481              :     /* get current write pointer */
    2482        15216 :     write = ((int *)(buf->shm))[0];
    2483        15216 :     read = ((int *)(buf->shm))[1];
    2484        15216 :     count = ((int *)(buf->shm))[2];
    2485              : 
    2486              :     /* check pointers */
    2487        15216 :     if (((unsigned int)read > buf->size) || ((unsigned int)write > buf->size)) {
    2488            0 :         dlt_vlog(LOG_ERR,
    2489              :                  "%s: Buffer: Pointer out of range. Read: %d, Write: %d, Size: %u\n",
    2490              :                  __func__, read, write, buf->size);
    2491            0 :         dlt_buffer_reset(buf);
    2492            0 :         return DLT_RETURN_ERROR; /* ERROR */
    2493              :     }
    2494              : 
    2495              :     /* calculate free size */
    2496        15216 :     if (read > write)
    2497            0 :         free_size = read - write;
    2498        15216 :     else if (count && (write == read))
    2499              :         free_size = 0;
    2500              :     else
    2501        15216 :         free_size = (int)buf->size - write + read;
    2502              : 
    2503              :     /* check size */
    2504        15220 :     while (free_size < (int) (sizeof(DltBufferBlockHead) + size1 + size2 + size3)) {
    2505              :         /* try to increase size if possible */
    2506            4 :         if (dlt_buffer_increase_size(buf))
    2507              :             /* increase size is not possible */
    2508              :             /*dlt_log(LOG_ERR, "Buffer: Buffer is full\n"); */
    2509              :             return DLT_RETURN_ERROR; /* ERROR */
    2510              : 
    2511              :         /* update pointers */
    2512            4 :         write = ((int *)(buf->shm))[0];
    2513            4 :         read = ((int *)(buf->shm))[1];
    2514              : 
    2515              :             /* update free size */
    2516            4 :         if (read > write)
    2517            0 :             free_size = read - write;
    2518            4 :         else if (count && (write == read))
    2519              :             free_size = 0;
    2520              :         else
    2521            4 :             free_size = buf->size - write + read;
    2522              :     }
    2523              : 
    2524              :     /* set header */
    2525              :     strncpy(head.head, DLT_BUFFER_HEAD, 4);
    2526              :     head.head[3] = 0;
    2527        15216 :     head.status = 2;
    2528        15216 :     head.size = (int)(size1 + size2 + size3);
    2529              : 
    2530              :     /* write data */
    2531        15216 :     dlt_buffer_write_block(buf, &write, (unsigned char *)&head, sizeof(DltBufferBlockHead));
    2532              : 
    2533        15216 :     if (size1)
    2534        15216 :         dlt_buffer_write_block(buf, &write, data1, size1);
    2535              : 
    2536        15216 :     if (size2)
    2537         7702 :         dlt_buffer_write_block(buf, &write, data2, size2);
    2538              : 
    2539        15216 :     if (size3)
    2540         1875 :         dlt_buffer_write_block(buf, &write, data3, size3);
    2541              : 
    2542              :     /* update global shm pointers */
    2543        15216 :     ((int *)(buf->shm))[0] = write; /* set new write pointer */
    2544        15216 :     ((int *)(buf->shm))[2] += 1; /* increase counter */
    2545              : 
    2546        15216 :     return DLT_RETURN_OK; /* OK */
    2547              : 
    2548              : }
    2549              : 
    2550           64 : int dlt_buffer_get(DltBuffer *buf, unsigned char *data, int max_size, int delete)
    2551              : {
    2552              :     int used_size;
    2553              :     int write, read, count;
    2554           64 :     char head_compare[] = DLT_BUFFER_HEAD;
    2555              :     DltBufferBlockHead head;
    2556              : 
    2557              :     /* catch null pointer */
    2558           64 :     if (buf == NULL)
    2559              :         return DLT_RETURN_WRONG_PARAMETER;
    2560              : 
    2561           47 :     if (buf->shm == NULL) {
    2562              :         /* shm not initialised */
    2563            0 :         dlt_vlog(LOG_ERR, "%s: Buffer: SHM not initialized\n", __func__);
    2564            0 :         return DLT_RETURN_ERROR; /* ERROR */
    2565              :     }
    2566              : 
    2567              :     /* get current write pointer */
    2568           47 :     write = ((int *)(buf->shm))[0];
    2569           47 :     read = ((int *)(buf->shm))[1];
    2570           47 :     count = ((int *)(buf->shm))[2];
    2571              : 
    2572              :     /* check pointers */
    2573           47 :     if (((unsigned int)read > buf->size) || ((unsigned int)write > buf->size) || (count < 0)) {
    2574            3 :         dlt_vlog(LOG_ERR,
    2575              :                  "%s: Buffer: Pointer out of range. Read: %d, Write: %d, Count: %d, Size: %u\n",
    2576              :                  __func__, read, write, count, buf->size);
    2577            3 :         dlt_buffer_reset(buf);
    2578            3 :         return DLT_RETURN_ERROR; /* ERROR */
    2579              :     }
    2580              : 
    2581              :     /* check if data is in there */
    2582           44 :     if (count == 0) {
    2583           22 :         if (write != read) {
    2584            1 :             dlt_vlog(LOG_ERR,
    2585              :                      "%s: Buffer: SHM should be empty, but is not. Read: %d, Write: %d\n",
    2586              :                      __func__, read, write);
    2587            1 :             dlt_buffer_reset(buf);
    2588              :         }
    2589              : 
    2590           22 :         return DLT_RETURN_ERROR; /* ERROR */
    2591              :     }
    2592              : 
    2593              :     /* calculate used size */
    2594           22 :     if (write > read)
    2595           21 :         used_size = write - read;
    2596              :     else
    2597            1 :         used_size = (int)buf->size - read + write;
    2598              : 
    2599              :     /* first check size */
    2600           22 :     if (used_size < (int)(sizeof(DltBufferBlockHead))) {
    2601            1 :         dlt_vlog(LOG_ERR,
    2602              :                  "%s: Buffer: Used size is smaller than buffer block header size. Used size: %d\n",
    2603              :                  __func__, used_size);
    2604            1 :         dlt_buffer_reset(buf);
    2605            1 :         return DLT_RETURN_ERROR; /* ERROR */
    2606              :     }
    2607              : 
    2608              :     /* read header */
    2609           21 :     dlt_buffer_read_block(buf, &read, (unsigned char *)&head, sizeof(DltBufferBlockHead));
    2610              : 
    2611              :     /* check header */
    2612           21 :     if (memcmp((unsigned char *)(head.head), head_compare, sizeof(head_compare)) != 0) {
    2613            1 :         dlt_vlog(LOG_ERR, "%s: Buffer: Header head check failed\n", __func__);
    2614            1 :         dlt_buffer_reset(buf);
    2615            1 :         return DLT_RETURN_ERROR; /* ERROR */
    2616              :     }
    2617              : 
    2618           20 :     if (head.status != 2) {
    2619            0 :         dlt_vlog(LOG_ERR, "%s: Buffer: Header status check failed\n", __func__);
    2620            0 :         dlt_buffer_reset(buf);
    2621            0 :         return DLT_RETURN_ERROR; /* ERROR */
    2622              :     }
    2623              : 
    2624              :     /* second check size */
    2625           20 :     if (used_size < ((int)sizeof(DltBufferBlockHead) + head.size)) {
    2626            1 :         dlt_vlog(LOG_ERR,
    2627              :                  "%s: Buffer: Used size is smaller than buffer block header size And read header size. Used size: %d\n",
    2628              :                  __func__, used_size);
    2629            1 :         dlt_buffer_reset(buf);
    2630            1 :         return DLT_RETURN_ERROR; /* ERROR */
    2631              :     }
    2632              : 
    2633              :     /* third check size */
    2634           19 :     if (max_size && (head.size > max_size))
    2635            1 :         dlt_vlog(LOG_WARNING,
    2636              :                  "%s: Buffer: Max size is smaller than read header size. Max size: %d\n",
    2637              :                  __func__, max_size);
    2638              : 
    2639              :     /* nothing to do but data does not fit provided buffer */
    2640              : 
    2641           19 :     if ((data != NULL) && max_size) {
    2642              :         /* read data */
    2643           14 :         dlt_buffer_read_block(buf, &read, data, (unsigned int)head.size);
    2644              : 
    2645           14 :         if (delete)
    2646              :             /* update buffer pointers */
    2647            3 :             ((int *)(buf->shm))[1] = read; /* set new read pointer */
    2648              : 
    2649              :     }
    2650            5 :     else if (delete)
    2651              :     {
    2652            5 :         if ((unsigned int)(read + head.size) <= buf->size)
    2653            5 :             ((int *)(buf->shm))[1] = read + head.size;  /* set new read pointer */
    2654              :         else
    2655            0 :             ((int *)(buf->shm))[1] = read + head.size - (int)buf->size;  /* set new read pointer */
    2656              : 
    2657              :     }
    2658              : 
    2659            8 :     if (delete) {
    2660            8 :         ((int *)(buf->shm))[2] -= 1; /* decrease counter */
    2661              : 
    2662            8 :         if (((int *)(buf->shm))[2] == 0)
    2663              :             /* try to minimize size */
    2664            5 :             dlt_buffer_minimize_size(buf);
    2665              :     }
    2666              : 
    2667           19 :     return head.size; /* OK */
    2668              : }
    2669              : 
    2670            8 : int dlt_buffer_pull(DltBuffer *buf, unsigned char *data, int max_size)
    2671              : {
    2672            8 :     return dlt_buffer_get(buf, data, max_size, 1);
    2673              : }
    2674              : 
    2675           13 : int dlt_buffer_copy(DltBuffer *buf, unsigned char *data, int max_size)
    2676              : {
    2677           13 :     return dlt_buffer_get(buf, data, max_size, 0);
    2678              : }
    2679              : 
    2680            7 : int dlt_buffer_remove(DltBuffer *buf)
    2681              : {
    2682            7 :     return dlt_buffer_get(buf, 0, 0, 1);
    2683              : }
    2684              : 
    2685            2 : void dlt_buffer_info(DltBuffer *buf)
    2686              : {
    2687              :     /* check nullpointer */
    2688            2 :     if (buf == NULL) {
    2689            1 :         dlt_vlog(LOG_WARNING, "%s: Wrong parameter: Null pointer\n", __func__);
    2690            1 :         return;
    2691              :     }
    2692              : 
    2693            1 :     dlt_vlog(LOG_DEBUG,
    2694              :              "Buffer: Available size: %u, Buffer: Buffer full start address: %lX, Buffer: Buffer start address: %lX\n",
    2695            1 :              buf->size, (unsigned long)buf->shm, (unsigned long)buf->mem);
    2696              : }
    2697              : 
    2698            2 : void dlt_buffer_status(DltBuffer *buf)
    2699              : {
    2700              :     int write, read, count;
    2701              : 
    2702              :     /* check nullpointer */
    2703            2 :     if (buf == NULL) {
    2704            1 :         dlt_vlog(LOG_WARNING, "%s: Wrong parameter: Null pointer\n", __func__);
    2705            1 :         return;
    2706              :     }
    2707              : 
    2708              :     /* check if buffer available */
    2709            1 :     if (buf->shm == NULL)
    2710              :         return;
    2711              : 
    2712            1 :     write = ((int *)(buf->shm))[0];
    2713            1 :     read = ((int *)(buf->shm))[1];
    2714            1 :     count = ((int *)(buf->shm))[2];
    2715              : 
    2716            1 :     dlt_vlog(LOG_DEBUG,
    2717              :              "Buffer: Write: %d, Read: %d, Count: %d\n",
    2718              :              write, read, count);
    2719              : }
    2720              : 
    2721            3 : uint32_t dlt_buffer_get_total_size(DltBuffer *buf)
    2722              : {
    2723              :     /* catch null pointer */
    2724            3 :     if (buf == NULL)
    2725              :         return DLT_RETURN_WRONG_PARAMETER;
    2726              : 
    2727            2 :     return buf->max_size;
    2728              : }
    2729              : 
    2730         2503 : int dlt_buffer_get_used_size(DltBuffer *buf)
    2731              : {
    2732              :     int write, read, count;
    2733              : 
    2734              :     /* catch null pointer */
    2735         2503 :     if (buf == NULL)
    2736              :         return DLT_RETURN_WRONG_PARAMETER;
    2737              : 
    2738              :     /* check if buffer available */
    2739         2502 :     if (buf->shm == NULL)
    2740              :         return DLT_RETURN_OK;
    2741              : 
    2742         2502 :     write = ((int *)(buf->shm))[0];
    2743         2502 :     read = ((int *)(buf->shm))[1];
    2744         2502 :     count = ((int *)(buf->shm))[2];
    2745              : 
    2746         2502 :     if (count == 0)
    2747              :         return DLT_RETURN_OK;
    2748              : 
    2749         2501 :     if (write > read)
    2750         2501 :         return write - read;
    2751              : 
    2752            0 :     return (int)buf->size - read + write;
    2753              : }
    2754              : 
    2755         8529 : int dlt_buffer_get_message_count(DltBuffer *buf)
    2756              : {
    2757              :     /* catch null pointer */
    2758         8529 :     if (buf == NULL)
    2759              :         return DLT_RETURN_WRONG_PARAMETER;
    2760              : 
    2761              :     /* check if buffer available */
    2762         8529 :     if (buf->shm == NULL)
    2763              :         return DLT_RETURN_OK;
    2764              : 
    2765         8529 :     return ((int *)(buf->shm))[2];
    2766              : }
    2767              : 
    2768              : #if !defined (__WIN32__)
    2769              : 
    2770            0 : DltReturnValue dlt_setup_serial(int fd, speed_t speed)
    2771              : {
    2772              : #   if !defined (__WIN32__) && !defined(_MSC_VER)
    2773              :     struct termios config;
    2774              : 
    2775            0 :     if (isatty(fd) == 0)
    2776              :         return DLT_RETURN_ERROR;
    2777              : 
    2778            0 :     if (tcgetattr(fd, &config) < 0)
    2779              :         return DLT_RETURN_ERROR;
    2780              : 
    2781              :     /* Input flags - Turn off input processing
    2782              :      * convert break to null byte, no CR to NL translation,
    2783              :      * no NL to CR translation, don't mark parity errors or breaks
    2784              :      * no input parity check, don't strip high bit off,
    2785              :      * no XON/XOFF software flow control
    2786              :      */
    2787            0 :     config.c_iflag &= ~(IGNBRK | BRKINT | ICRNL |
    2788              :                         INLCR | PARMRK | INPCK | ISTRIP | IXON);
    2789              : 
    2790              :     /* Output flags - Turn off output processing
    2791              :      * no CR to NL translation, no NL to CR-NL translation,
    2792              :      * no NL to CR translation, no column 0 CR suppression,
    2793              :      * no Ctrl-D suppression, no fill characters, no case mapping,
    2794              :      * no local output processing
    2795              :      *
    2796              :      * config.c_oflag &= ~(OCRNL | ONLCR | ONLRET |
    2797              :      *                     ONOCR | ONOEOT| OFILL | OLCUC | OPOST);
    2798              :      */
    2799            0 :     config.c_oflag = 0;
    2800              : 
    2801              :     /* No line processing:
    2802              :      * echo off, echo newline off, canonical mode off,
    2803              :      * extended input processing off, signal chars off
    2804              :      */
    2805            0 :     config.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG);
    2806              : 
    2807              :     /* Turn off character processing
    2808              :      * clear current char size mask, no parity checking,
    2809              :      * no output processing, force 8 bit input
    2810              :      */
    2811            0 :     config.c_cflag &= ~(CSIZE | PARENB);
    2812            0 :     config.c_cflag |= CS8;
    2813              : 
    2814              :     /* One input byte is enough to return from read()
    2815              :      * Inter-character timer off
    2816              :      */
    2817            0 :     config.c_cc[VMIN] = 1;
    2818            0 :     config.c_cc[VTIME] = 0;
    2819              : 
    2820              :     /* Communication speed (simple version, using the predefined
    2821              :      * constants)
    2822              :      */
    2823            0 :     if ((cfsetispeed(&config, speed) < 0) || (cfsetospeed(&config, speed) < 0))
    2824            0 :         return DLT_RETURN_ERROR;
    2825              : 
    2826              :     /* Finally, apply the configuration
    2827              :      */
    2828            0 :     if (tcsetattr(fd, TCSAFLUSH, &config) < 0)
    2829              :         return DLT_RETURN_ERROR;
    2830              : 
    2831              :     return DLT_RETURN_OK;
    2832              : #   else
    2833              :     return DLT_RETURN_ERROR;
    2834              : #   endif
    2835              : }
    2836              : 
    2837            0 : speed_t dlt_convert_serial_speed(int baudrate)
    2838              : {
    2839              : #   if !defined (__WIN32__) && !defined(_MSC_VER) && !defined(__CYGWIN__)
    2840              :     speed_t ret;
    2841              : 
    2842            0 :     switch (baudrate) {
    2843              :     case  50:
    2844              :     {
    2845              :         ret = B50;
    2846              :         break;
    2847              :     }
    2848            0 :     case  75:
    2849              :     {
    2850              :         ret = B75;
    2851            0 :         break;
    2852              :     }
    2853            0 :     case  110:
    2854              :     {
    2855              :         ret = B110;
    2856            0 :         break;
    2857              :     }
    2858            0 :     case  134:
    2859              :     {
    2860              :         ret = B134;
    2861            0 :         break;
    2862              :     }
    2863            0 :     case  150:
    2864              :     {
    2865              :         ret = B150;
    2866            0 :         break;
    2867              :     }
    2868            0 :     case  200:
    2869              :     {
    2870              :         ret = B200;
    2871            0 :         break;
    2872              :     }
    2873            0 :     case  300:
    2874              :     {
    2875              :         ret = B300;
    2876            0 :         break;
    2877              :     }
    2878            0 :     case  600:
    2879              :     {
    2880              :         ret = B600;
    2881            0 :         break;
    2882              :     }
    2883            0 :     case  1200:
    2884              :     {
    2885              :         ret = B1200;
    2886            0 :         break;
    2887              :     }
    2888            0 :     case  1800:
    2889              :     {
    2890              :         ret = B1800;
    2891            0 :         break;
    2892              :     }
    2893            0 :     case  2400:
    2894              :     {
    2895              :         ret = B2400;
    2896            0 :         break;
    2897              :     }
    2898            0 :     case  4800:
    2899              :     {
    2900              :         ret = B4800;
    2901            0 :         break;
    2902              :     }
    2903            0 :     case  9600:
    2904              :     {
    2905              :         ret = B9600;
    2906            0 :         break;
    2907              :     }
    2908            0 :     case  19200:
    2909              :     {
    2910              :         ret = B19200;
    2911            0 :         break;
    2912              :     }
    2913            0 :     case  38400:
    2914              :     {
    2915              :         ret = B38400;
    2916            0 :         break;
    2917              :     }
    2918            0 :     case  57600:
    2919              :     {
    2920              :         ret = B57600;
    2921            0 :         break;
    2922              :     }
    2923              :     case  115200:
    2924              :     {
    2925              :         ret = B115200;
    2926              :         break;
    2927              :     }
    2928              : #      ifdef __linux__
    2929            0 :     case 230400:
    2930              :     {
    2931              :         ret = B230400;
    2932            0 :         break;
    2933              :     }
    2934            0 :     case 460800:
    2935              :     {
    2936              :         ret = B460800;
    2937            0 :         break;
    2938              :     }
    2939            0 :     case  500000:
    2940              :     {
    2941              :         ret = B500000;
    2942            0 :         break;
    2943              :     }
    2944            0 :     case  576000:
    2945              :     {
    2946              :         ret = B576000;
    2947            0 :         break;
    2948              :     }
    2949            0 :     case  921600:
    2950              :     {
    2951              :         ret = B921600;
    2952            0 :         break;
    2953              :     }
    2954            0 :     case  1000000:
    2955              :     {
    2956              :         ret = B1000000;
    2957            0 :         break;
    2958              :     }
    2959            0 :     case  1152000:
    2960              :     {
    2961              :         ret = B1152000;
    2962            0 :         break;
    2963              :     }
    2964            0 :     case  1500000:
    2965              :     {
    2966              :         ret = B1500000;
    2967            0 :         break;
    2968              :     }
    2969            0 :     case  2000000:
    2970              :     {
    2971              :         ret = B2000000;
    2972            0 :         break;
    2973              :     }
    2974              : #ifdef B2500000
    2975            0 :     case  2500000:
    2976              :     {
    2977              :         ret = B2500000;
    2978            0 :         break;
    2979              :     }
    2980              : #endif
    2981              : #ifdef B3000000
    2982            0 :     case  3000000:
    2983              :     {
    2984              :         ret = B3000000;
    2985            0 :         break;
    2986              :     }
    2987              : #endif
    2988              : #ifdef B3500000
    2989            0 :     case  3500000:
    2990              :     {
    2991              :         ret = B3500000;
    2992            0 :         break;
    2993              :     }
    2994              : #endif
    2995              : #ifdef B4000000
    2996            0 :     case  4000000:
    2997              :     {
    2998              :         ret = B4000000;
    2999            0 :         break;
    3000              :     }
    3001              : #endif
    3002              : #      endif /* __linux__ */
    3003              :     default:
    3004              :     {
    3005              :         ret = B115200;
    3006              :         break;
    3007              :     }
    3008              :     }
    3009              : 
    3010            0 :     return ret;
    3011              : #   else
    3012              :     return 0;
    3013              : #   endif
    3014              : }
    3015              : 
    3016              : #endif
    3017              : 
    3018           22 : void dlt_get_version(char *buf, size_t size)
    3019              : {
    3020           22 :     if ((buf == NULL) && (size > 0)) {
    3021            0 :         dlt_log(LOG_WARNING, "Wrong parameter: Null pointer\n");
    3022            0 :         return;
    3023              :     }
    3024              : 
    3025              : /* Clang does not like these macros, because they are not reproducable */
    3026              : #pragma GCC diagnostic push
    3027              : #pragma GCC diagnostic ignored "-Wdate-time"
    3028              :     snprintf(buf,
    3029              :              size,
    3030              :              "DLT Package Version: %s %s, Package Revision: %s, build on %s %s\n%s %s %s %s\n",
    3031              :              _DLT_PACKAGE_VERSION,
    3032              :              _DLT_PACKAGE_VERSION_STATE,
    3033              :              _DLT_PACKAGE_REVISION,
    3034              :              __DATE__,
    3035              :              __TIME__,
    3036              :              _DLT_SYSTEMD_ENABLE,
    3037              :              _DLT_SYSTEMD_WATCHDOG_ENABLE,
    3038              :              _DLT_TEST_ENABLE,
    3039              :              _DLT_SHM_ENABLE);
    3040              : #pragma GCC diagnostic pop
    3041              : }
    3042              : 
    3043            9 : void dlt_get_major_version(char *buf, size_t size)
    3044              : {
    3045            9 :     if ((buf == NULL) && (size > 0)) {
    3046            0 :         dlt_log(LOG_WARNING, "Wrong parameter: Null pointer\n");
    3047            0 :         return;
    3048              :     }
    3049              : 
    3050              :     snprintf(buf, size, "%s", _DLT_PACKAGE_MAJOR_VERSION);
    3051              : }
    3052              : 
    3053            9 : void dlt_get_minor_version(char *buf, size_t size)
    3054              : {
    3055            9 :     if ((buf == NULL) && (size > 0)) {
    3056            0 :         dlt_log(LOG_WARNING, "Wrong parameter: Null pointer\n");
    3057            0 :         return;
    3058              :     }
    3059              : 
    3060              :     snprintf(buf, size, "%s", _DLT_PACKAGE_MINOR_VERSION);
    3061              : }
    3062              : 
    3063              : 
    3064         6301 : uint32_t dlt_uptime(void)
    3065              : {
    3066              : 
    3067              : #if defined (__WIN32__) || defined(_MSC_VER)
    3068              : 
    3069              :     return (uint32_t)(GetTickCount() * 10); /* GetTickCount() return DWORD */
    3070              : 
    3071              : #else
    3072              :     struct timespec ts;
    3073              : 
    3074         6301 :     if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0)
    3075         6301 :         return (uint32_t)ts.tv_sec * 10000 + (uint32_t)ts.tv_nsec / 100000; /* in 0.1 ms = 100 us */
    3076              :     else
    3077              :         return 0;
    3078              : 
    3079              : #endif
    3080              : 
    3081              : }
    3082              : 
    3083          328 : DltReturnValue dlt_message_print_header(DltMessage *message, char *text, uint32_t size, int verbose)
    3084              : {
    3085          328 :     if ((message == NULL) || (text == NULL))
    3086              :         return DLT_RETURN_WRONG_PARAMETER;
    3087              : 
    3088          316 :     if (dlt_message_header(message, text, size, verbose) < DLT_RETURN_OK)
    3089              :         return DLT_RETURN_ERROR;
    3090          316 :     dlt_user_printf("%s\n", text);
    3091              : 
    3092          316 :     return DLT_RETURN_OK;
    3093              : }
    3094              : 
    3095          328 : DltReturnValue dlt_message_print_hex(DltMessage *message, char *text, uint32_t size, int verbose)
    3096              : {
    3097          328 :     if ((message == NULL) || (text == NULL))
    3098              :         return DLT_RETURN_WRONG_PARAMETER;
    3099              : 
    3100          316 :     if (dlt_message_header(message, text, size, verbose) < DLT_RETURN_OK)
    3101              :         return DLT_RETURN_ERROR;
    3102          316 :     dlt_user_printf("%s ", text);
    3103              : 
    3104          316 :     if (dlt_message_payload(message, text, size, DLT_OUTPUT_HEX, verbose) < DLT_RETURN_OK)
    3105              :         return DLT_RETURN_ERROR;
    3106          316 :     dlt_user_printf("[%s]\n", text);
    3107              : 
    3108          316 :     return DLT_RETURN_OK;
    3109              : }
    3110              : 
    3111          328 : DltReturnValue dlt_message_print_ascii(DltMessage *message, char *text, uint32_t size, int verbose)
    3112              : {
    3113          328 :     if ((message == NULL) || (text == NULL))
    3114              :         return DLT_RETURN_WRONG_PARAMETER;
    3115              : 
    3116          316 :     if (dlt_message_header(message, text, size, verbose) < DLT_RETURN_OK)
    3117              :         return DLT_RETURN_ERROR;
    3118          316 :     dlt_user_printf("%s ", text);
    3119              : 
    3120          316 :     if (dlt_message_payload(message, text, size, DLT_OUTPUT_ASCII, verbose) < DLT_RETURN_OK)
    3121              :         return DLT_RETURN_ERROR;
    3122          316 :     dlt_user_printf("[%s]\n", text);
    3123              : 
    3124          316 :     return DLT_RETURN_OK;
    3125              : }
    3126              : 
    3127          328 : DltReturnValue dlt_message_print_mixed_plain(DltMessage *message, char *text, uint32_t size, int verbose)
    3128              : {
    3129          328 :     if ((message == NULL) || (text == NULL))
    3130              :         return DLT_RETURN_WRONG_PARAMETER;
    3131              : 
    3132          316 :     if (dlt_message_header(message, text, size, verbose) < DLT_RETURN_OK)
    3133              :         return DLT_RETURN_ERROR;
    3134          316 :     dlt_user_printf("%s \n", text);
    3135              : 
    3136          316 :     if (dlt_message_payload(message, text, size, DLT_OUTPUT_MIXED_FOR_PLAIN, verbose) < DLT_RETURN_OK)
    3137              :         return DLT_RETURN_ERROR;
    3138          316 :     dlt_user_printf("[%s]\n", text);
    3139              : 
    3140          316 :     return DLT_RETURN_OK;
    3141              : }
    3142              : 
    3143          328 : DltReturnValue dlt_message_print_mixed_html(DltMessage *message, char *text, uint32_t size, int verbose)
    3144              : {
    3145          328 :     if ((message == NULL) || (text == NULL))
    3146              :         return DLT_RETURN_WRONG_PARAMETER;
    3147              : 
    3148          316 :     if (dlt_message_header(message, text, size, verbose) < DLT_RETURN_OK)
    3149              :         return DLT_RETURN_ERROR;
    3150          316 :     dlt_user_printf("%s \n", text);
    3151              : 
    3152          316 :     if (dlt_message_payload(message, text, size, DLT_OUTPUT_MIXED_FOR_HTML, verbose) < DLT_RETURN_OK)
    3153              :         return DLT_RETURN_ERROR;
    3154              : 
    3155          316 :     dlt_user_printf("[%s]\n", text);
    3156              : 
    3157          316 :     return DLT_RETURN_OK;
    3158              : }
    3159              : 
    3160         2771 : DltReturnValue dlt_message_argument_print(DltMessage *msg,
    3161              :                                           uint32_t type_info,
    3162              :                                           uint8_t **ptr,
    3163              :                                           int32_t *datalength,
    3164              :                                           char *text,
    3165              :                                           size_t textlength,
    3166              :                                           int byteLength,
    3167              :                                           int __attribute__((unused)) verbose)
    3168              : {
    3169              :     /* check null pointers */
    3170         2771 :     if ((msg == NULL) || (ptr == NULL) || (datalength == NULL) || (text == NULL))
    3171              :         return DLT_RETURN_WRONG_PARAMETER;
    3172              : 
    3173              :     uint16_t length = 0, length2 = 0, length3 = 0;
    3174              : 
    3175              :     uint8_t value8u = 0;
    3176              :     uint16_t value16u = 0, value16u_tmp = 0;
    3177              :     uint32_t value32u = 0, value32u_tmp = 0;
    3178              :     uint64_t value64u = 0, value64u_tmp = 0;
    3179              : 
    3180              :     int8_t value8i = 0;
    3181              :     int16_t value16i = 0, value16i_tmp = 0;
    3182              :     int32_t value32i = 0, value32i_tmp = 0;
    3183              :     int64_t value64i = 0, value64i_tmp = 0;
    3184              : 
    3185         2756 :     float32_t value32f = 0, value32f_tmp = 0;
    3186         2756 :     int32_t value32f_tmp_int32i = 0, value32f_tmp_int32i_swaped = 0;
    3187         2756 :     float64_t value64f = 0, value64f_tmp = 0;
    3188         2756 :     int64_t value64f_tmp_int64i = 0, value64f_tmp_int64i_swaped = 0;
    3189              : 
    3190              :     uint32_t quantisation_tmp = 0;
    3191              : 
    3192              :     // pointer to the value string
    3193              :     char* value_text = text;
    3194              :     // pointer to the "unit" attribute string, if there is one (only for *INT and FLOAT*)
    3195              :     const uint8_t* unit_text_src = NULL;
    3196              :     // length of the "unit" attribute string, if there is one (only for *INT and FLOAT*)
    3197              :     size_t unit_text_len = 0;
    3198              : 
    3199              :     /* apparently this makes no sense but needs to be done to prevent compiler warning.
    3200              :      * This variable is only written by DLT_MSG_READ_VALUE macro in if (type_info & DLT_TYPE_INFO_FIXP)
    3201              :      * case but never read anywhere */
    3202              :     quantisation_tmp += quantisation_tmp;
    3203              : 
    3204         2756 :     if ((type_info & DLT_TYPE_INFO_STRG) &&
    3205         1159 :         (((type_info & DLT_TYPE_INFO_SCOD) == DLT_SCOD_ASCII) || ((type_info & DLT_TYPE_INFO_SCOD) == DLT_SCOD_UTF8))) {
    3206              :         /* string type or utf8-encoded string type */
    3207         1159 :         if (byteLength < 0) {
    3208         1159 :             DLT_MSG_READ_VALUE(value16u_tmp, *ptr, *datalength, uint16_t);
    3209              : 
    3210         1159 :             if ((*datalength) < 0)
    3211              :                 return DLT_RETURN_ERROR;
    3212              : 
    3213         1159 :             length = (uint16_t) DLT_ENDIAN_GET_16(msg->standardheader->htyp, value16u_tmp);
    3214              :         }
    3215              :         else {
    3216            0 :             length = (uint16_t)byteLength;
    3217              :         }
    3218              : 
    3219         1159 :         if (type_info & DLT_TYPE_INFO_VARI) {
    3220            0 :             DLT_MSG_READ_VALUE(value16u_tmp, *ptr, *datalength, uint16_t);
    3221              : 
    3222            0 :             if ((*datalength) < 0)
    3223              :                 return DLT_RETURN_ERROR;
    3224              : 
    3225            0 :             length2 = (uint16_t) DLT_ENDIAN_GET_16(msg->standardheader->htyp, value16u_tmp);
    3226              : 
    3227            0 :             if ((*datalength) < length2)
    3228              :                 return DLT_RETURN_ERROR;
    3229              : 
    3230            0 :             if (print_with_attributes) {
    3231              :                 // Print "name" attribute, if we have one with non-zero size.
    3232            0 :                 if (length2 > 1) {
    3233            0 :                     snprintf(text, textlength, "%s:", *ptr);
    3234            0 :                     value_text += length2+1-1;  // +1 for ":" and -1 for NUL
    3235            0 :                     textlength -= length2+1-1;
    3236              :                 }
    3237              :             }
    3238              : 
    3239            0 :             *ptr += length2;
    3240            0 :             *datalength -= length2;
    3241              :         }
    3242              : 
    3243         1159 :         DLT_MSG_READ_STRING(value_text, *ptr, *datalength, textlength, length);
    3244              : 
    3245         1159 :         if ((*datalength) < 0)
    3246              :             return DLT_RETURN_ERROR;
    3247              :     }
    3248         1597 :     else if (type_info & DLT_TYPE_INFO_BOOL)
    3249              :     {
    3250              :         /* Boolean type */
    3251          112 :         if (type_info & DLT_TYPE_INFO_VARI) {
    3252            0 :             DLT_MSG_READ_VALUE(value16u_tmp, *ptr, *datalength, uint16_t);
    3253              : 
    3254            0 :             if ((*datalength) < 0)
    3255              :                 return DLT_RETURN_ERROR;
    3256              : 
    3257            0 :             length2 = (uint16_t) DLT_ENDIAN_GET_16(msg->standardheader->htyp, value16u_tmp);
    3258              : 
    3259            0 :             if ((*datalength) < length2)
    3260              :                 return DLT_RETURN_ERROR;
    3261              : 
    3262            0 :             if (print_with_attributes) {
    3263              :                 // Print "name" attribute, if we have one with non-zero size.
    3264            0 :                 if (length2 > 1) {
    3265            0 :                     snprintf(text, textlength, "%s:", *ptr);
    3266            0 :                     value_text += length2+1-1;  // +1 for ":" and -1 for NUL
    3267            0 :                     textlength -= length2+1-2;
    3268              :                 }
    3269              :             }
    3270              : 
    3271            0 :             *ptr += length2;
    3272            0 :             *datalength -= length2;
    3273              :         }
    3274              : 
    3275              :         value8u = 0;
    3276          112 :         DLT_MSG_READ_VALUE(value8u, *ptr, *datalength, uint8_t); /* No endian conversion necessary */
    3277              : 
    3278          112 :         if ((*datalength) < 0)
    3279              :             return DLT_RETURN_ERROR;
    3280              : 
    3281          110 :         snprintf(value_text, textlength, "%d", value8u);
    3282              :     }
    3283         1485 :     else if ((type_info & DLT_TYPE_INFO_UINT) && (DLT_SCOD_BIN == (type_info & DLT_TYPE_INFO_SCOD)))
    3284              :     {
    3285            0 :         if (DLT_TYLE_8BIT == (type_info & DLT_TYPE_INFO_TYLE)) {
    3286            0 :             DLT_MSG_READ_VALUE(value8u, *ptr, *datalength, uint8_t); /* No endian conversion necessary */
    3287              : 
    3288            0 :             if ((*datalength) < 0)
    3289            0 :                 return DLT_RETURN_ERROR;
    3290              : 
    3291            0 :             char binary[10] = { '\0' }; /* e.g.: "0b1100 0010" */
    3292              :             int i;
    3293              : 
    3294            0 :             for (i = (1 << 7); i > 0; i >>= 1) {
    3295            0 :                 if ((1 << 3) == i)
    3296              :                     strcat(binary, " ");
    3297              : 
    3298            0 :                 strcat(binary, (i == (value8u & i)) ? "1" : "0");
    3299              :             }
    3300              : 
    3301              :             snprintf(value_text, textlength, "0b%s", binary);
    3302              :         }
    3303              : 
    3304            0 :         if (DLT_TYLE_16BIT == (type_info & DLT_TYPE_INFO_TYLE)) {
    3305            0 :             DLT_MSG_READ_VALUE(value16u, *ptr, *datalength, uint16_t);
    3306              : 
    3307            0 :             if ((*datalength) < 0)
    3308            0 :                 return DLT_RETURN_ERROR;
    3309              : 
    3310            0 :             char binary[20] = { '\0' }; /* e.g.: "0b1100 0010 0011 0110" */
    3311              :             int i;
    3312              : 
    3313            0 :             for (i = (1 << 15); i > 0; i >>= 1) {
    3314            0 :                 if (((1 << 3) == i) || ((1 << 7) == i) || ((1 << 11) == i))
    3315              :                     strcat(binary, " ");
    3316              : 
    3317            0 :                 strcat(binary, (i == (value16u & i)) ? "1" : "0");
    3318              :             }
    3319              : 
    3320              :             snprintf(value_text, textlength, "0b%s", binary);
    3321              :         }
    3322              :     }
    3323         1485 :     else if ((type_info & DLT_TYPE_INFO_UINT) && (DLT_SCOD_HEX == (type_info & DLT_TYPE_INFO_SCOD)))
    3324              :     {
    3325            0 :         if (DLT_TYLE_8BIT == (type_info & DLT_TYPE_INFO_TYLE)) {
    3326            0 :             DLT_MSG_READ_VALUE(value8u, *ptr, *datalength, uint8_t); /* No endian conversion necessary */
    3327              : 
    3328            0 :             if ((*datalength) < 0)
    3329              :                 return DLT_RETURN_ERROR;
    3330              : 
    3331            0 :             snprintf(value_text, textlength, "0x%02x", value8u);
    3332              :         }
    3333              : 
    3334            0 :         if (DLT_TYLE_16BIT == (type_info & DLT_TYPE_INFO_TYLE)) {
    3335            0 :             DLT_MSG_READ_VALUE(value16u, *ptr, *datalength, uint16_t);
    3336              : 
    3337            0 :             if ((*datalength) < 0)
    3338              :                 return DLT_RETURN_ERROR;
    3339              : 
    3340            0 :             snprintf(value_text, textlength, "0x%04x", value16u);
    3341              :         }
    3342              : 
    3343            0 :         if (DLT_TYLE_32BIT == (type_info & DLT_TYPE_INFO_TYLE)) {
    3344            0 :             DLT_MSG_READ_VALUE(value32u, *ptr, *datalength, uint32_t);
    3345              : 
    3346            0 :             if ((*datalength) < 0)
    3347              :                 return DLT_RETURN_ERROR;
    3348              : 
    3349              :             snprintf(value_text, textlength, "0x%08x", value32u);
    3350              :         }
    3351              : 
    3352            0 :         if (DLT_TYLE_64BIT == (type_info & DLT_TYPE_INFO_TYLE)) {
    3353            0 :             *ptr += 4;
    3354            0 :             DLT_MSG_READ_VALUE(value32u, *ptr, *datalength, uint32_t);
    3355              : 
    3356            0 :             if ((*datalength) < 0)
    3357              :                 return DLT_RETURN_ERROR;
    3358              : 
    3359              :             snprintf(value_text, textlength, "0x%08x", value32u);
    3360            0 :             *ptr -= 8;
    3361            0 :             DLT_MSG_READ_VALUE(value32u, *ptr, *datalength, uint32_t);
    3362              : 
    3363            0 :             if ((*datalength) < 0)
    3364              :                 return DLT_RETURN_ERROR;
    3365              : 
    3366            0 :             snprintf(value_text + strlen(value_text), textlength - strlen(value_text), "%08x", value32u);
    3367            0 :             *ptr += 4;
    3368              :         }
    3369              :     }
    3370         1485 :     else if ((type_info & DLT_TYPE_INFO_SINT) || (type_info & DLT_TYPE_INFO_UINT))
    3371              :     {
    3372              :         /* signed or unsigned argument received */
    3373         1358 :         if (type_info & DLT_TYPE_INFO_VARI) {
    3374            0 :             DLT_MSG_READ_VALUE(value16u_tmp, *ptr, *datalength, uint16_t);
    3375              : 
    3376            0 :             if ((*datalength) < 0)
    3377              :                 return DLT_RETURN_ERROR;
    3378              : 
    3379            0 :             length2 = (uint16_t) DLT_ENDIAN_GET_16(msg->standardheader->htyp, value16u_tmp);
    3380            0 :             DLT_MSG_READ_VALUE(value16u_tmp, *ptr, *datalength, uint16_t);
    3381              : 
    3382            0 :             if ((*datalength) < 0)
    3383              :                 return DLT_RETURN_ERROR;
    3384              : 
    3385            0 :             length3 = (uint16_t) DLT_ENDIAN_GET_16(msg->standardheader->htyp, value16u_tmp);
    3386              : 
    3387            0 :             if ((*datalength) < length2)
    3388              :                 return DLT_RETURN_ERROR;
    3389              : 
    3390            0 :             if (print_with_attributes) {
    3391              :                 // Print "name" attribute, if we have one with non-zero size.
    3392            0 :                 if (length2 > 1) {
    3393            0 :                     snprintf(text, textlength, "%s:", *ptr);
    3394            0 :                     value_text += length2+1-1;  // +1 for the ":", and -1 for nul
    3395            0 :                     textlength -= length2+1-1;
    3396              :                 }
    3397              :             }
    3398              : 
    3399            0 :             *ptr += length2;
    3400            0 :             *datalength -= length2;
    3401              : 
    3402            0 :             if ((*datalength) < length3)
    3403              :                 return DLT_RETURN_ERROR;
    3404              : 
    3405              :             // We want to add the "unit" attribute only after the value, so remember its pointer and length here.
    3406              :             unit_text_src = *ptr;
    3407            0 :             unit_text_len = length3;
    3408              : 
    3409            0 :             *ptr += length3;
    3410            0 :             *datalength -= length3;
    3411              :         }
    3412              : 
    3413         1358 :         if (type_info & DLT_TYPE_INFO_FIXP) {
    3414            0 :             DLT_MSG_READ_VALUE(quantisation_tmp, *ptr, *datalength, uint32_t);
    3415              : 
    3416            0 :             if ((*datalength) < 0)
    3417              :                 return DLT_RETURN_ERROR;
    3418              : 
    3419            0 :             switch (type_info & DLT_TYPE_INFO_TYLE) {
    3420            0 :             case DLT_TYLE_8BIT:
    3421              :             case DLT_TYLE_16BIT:
    3422              :             case DLT_TYLE_32BIT:
    3423              :             {
    3424            0 :                 if ((*datalength) < 4)
    3425              :                     return DLT_RETURN_ERROR;
    3426              : 
    3427            0 :                 *ptr += 4;
    3428            0 :                 *datalength -= 4;
    3429            0 :                 break;
    3430              :             }
    3431            0 :             case DLT_TYLE_64BIT:
    3432              :             {
    3433            0 :                 if ((*datalength) < 8)
    3434              :                     return DLT_RETURN_ERROR;
    3435              : 
    3436            0 :                 *ptr += 8;
    3437            0 :                 *datalength -= 8;
    3438            0 :                 break;
    3439              :             }
    3440            0 :             case DLT_TYLE_128BIT:
    3441              :             {
    3442            0 :                 if ((*datalength) < 16)
    3443              :                     return DLT_RETURN_ERROR;
    3444              : 
    3445            0 :                 *ptr += 16;
    3446            0 :                 *datalength -= 16;
    3447            0 :                 break;
    3448              :             }
    3449              :             default:
    3450              :             {
    3451              :                 return DLT_RETURN_ERROR;
    3452              :             }
    3453              :             }
    3454              :         }
    3455              : 
    3456         1358 :         switch (type_info & DLT_TYPE_INFO_TYLE) {
    3457           14 :         case DLT_TYLE_8BIT:
    3458              :         {
    3459           14 :             if (type_info & DLT_TYPE_INFO_SINT) {
    3460              :                 value8i = 0;
    3461            7 :                 DLT_MSG_READ_VALUE(value8i, *ptr, *datalength, int8_t);  /* No endian conversion necessary */
    3462              : 
    3463            7 :                 if ((*datalength) < 0)
    3464              :                     return DLT_RETURN_ERROR;
    3465              : 
    3466            7 :                 snprintf(value_text, textlength, "%d", value8i);
    3467              :             }
    3468              :             else {
    3469              :                 value8u = 0;
    3470            7 :                 DLT_MSG_READ_VALUE(value8u, *ptr, *datalength, uint8_t);  /* No endian conversion necessary */
    3471              : 
    3472            7 :                 if ((*datalength) < 0)
    3473              :                     return DLT_RETURN_ERROR;
    3474              : 
    3475            7 :                 snprintf(value_text, textlength, "%d", value8u);
    3476              :             }
    3477              : 
    3478              :             break;
    3479              :         }
    3480           21 :         case DLT_TYLE_16BIT:
    3481              :         {
    3482           21 :             if (type_info & DLT_TYPE_INFO_SINT) {
    3483              :                 value16i = 0;
    3484              :                 value16i_tmp = 0;
    3485            7 :                 DLT_MSG_READ_VALUE(value16i_tmp, *ptr, *datalength, int16_t);
    3486              : 
    3487            7 :                 if ((*datalength) < 0)
    3488              :                     return DLT_RETURN_ERROR;
    3489              : 
    3490            7 :                 value16i = (int16_t) DLT_ENDIAN_GET_16(msg->standardheader->htyp, value16i_tmp);
    3491            7 :                 snprintf(value_text, textlength, "%hd", value16i);
    3492              :             }
    3493              :             else {
    3494              :                 value16u = 0;
    3495              :                 value16u_tmp = 0;
    3496           14 :                 DLT_MSG_READ_VALUE(value16u_tmp, *ptr, *datalength, uint16_t);
    3497              : 
    3498           14 :                 if ((*datalength) < 0)
    3499              :                     return DLT_RETURN_ERROR;
    3500              : 
    3501           14 :                 value16u = (uint16_t) DLT_ENDIAN_GET_16(msg->standardheader->htyp, value16u_tmp);
    3502           14 :                 snprintf(value_text, textlength, "%hu", value16u);
    3503              :             }
    3504              : 
    3505              :             break;
    3506              :         }
    3507         1309 :         case DLT_TYLE_32BIT:
    3508              :         {
    3509         1309 :             if (type_info & DLT_TYPE_INFO_SINT) {
    3510              :                 value32i = 0;
    3511              :                 value32i_tmp = 0;
    3512          287 :                 DLT_MSG_READ_VALUE(value32i_tmp, *ptr, *datalength, int32_t);
    3513              : 
    3514          287 :                 if ((*datalength) < 0)
    3515              :                     return DLT_RETURN_ERROR;
    3516              : 
    3517          287 :                 value32i = (int32_t) DLT_ENDIAN_GET_32(msg->standardheader->htyp, (uint32_t)value32i_tmp);
    3518              :                 snprintf(value_text, textlength, "%d", value32i);
    3519              :             }
    3520              :             else {
    3521              :                 value32u = 0;
    3522              :                 value32u_tmp = 0;
    3523         1022 :                 DLT_MSG_READ_VALUE(value32u_tmp, *ptr, *datalength, uint32_t);
    3524              : 
    3525         1022 :                 if ((*datalength) < 0)
    3526              :                     return DLT_RETURN_ERROR;
    3527              : 
    3528         1022 :                 value32u = DLT_ENDIAN_GET_32(msg->standardheader->htyp, value32u_tmp);
    3529              :                 snprintf(value_text, textlength, "%u", value32u);
    3530              :             }
    3531              : 
    3532              :             break;
    3533              :         }
    3534           14 :         case DLT_TYLE_64BIT:
    3535              :         {
    3536           14 :             if (type_info & DLT_TYPE_INFO_SINT) {
    3537              :                 value64i = 0;
    3538              :                 value64i_tmp = 0;
    3539            7 :                 DLT_MSG_READ_VALUE(value64i_tmp, *ptr, *datalength, int64_t);
    3540              : 
    3541            7 :                 if ((*datalength) < 0)
    3542              :                     return DLT_RETURN_ERROR;
    3543              : 
    3544            7 :                 value64i = (int64_t) DLT_ENDIAN_GET_64(msg->standardheader->htyp, (uint64_t)value64i_tmp);
    3545              :     #if defined (__WIN32__) && !defined(_MSC_VER)
    3546              :                 snprintf(value_text, textlength, "%I64d", value64i);
    3547              :     #else
    3548              :                 snprintf(value_text, textlength, "%" PRId64, value64i);
    3549              :     #endif
    3550              :             }
    3551              :             else {
    3552              :                 value64u = 0;
    3553              :                 value64u_tmp = 0;
    3554            7 :                 DLT_MSG_READ_VALUE(value64u_tmp, *ptr, *datalength, uint64_t);
    3555              : 
    3556            7 :                 if ((*datalength) < 0)
    3557              :                     return DLT_RETURN_ERROR;
    3558              : 
    3559            7 :                 value64u = DLT_ENDIAN_GET_64(msg->standardheader->htyp, value64u_tmp);
    3560              :     #if defined (__WIN32__) && !defined(_MSC_VER)
    3561              :                 snprintf(value_text, textlength, "%I64u", value64u);
    3562              :     #else
    3563              :                 snprintf(value_text, textlength, "%" PRIu64, value64u);
    3564              :     #endif
    3565              :             }
    3566              : 
    3567              :             break;
    3568              :         }
    3569            0 :         case DLT_TYLE_128BIT:
    3570              :         {
    3571            0 :             if (*datalength >= 16)
    3572            0 :                 dlt_print_hex_string(value_text, (int) textlength, *ptr, 16);
    3573              : 
    3574            0 :             if ((*datalength) < 16)
    3575              :                 return DLT_RETURN_ERROR;
    3576              : 
    3577            0 :             *ptr += 16;
    3578            0 :             *datalength -= 16;
    3579            0 :             break;
    3580              :         }
    3581              :         default:
    3582              :         {
    3583              :             return DLT_RETURN_ERROR;
    3584              :         }
    3585              :         }
    3586              :     }
    3587          127 :     else if (type_info & DLT_TYPE_INFO_FLOA)
    3588              :     {
    3589              :         /* float data argument */
    3590           14 :         if (type_info & DLT_TYPE_INFO_VARI) {
    3591            0 :             DLT_MSG_READ_VALUE(value16u_tmp, *ptr, *datalength, uint16_t);
    3592              : 
    3593            0 :             if ((*datalength) < 0)
    3594              :                 return DLT_RETURN_ERROR;
    3595              : 
    3596            0 :             length2 = DLT_ENDIAN_GET_16(msg->standardheader->htyp, value16u_tmp);
    3597            0 :             DLT_MSG_READ_VALUE(value16u_tmp, *ptr, *datalength, uint16_t);
    3598              : 
    3599            0 :             if ((*datalength) < 0)
    3600              :                 return DLT_RETURN_ERROR;
    3601              : 
    3602            0 :             length3 = DLT_ENDIAN_GET_16(msg->standardheader->htyp, value16u_tmp);
    3603              : 
    3604            0 :             if ((*datalength) < length2)
    3605              :                 return DLT_RETURN_ERROR;
    3606              : 
    3607            0 :             if (print_with_attributes) {
    3608              :                 // Print "name" attribute, if we have one with non-zero size.
    3609            0 :                 if (length2 > 1) {
    3610            0 :                     snprintf(text, textlength, "%s:", *ptr);
    3611            0 :                     value_text += length2+1-1;  // +1 for ":" and -1 for NUL
    3612            0 :                     textlength -= length2+1-1;
    3613              :                 }
    3614              :             }
    3615              : 
    3616            0 :             *ptr += length2;
    3617            0 :             *datalength -= length2;
    3618              : 
    3619            0 :             if ((*datalength) < length3)
    3620              :                 return DLT_RETURN_ERROR;
    3621              : 
    3622              :             // We want to add the "unit" attribute only after the value, so remember its pointer and length here.
    3623              :             unit_text_src = *ptr;
    3624            0 :             unit_text_len = length3;
    3625              : 
    3626            0 :             *ptr += length3;
    3627            0 :             *datalength -= length3;
    3628              :         }
    3629              : 
    3630           14 :         switch (type_info & DLT_TYPE_INFO_TYLE) {
    3631            0 :         case DLT_TYLE_8BIT:
    3632              :         {
    3633            0 :             if (*datalength >= 1)
    3634            0 :                 dlt_print_hex_string(value_text, (int) textlength, *ptr, 1);
    3635              : 
    3636            0 :             if ((*datalength) < 1)
    3637              :                 return DLT_RETURN_ERROR;
    3638              : 
    3639            0 :             *ptr += 1;
    3640            0 :             *datalength -= 1;
    3641            0 :             break;
    3642              :         }
    3643            0 :         case DLT_TYLE_16BIT:
    3644              :         {
    3645            0 :             if (*datalength >= 2)
    3646            0 :                 dlt_print_hex_string(value_text, (int) textlength, *ptr, 2);
    3647              : 
    3648            0 :             if ((*datalength) < 2)
    3649              :                 return DLT_RETURN_ERROR;
    3650              : 
    3651            0 :             *ptr += 2;
    3652            0 :             *datalength -= 2;
    3653            0 :             break;
    3654              :         }
    3655              :         case DLT_TYLE_32BIT:
    3656              :         {
    3657              :             if (sizeof(float32_t) == 4) {
    3658              :                 value32f = 0;
    3659              :                 value32f_tmp = 0;
    3660              :                 value32f_tmp_int32i = 0;
    3661              :                 value32f_tmp_int32i_swaped = 0;
    3662            7 :                 DLT_MSG_READ_VALUE(value32f_tmp, *ptr, *datalength, float32_t);
    3663              : 
    3664            7 :                 if ((*datalength) < 0)
    3665              :                     return DLT_RETURN_ERROR;
    3666              : 
    3667              :                 memcpy(&value32f_tmp_int32i, &value32f_tmp, sizeof(float32_t));
    3668              :                 value32f_tmp_int32i_swaped =
    3669            7 :                     (int32_t) DLT_ENDIAN_GET_32(msg->standardheader->htyp, (uint32_t)value32f_tmp_int32i);
    3670              :                 memcpy(&value32f, &value32f_tmp_int32i_swaped, sizeof(float32_t));
    3671            7 :                 snprintf(value_text, textlength, "%g", value32f);
    3672              :             }
    3673              :             else {
    3674              :                 dlt_log(LOG_ERR, "Invalid size of float32_t\n");
    3675              :                 return DLT_RETURN_ERROR;
    3676              :             }
    3677              : 
    3678              :             break;
    3679              :         }
    3680              :         case DLT_TYLE_64BIT:
    3681              :         {
    3682              :             if (sizeof(float64_t) == 8) {
    3683              :                 value64f = 0;
    3684              :                 value64f_tmp = 0;
    3685              :                 value64f_tmp_int64i = 0;
    3686              :                 value64f_tmp_int64i_swaped = 0;
    3687            7 :                 DLT_MSG_READ_VALUE(value64f_tmp, *ptr, *datalength, float64_t);
    3688              : 
    3689            7 :                 if ((*datalength) < 0)
    3690              :                     return DLT_RETURN_ERROR;
    3691              : 
    3692              :                 memcpy(&value64f_tmp_int64i, &value64f_tmp, sizeof(float64_t));
    3693              :                 value64f_tmp_int64i_swaped =
    3694            7 :                     (int64_t) DLT_ENDIAN_GET_64(msg->standardheader->htyp, (uint64_t)value64f_tmp_int64i);
    3695              :                 memcpy(&value64f, &value64f_tmp_int64i_swaped, sizeof(float64_t));
    3696              : #ifdef __arm__
    3697              :                 snprintf(value_text, textlength, "ILLEGAL");
    3698              : #else
    3699              :                 snprintf(value_text, textlength, "%g", value64f);
    3700              : #endif
    3701              :             }
    3702              :             else {
    3703              :                 dlt_log(LOG_ERR, "Invalid size of float64_t\n");
    3704              :                 return DLT_RETURN_ERROR;
    3705              :             }
    3706              : 
    3707              :             break;
    3708              :         }
    3709            0 :         case DLT_TYLE_128BIT:
    3710              :         {
    3711            0 :             if (*datalength >= 16)
    3712            0 :                 dlt_print_hex_string(value_text, textlength, *ptr, 16);
    3713              : 
    3714            0 :             if ((*datalength) < 16)
    3715              :                 return DLT_RETURN_ERROR;
    3716              : 
    3717            0 :             *ptr += 16;
    3718            0 :             *datalength -= 16;
    3719            0 :             break;
    3720              :         }
    3721              :         default:
    3722              :         {
    3723              :             return DLT_RETURN_ERROR;
    3724              :         }
    3725              :         }
    3726              :     }
    3727          113 :     else if (type_info & DLT_TYPE_INFO_RAWD)
    3728              :     {
    3729              :         /* raw data argument */
    3730          112 :         DLT_MSG_READ_VALUE(value16u_tmp, *ptr, *datalength, uint16_t);
    3731              : 
    3732          112 :         if ((*datalength) < 0)
    3733              :             return DLT_RETURN_ERROR;
    3734              : 
    3735          110 :         length = DLT_ENDIAN_GET_16(msg->standardheader->htyp, value16u_tmp);
    3736              : 
    3737          110 :         if (type_info & DLT_TYPE_INFO_VARI) {
    3738            0 :             DLT_MSG_READ_VALUE(value16u_tmp, *ptr, *datalength, uint16_t);
    3739              : 
    3740            0 :             if ((*datalength) < 0)
    3741              :                 return DLT_RETURN_ERROR;
    3742              : 
    3743            0 :             length2 = DLT_ENDIAN_GET_16(msg->standardheader->htyp, value16u_tmp);
    3744              : 
    3745            0 :             if ((*datalength) < length2)
    3746              :                 return DLT_RETURN_ERROR;
    3747              : 
    3748            0 :             if (print_with_attributes) {
    3749              :                 // Print "name" attribute, if we have one with non-zero size.
    3750            0 :                 if (length2 > 1) {
    3751            0 :                     snprintf(text, textlength, "%s:", *ptr);
    3752            0 :                     value_text += length2+1-1;  // +1 for ":" and -1 for NUL
    3753            0 :                     textlength -= length2+1-1;
    3754              :                 }
    3755              :             }
    3756              : 
    3757            0 :             *ptr += length2;
    3758            0 :             *datalength -= length2;
    3759              :         }
    3760              : 
    3761          110 :         if ((*datalength) < length)
    3762              :             return DLT_RETURN_ERROR;
    3763              : 
    3764            9 :         if (dlt_print_hex_string_delim(value_text, (int) textlength, *ptr, length, '\'') < DLT_RETURN_OK)
    3765              :             return DLT_RETURN_ERROR;
    3766            9 :         *ptr += length;
    3767            9 :         *datalength -= length;
    3768              :     }
    3769            1 :     else if (type_info & DLT_TYPE_INFO_TRAI)
    3770              :     {
    3771              :         /* trace info argument */
    3772            0 :         DLT_MSG_READ_VALUE(value16u_tmp, *ptr, *datalength, uint16_t);
    3773              : 
    3774            0 :         if ((*datalength) < 0)
    3775              :             return DLT_RETURN_ERROR;
    3776              : 
    3777            0 :         length = DLT_ENDIAN_GET_16(msg->standardheader->htyp, value16u_tmp);
    3778              : 
    3779            0 :         DLT_MSG_READ_STRING(value_text, *ptr, *datalength, textlength, length);
    3780              : 
    3781            0 :         if ((*datalength) < 0)
    3782              :             return DLT_RETURN_ERROR;
    3783              :     }
    3784              :     else {
    3785              :         return DLT_RETURN_ERROR;
    3786              :     }
    3787              : 
    3788         2650 :     if (*datalength < 0) {
    3789            0 :         dlt_log(LOG_ERR, "Payload of DLT message corrupted\n");
    3790            0 :         return DLT_RETURN_ERROR;
    3791              :     }
    3792              : 
    3793              :     // Now write "unit" attribute, but only if it has more than only a nul-termination char.
    3794         2650 :     if (print_with_attributes) {
    3795            0 :         if (unit_text_len > 1) {
    3796              :             // 'value_text' still points to the +start+ of the value text
    3797            0 :             size_t currLen = strlen(value_text);
    3798              : 
    3799            0 :             char* unitText = value_text + currLen;
    3800            0 :             textlength -= currLen;
    3801              :             snprintf(unitText, textlength, ":%s", unit_text_src);
    3802              :         }
    3803              :     }
    3804              : 
    3805              :     return DLT_RETURN_OK;
    3806              : }
    3807              : 
    3808        21213 : void dlt_check_envvar()
    3809              : {
    3810        21213 :     char *env_log_filename = getenv("DLT_LOG_FILENAME");
    3811              : 
    3812        21213 :     if (env_log_filename != NULL)
    3813            0 :         dlt_log_set_filename(env_log_filename);
    3814              : 
    3815        21213 :     char *env_log_level_str = getenv("DLT_LOG_LEVEL");
    3816              : 
    3817        21213 :     if (env_log_level_str != NULL) {
    3818            0 :         int level = 0;
    3819              : 
    3820            0 :         if (sscanf(env_log_level_str, "%d", &level) == 1)
    3821            0 :             dlt_log_set_level(level);
    3822              :     }
    3823              : 
    3824        21213 :     char *env_log_mode = getenv("DLT_LOG_MODE");
    3825              : 
    3826        21213 :     if (env_log_mode != NULL) {
    3827            0 :         int mode = 0;
    3828              : 
    3829            0 :         if (sscanf(env_log_mode, "%d", &mode) == 1)
    3830            0 :             dlt_log_init(mode);
    3831              :     }
    3832              : 
    3833              : #if defined DLT_DAEMON_USE_FIFO_IPC || defined DLT_LIB_USE_FIFO_IPC
    3834        21213 :     char *env_pipe_dir = getenv("DLT_PIPE_DIR");
    3835              : 
    3836        21213 :     if (env_pipe_dir != NULL)
    3837            0 :         dlt_log_set_fifo_basedir(env_pipe_dir);
    3838              :     else
    3839        21213 :         dlt_log_set_fifo_basedir(DLT_USER_IPC_PATH);
    3840              : 
    3841              : #endif
    3842              : 
    3843              : #ifdef DLT_SHM_ENABLE
    3844              :     char *env_shm_name = getenv("DLT_SHM_NAME");
    3845              : 
    3846              :     if (env_shm_name != NULL)
    3847              :         dlt_log_set_shm_name(env_shm_name);
    3848              : 
    3849              : #endif
    3850        21213 : }
    3851              : 
    3852            2 : int dlt_set_loginfo_parse_service_id(char *resp_text,
    3853              :                                      uint32_t *service_id,
    3854              :                                      uint8_t *service_opt)
    3855              : {
    3856              :     int ret = -1;
    3857              :     char get_log_info_tag[GET_LOG_INFO_LENGTH];
    3858              :     char service_opt_str[SERVICE_OPT_LENGTH];
    3859              : 
    3860            2 :     if ((resp_text == NULL) || (service_id == NULL) || (service_opt == NULL))
    3861              :         return DLT_RETURN_ERROR;
    3862              : 
    3863              :     /* ascii type, syntax is 'get_log_info, ..' */
    3864              :     /* check target id */
    3865              :     strncpy(get_log_info_tag, "get_log_info", strlen("get_log_info") + 1);
    3866            2 :     ret = memcmp((void *)resp_text, (void *)get_log_info_tag, sizeof(get_log_info_tag) - 1);
    3867              : 
    3868            2 :     if (ret == 0) {
    3869            2 :         *service_id = DLT_SERVICE_ID_GET_LOG_INFO;
    3870              :         /* reading the response mode from the resp_text. eg. option 7*/
    3871            2 :         service_opt_str[0] = *(resp_text + GET_LOG_INFO_LENGTH + 1);
    3872            2 :         service_opt_str[1] = *(resp_text + GET_LOG_INFO_LENGTH + 2);
    3873            2 :         service_opt_str[2] = 0;
    3874            2 :         *service_opt = (uint8_t) atoi(service_opt_str);
    3875              :     }
    3876              : 
    3877              :     return ret;
    3878              : }
    3879              : 
    3880           14 : int16_t dlt_getloginfo_conv_ascii_to_uint16_t(char *rp, int *rp_count)
    3881              : {
    3882           14 :     char num_work[5] = { 0 };
    3883              :     char *endptr;
    3884              : 
    3885           14 :     if ((rp == NULL) || (rp_count == NULL))
    3886              :         return -1;
    3887              : 
    3888              :     /* ------------------------------------------------------
    3889              :      *  from: [89 13 ] -> to: ['+0x'1389\0] -> to num
    3890              :      *  ------------------------------------------------------ */
    3891           14 :     num_work[0] = *(rp + *rp_count + 3);
    3892           14 :     num_work[1] = *(rp + *rp_count + 4);
    3893           14 :     num_work[2] = *(rp + *rp_count + 0);
    3894           14 :     num_work[3] = *(rp + *rp_count + 1);
    3895              :     num_work[4] = 0;
    3896           14 :     *rp_count += 6;
    3897              : 
    3898           14 :     return (uint16_t)strtol(num_work, &endptr, 16);
    3899              : }
    3900              : 
    3901           12 : int16_t dlt_getloginfo_conv_ascii_to_int16_t(char *rp, int *rp_count)
    3902              : {
    3903           12 :     char num_work[3] = { 0 };
    3904              :     char *endptr;
    3905              : 
    3906           12 :     if ((rp == NULL) || (rp_count == NULL))
    3907              :         return -1;
    3908              : 
    3909              :     /* ------------------------------------------------------
    3910              :      *  from: [89 ] -> to: ['0x'89\0] -> to num
    3911              :      *  ------------------------------------------------------ */
    3912           12 :     num_work[0] = *(rp + *rp_count + 0);
    3913           12 :     num_work[1] = *(rp + *rp_count + 1);
    3914              :     num_work[2] = 0;
    3915           12 :     *rp_count += 3;
    3916              : 
    3917           12 :     return (signed char)strtol(num_work, &endptr, 16);
    3918              : }
    3919              : 
    3920           11 : void dlt_getloginfo_conv_ascii_to_string(char *rp, int *rp_count, char *wp, int len)
    3921              : {
    3922           11 :     if ((rp == NULL ) || (rp_count == NULL ) || (wp == NULL ))
    3923              :         return;
    3924              :     /* ------------------------------------------------------
    3925              :      *  from: [72 65 6d 6f ] -> to: [0x72,0x65,0x6d,0x6f,0x00]
    3926              :      *  ------------------------------------------------------ */
    3927              : 
    3928           11 :     int count = dlt_getloginfo_conv_ascii_to_id(rp, rp_count, wp, len);
    3929           11 :     *(wp + count) = '\0';
    3930              : 
    3931           11 :     return;
    3932              : }
    3933              : 
    3934           20 : int dlt_getloginfo_conv_ascii_to_id(char *rp, int *rp_count, char *wp, int len)
    3935              : {
    3936           20 :     char number16[3] = { 0 };
    3937              :     char *endptr;
    3938              :     int count;
    3939              : 
    3940           20 :     if ((rp == NULL) || (rp_count == NULL) || (wp == NULL))
    3941              :         return 0;
    3942              : 
    3943              :     /* ------------------------------------------------------
    3944              :      *  from: [72 65 6d 6f ] -> to: [0x72,0x65,0x6d,0x6f]
    3945              :      *  ------------------------------------------------------ */
    3946          289 :     for (count = 0; count < len; count++) {
    3947          269 :         number16[0] = *(rp + *rp_count + 0);
    3948          269 :         number16[1] = *(rp + *rp_count + 1);
    3949          269 :         *(wp + count) = (char) strtol(number16, &endptr, 16);
    3950          269 :         *rp_count += 3;
    3951              :     }
    3952              : 
    3953              :     return count;
    3954              : }
    3955              : 
    3956            0 : void dlt_hex_ascii_to_binary(const char *ptr, uint8_t *binary, int *size)
    3957              : {
    3958            0 :     char ch = *ptr;
    3959              :     int pos = 0;
    3960            0 :     binary[pos] = 0;
    3961              :     int first = 1;
    3962              :     int found;
    3963              : 
    3964              :     for (;;) {
    3965            0 :         if (ch == 0) {
    3966            0 :             *size = pos;
    3967            0 :             return;
    3968              :         }
    3969              : 
    3970              :         found = 0;
    3971              : 
    3972            0 :         if ((ch >= '0') && (ch <= '9')) {
    3973            0 :             binary[pos] = (uint8_t) ((binary[pos] << 4) + (ch - '0'));
    3974              :             found = 1;
    3975              :         }
    3976            0 :         else if ((ch >= 'A') && (ch <= 'F'))
    3977              :         {
    3978            0 :             binary[pos] = (uint8_t) ((binary[pos] << 4) + (ch - 'A' + 10));
    3979              :             found = 1;
    3980              :         }
    3981            0 :         else if ((ch >= 'a') && (ch <= 'f'))
    3982              :         {
    3983            0 :             binary[pos] = (uint8_t) ((binary[pos] << 4) + (ch - 'a' + 10));
    3984              :             found = 1;
    3985              :         }
    3986              : 
    3987              :         if (found) {
    3988            0 :             if (first) {
    3989              :                 first = 0;
    3990              :             }
    3991              :             else {
    3992              :                 first = 1;
    3993            0 :                 pos++;
    3994              : 
    3995            0 :                 if (pos >= *size)
    3996              :                     return;
    3997              : 
    3998            0 :                 binary[pos] = 0;
    3999              :             }
    4000              :         }
    4001              : 
    4002            0 :         ch = *(++ptr);
    4003              :     }
    4004              : }
    4005              : 
    4006            3 : DltReturnValue dlt_file_quick_parsing(DltFile *file, const char *filename,
    4007              :                                       int type, int verbose)
    4008              : {
    4009            3 :     PRINT_FUNCTION_VERBOSE(verbose);
    4010              :     int ret = DLT_RETURN_OK;
    4011            3 :     char text[DLT_CONVERT_TEXTBUFSIZE] = { 0 };
    4012              : 
    4013            3 :     if ((file == NULL) || (filename == NULL))
    4014              :         return DLT_RETURN_WRONG_PARAMETER;
    4015              : 
    4016            1 :     FILE *output = fopen(filename, "w+");
    4017              : 
    4018            1 :     if (output == NULL) {
    4019            0 :         dlt_vlog(LOG_ERR, "Cannot open output file %s for parsing\n", filename);
    4020            0 :         return DLT_RETURN_ERROR;
    4021              :     }
    4022              : 
    4023          106 :     while (ret >= DLT_RETURN_OK && file->file_position < file->file_length) {
    4024              :         /* get file position at start of DLT message */
    4025          105 :         if (verbose)
    4026            0 :             dlt_vlog(LOG_DEBUG, "Position in file: %" PRIu64 "\n", file->file_position);
    4027              : 
    4028              :         /* read all header and payload */
    4029          105 :         ret = dlt_file_read_header(file, verbose);
    4030              : 
    4031          105 :         if (ret < DLT_RETURN_OK)
    4032              :             break;
    4033              : 
    4034          105 :         ret = dlt_file_read_header_extended(file, verbose);
    4035              : 
    4036          105 :         if (ret < DLT_RETURN_OK)
    4037              :             break;
    4038              : 
    4039          105 :         ret = dlt_file_read_data(file, verbose);
    4040              : 
    4041          105 :         if (ret < DLT_RETURN_OK)
    4042              :             break;
    4043              : 
    4044          105 :         if (file->filter) {
    4045              :             /* check the filters if message is used */
    4046            0 :             ret = dlt_message_filter_check(&(file->msg), file->filter, verbose);
    4047              : 
    4048            0 :             if (ret != DLT_RETURN_TRUE)
    4049            0 :                 continue;
    4050              :         }
    4051              : 
    4052          105 :         ret = dlt_message_header(&(file->msg), text,
    4053              :                                  DLT_CONVERT_TEXTBUFSIZE, verbose);
    4054              : 
    4055          105 :         if (ret < DLT_RETURN_OK)
    4056              :             break;
    4057              : 
    4058              :         fprintf(output, "%s", text);
    4059              : 
    4060          105 :         ret = dlt_message_payload(&(file->msg), text,
    4061              :                                   DLT_CONVERT_TEXTBUFSIZE, type, verbose);
    4062              : 
    4063          105 :         if (ret < DLT_RETURN_OK)
    4064              :             break;
    4065              : 
    4066              :         fprintf(output, "[%s]\n", text);
    4067              : 
    4068              :         /* store index pointer to message position in DLT file */
    4069          105 :         file->counter++;
    4070          105 :         file->position = file->counter_total - 1;
    4071              :         /* increase total message counter */
    4072          105 :         file->counter_total++;
    4073              :         /* store position to next message */
    4074          105 :         file->file_position = ftell(file->handle);
    4075              :     } /* while() */
    4076              : 
    4077            1 :     fclose(output);
    4078            1 :     return ret;
    4079              : }
    4080              : 
    4081              : 
    4082            0 : int dlt_execute_command(char *filename, char *command, ...)
    4083              : {
    4084              :     va_list val;
    4085              :     int argc;
    4086              :     char **args = NULL;
    4087            0 :     int ret = 0;
    4088              : 
    4089            0 :     if (command == NULL)
    4090              :         return -1;
    4091              : 
    4092              :     /* Determine number of variadic arguments */
    4093            0 :     va_start(val, command);
    4094              : 
    4095            0 :     for (argc = 2; va_arg(val, char *) != NULL; argc++);
    4096              : 
    4097            0 :     va_end(val);
    4098              : 
    4099              :     /* Allocate args, put references to command */
    4100            0 :     args = (char **) malloc( (uint32_t) argc * sizeof(char*));
    4101            0 :     args[0] = command;
    4102              : 
    4103            0 :     va_start(val, command);
    4104              : 
    4105            0 :     for (int i = 0; args[i] != NULL; i++)
    4106            0 :         args[i + 1] = va_arg(val, char *);
    4107              : 
    4108            0 :     va_end(val);
    4109              : 
    4110              :     /* Run command in child process */
    4111            0 :     pid_t pid = fork();
    4112              : 
    4113            0 :     if (pid == 0) { /* child process */
    4114              : 
    4115              :         /* Redirect output if required */
    4116            0 :         if (filename != NULL) {
    4117              :             int fd = open(filename, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
    4118              : 
    4119            0 :             if (fd < 0)
    4120            0 :                 err(-1, "%s failed on open()", __func__);
    4121              : 
    4122            0 :             if (dup2(fd, STDOUT_FILENO) == -1) {
    4123            0 :                 close(fd);
    4124            0 :                 err(-1, "%s failed on dup2()", __func__);
    4125              :             }
    4126              : 
    4127            0 :             close(fd);
    4128              :         }
    4129              : 
    4130              :         /* Run command */
    4131            0 :         execvp(command, (char **)args);
    4132              :     }
    4133            0 :     else if (pid == -1) /* error in fork */
    4134              :     {
    4135            0 :         ret = -1;
    4136              :     }
    4137              :     else /* parent */
    4138              :     {
    4139            0 :         if (wait(&ret) == -1) {
    4140            0 :             err(-1, "%s failed on wait()", __func__);
    4141              :         }
    4142              :     }
    4143              : 
    4144            0 :     free(args);
    4145            0 :     return ret;
    4146              : }
    4147              : 
    4148            5 : char *get_filename_ext(const char *filename)
    4149              : {
    4150            5 :     if (filename == NULL) {
    4151            0 :         fprintf(stderr, "ERROR: %s: invalid arguments\n", __FUNCTION__);
    4152            0 :         return "";
    4153              :     }
    4154              : 
    4155            5 :     char *dot = strrchr(filename, '.');
    4156            5 :     return (!dot || dot == filename) ? NULL : dot;
    4157              : }
    4158              : 
    4159            6 : bool dlt_extract_base_name_without_ext(const char* const abs_file_name, char* base_name, long base_name_len) {
    4160            6 :     if (abs_file_name == NULL || base_name == NULL) return false;
    4161              : 
    4162            6 :     const char* last_separator = strrchr(abs_file_name, '.');
    4163            6 :     if (!last_separator) return false;
    4164            5 :     long length = last_separator - abs_file_name;
    4165            5 :     length = length > base_name_len ? base_name_len : length;
    4166              : 
    4167            5 :     strncpy(base_name, abs_file_name, length);
    4168            5 :     base_name[length] = '\0';
    4169            5 :     return true;
    4170              : }
    4171              : 
    4172              : #ifdef DLT_TRACE_LOAD_CTRL_ENABLE
    4173              : static int32_t dlt_output_soft_limit_over_warning(
    4174              :     DltTraceLoadSettings* const tl_settings,
    4175              :     DltLogInternal log_internal,
    4176              :     void *const log_params)
    4177              : {
    4178              :     char local_str[255];
    4179              : 
    4180              :     if (!tl_settings || !tl_settings->tl_stat.is_over_soft_limit || tl_settings->tl_stat.slot_left_soft_limit_warn)
    4181              :     {
    4182              :         /* No need to output warning message */
    4183              :         return 0;
    4184              :     }
    4185              : 
    4186              :     /* Calculate extra trace load which was over limit */
    4187              :     const uint64_t dropped_message_load
    4188              :         = (tl_settings->tl_stat.hard_limit_over_bytes * DLT_TIMESTAMP_RESOLUTION)
    4189              :           / TIMESTAMP_BASED_WINDOW_SIZE;
    4190              :     const uint64_t curr_trace_load = tl_settings->tl_stat.avg_trace_load + dropped_message_load;
    4191              :     if (curr_trace_load <= tl_settings->soft_limit) {
    4192              :         /* No need to output warning message */
    4193              :         return 0;
    4194              :     }
    4195              : 
    4196              :     /* Warning for exceeded soft limit */
    4197              :     if (tl_settings->ctid[0] == 0) {
    4198              :         snprintf(local_str, sizeof(local_str),
    4199              :                  "Trace load exceeded trace soft limit on apid %.4s "
    4200              :                  "(soft limit: %u bytes/sec, current: %lu bytes/sec)",
    4201              :                  tl_settings->apid,
    4202              :                  tl_settings->soft_limit,
    4203              :                  curr_trace_load);
    4204              :     } else {
    4205              :         snprintf(local_str, sizeof(local_str),
    4206              :                  "Trace load exceeded trace soft limit on apid %.4s, ctid %.4s "
    4207              :                  "(soft limit: %u bytes/sec, current: %lu bytes/sec)",
    4208              :                  tl_settings->apid,
    4209              :                  tl_settings->ctid,
    4210              :                  tl_settings->soft_limit,
    4211              :                  curr_trace_load);
    4212              :     }
    4213              : 
    4214              :     // must be signed int for error return value
    4215              :     int32_t sent_size = log_internal(DLT_LOG_WARN, local_str, log_params);
    4216              :     if (sent_size < DLT_RETURN_OK)
    4217              :     {
    4218              :         /* Output warning message via other route for safety */
    4219              :         dlt_log(DLT_LOG_WARN, local_str);
    4220              :         sent_size = 0;
    4221              :     }
    4222              : 
    4223              :     /* Turn off the flag after sending warning message */
    4224              :     tl_settings->tl_stat.is_over_soft_limit = false;
    4225              :     tl_settings->tl_stat.slot_left_soft_limit_warn = DLT_SOFT_LIMIT_WARN_FREQUENCY;
    4226              : 
    4227              :     return sent_size;
    4228              : }
    4229              : 
    4230              : static int32_t dlt_output_hard_limit_warning(
    4231              :     DltTraceLoadSettings* const tl_settings,
    4232              :     DltLogInternal log_internal,
    4233              :     void *const log_params)
    4234              : {
    4235              :     char local_str[255];
    4236              :     if (!tl_settings || !tl_settings->tl_stat.is_over_hard_limit || tl_settings->tl_stat.slot_left_hard_limit_warn)
    4237              :     {
    4238              :         /* No need to output warning message */
    4239              :         return 0;
    4240              :     }
    4241              : 
    4242              :     /* Calculate extra trace load which was over limit */
    4243              :     const uint64_t dropped_message_load
    4244              :         = (tl_settings->tl_stat.hard_limit_over_bytes * DLT_TIMESTAMP_RESOLUTION)
    4245              :           / TIMESTAMP_BASED_WINDOW_SIZE;
    4246              :     const uint64_t curr_trace_load = tl_settings->tl_stat.avg_trace_load + dropped_message_load;
    4247              :     if (curr_trace_load <= tl_settings->hard_limit) {
    4248              :         /* No need to output warning message */
    4249              :         return 0;
    4250              :     }
    4251              : 
    4252              :     if (tl_settings->ctid[0] == 0) {
    4253              :         snprintf(local_str, sizeof(local_str),
    4254              :                  "Trace load exceeded trace hard limit on apid %.4s "
    4255              :                  "(hard limit: %u bytes/sec, current: %lu bytes/sec) %u messages discarded. ",
    4256              :                  tl_settings->apid,
    4257              :                  tl_settings->hard_limit,
    4258              :                  curr_trace_load,
    4259              :                  tl_settings->tl_stat.hard_limit_over_counter);
    4260              :     } else {
    4261              :         snprintf(local_str, sizeof(local_str),
    4262              :                  "Trace load exceeded trace hard limit on apid %.4s, ctid %.4s."
    4263              :                  "(hard limit: %u bytes/sec, current: %lu bytes/sec) %u messages discarded.",
    4264              :                  tl_settings->apid,
    4265              :                  tl_settings->ctid,
    4266              :                  tl_settings->hard_limit,
    4267              :                  curr_trace_load,
    4268              :                  tl_settings->tl_stat.hard_limit_over_counter);
    4269              :     }
    4270              : 
    4271              :     // must be signed int for error return
    4272              :     int32_t sent_size = log_internal(DLT_LOG_WARN, local_str, log_params);
    4273              :     if (sent_size < DLT_RETURN_OK)
    4274              :     {
    4275              :         /* Output warning message via other route for safety */
    4276              :         dlt_log(DLT_LOG_WARN, local_str);
    4277              :         sent_size = 0;
    4278              :     }
    4279              : 
    4280              :     /* Turn off the flag after sending warning message */
    4281              :     tl_settings->tl_stat.is_over_hard_limit = false;
    4282              :     tl_settings->tl_stat.hard_limit_over_counter = 0;
    4283              :     tl_settings->tl_stat.hard_limit_over_bytes = 0;
    4284              :     tl_settings->tl_stat.slot_left_hard_limit_warn = DLT_HARD_LIMIT_WARN_FREQUENCY;
    4285              : 
    4286              :     return sent_size;
    4287              : }
    4288              : 
    4289              : static bool dlt_user_cleanup_window(DltTraceLoadStat *const tl_stat)
    4290              : {
    4291              :     if (!tl_stat)
    4292              :     {
    4293              :         return false;
    4294              :     }
    4295              : 
    4296              :     uint32_t elapsed_slots  = 0;
    4297              :     /* check if overflow of timestamp happened, after ~119 hours */
    4298              :     if (tl_stat->curr_abs_slot < tl_stat->last_abs_slot) {
    4299              :         /* calculate where the next slot starts according to the last slot
    4300              :          * This works because the value after the uint32 rollover equals is equal to the remainder that did not fit
    4301              :          * into uint32 before. Therefore, we always have slots that are DLT_TIMESTAMP_RESOLUTION long
    4302              :          * */
    4303              :         const uint32_t next_slot_start =
    4304              :             DLT_TIMESTAMP_RESOLUTION + tl_stat->last_abs_slot;
    4305              : 
    4306              :         /* Check if we are already in the next slot */
    4307              :         if (next_slot_start <= tl_stat->curr_abs_slot) {
    4308              :             /* Calculate relative amount of elapsed slots */
    4309              :             elapsed_slots = (tl_stat->curr_abs_slot - next_slot_start) / DLT_TIMESTAMP_RESOLUTION + 1;
    4310              :         }
    4311              :         /* else we are not in the next slot yet */
    4312              :     } else {
    4313              :         /* no rollover, get difference between slots to get amount of elapsed slots  */
    4314              :         elapsed_slots = (tl_stat->curr_abs_slot - tl_stat->last_abs_slot);
    4315              :     }
    4316              : 
    4317              :     if (!elapsed_slots)
    4318              :     {
    4319              :         /* Same slot can be still used. No need to cleanup slot */
    4320              :         return false;
    4321              :     }
    4322              : 
    4323              :     /* Slot-Based Count down for next warning messages */
    4324              :     tl_stat->slot_left_soft_limit_warn = (tl_stat->slot_left_soft_limit_warn > elapsed_slots) ?
    4325              :                                                                                               (tl_stat->slot_left_soft_limit_warn - elapsed_slots) : 0;
    4326              : 
    4327              :     tl_stat->slot_left_hard_limit_warn = (tl_stat->slot_left_hard_limit_warn > elapsed_slots) ?
    4328              :                                                                                               (tl_stat->slot_left_hard_limit_warn - elapsed_slots) : 0;
    4329              : 
    4330              :     /* Clear whole window when time elapsed longer than window size from last message */
    4331              :     if (elapsed_slots >= DLT_TRACE_LOAD_WINDOW_SIZE)
    4332              :     {
    4333              :         tl_stat->total_bytes_of_window = 0;
    4334              :         memset(tl_stat->window, 0, sizeof(tl_stat->window));
    4335              :         return true;
    4336              :     }
    4337              : 
    4338              :     /* Clear skipped no data slots */
    4339              :     uint32_t temp_slot = tl_stat->last_slot;
    4340              :     while (temp_slot != tl_stat->curr_slot)
    4341              :     {
    4342              :         temp_slot++;
    4343              :         temp_slot %= DLT_TRACE_LOAD_WINDOW_SIZE;
    4344              :         tl_stat->total_bytes_of_window -= tl_stat->window[temp_slot];
    4345              :         tl_stat->window[temp_slot] = 0;
    4346              :     }
    4347              : 
    4348              :     return true;
    4349              : }
    4350              : 
    4351              : static int32_t dlt_switch_slot_if_needed(
    4352              :     DltTraceLoadSettings* const tl_settings,
    4353              :     DltLogInternal log_internal,
    4354              :     void* const log_internal_params,
    4355              :     const uint32_t timestamp)
    4356              : {
    4357              :     if (!tl_settings)
    4358              :     {
    4359              :         return 0;
    4360              :     }
    4361              : 
    4362              :     /* Get new window slot No. */
    4363              :     tl_settings->tl_stat.curr_abs_slot = timestamp / DLT_TRACE_LOAD_WINDOW_RESOLUTION;
    4364              :     tl_settings->tl_stat.curr_slot = tl_settings->tl_stat.curr_abs_slot % DLT_TRACE_LOAD_WINDOW_SIZE;
    4365              : 
    4366              :     /* Cleanup window */
    4367              :     if (!dlt_user_cleanup_window(&tl_settings->tl_stat))
    4368              :     {
    4369              :         /* No need to switch slot because same slot can be still used */
    4370              :         return 0;
    4371              :     }
    4372              : 
    4373              :     /* If slot is switched and trace load has been over soft/hard limit
    4374              :      * in previous slot, warning messages may be sent.
    4375              :      * The warning messages will be also counted as trace load.
    4376              :      */
    4377              :     const int32_t sent_warn_msg_bytes =
    4378              :         dlt_output_soft_limit_over_warning(tl_settings, log_internal, log_internal_params) +
    4379              :         dlt_output_hard_limit_warning(tl_settings, log_internal, log_internal_params);
    4380              :     return sent_warn_msg_bytes;
    4381              : }
    4382              : 
    4383              : static void dlt_record_trace_load(DltTraceLoadStat *const tl_stat, const int32_t size)
    4384              : {
    4385              :     if (!tl_stat)
    4386              :     {
    4387              :         return;
    4388              :     }
    4389              : 
    4390              :     /* Record trace load to current slot by message size of
    4391              :      * original message and warning message if it was sent
    4392              :      */
    4393              :     tl_stat->window[tl_stat->curr_slot] += size;
    4394              :     tl_stat->total_bytes_of_window += size;
    4395              : 
    4396              :     /* Keep the latest time information */
    4397              :     tl_stat->last_abs_slot = tl_stat->curr_abs_slot;
    4398              :     tl_stat->last_slot = tl_stat->curr_slot;
    4399              : 
    4400              :     /* Calculate average trace load [bytes/sec] in window
    4401              :      * The division is necessary to normalize the average to bytes per second even if
    4402              :      * the slot size is not equal to 1s
    4403              :      * */
    4404              :     tl_stat->avg_trace_load
    4405              :         = (tl_stat->total_bytes_of_window * DLT_TIMESTAMP_RESOLUTION) / TIMESTAMP_BASED_WINDOW_SIZE;
    4406              : }
    4407              : 
    4408              : static inline bool dlt_is_over_trace_load_soft_limit(DltTraceLoadSettings* const tl_settings)
    4409              : {
    4410              :     if (tl_settings
    4411              :         && (tl_settings->tl_stat.avg_trace_load > tl_settings->soft_limit || tl_settings->soft_limit == 0))
    4412              :     {
    4413              :         /* Mark as soft limit over */
    4414              :         tl_settings->tl_stat.is_over_soft_limit = true;
    4415              :         return true;
    4416              :     }
    4417              : 
    4418              :     return false;
    4419              : }
    4420              : 
    4421              : static inline bool dlt_is_over_trace_load_hard_limit(
    4422              :     DltTraceLoadSettings* const tl_settings, const int size)
    4423              : {
    4424              :     if (tl_settings
    4425              :         && (tl_settings->tl_stat.avg_trace_load > tl_settings->hard_limit
    4426              :             || tl_settings->hard_limit == 0))
    4427              :     {
    4428              :         /* Mark as limit over */
    4429              :         tl_settings->tl_stat.is_over_hard_limit = true;
    4430              :         tl_settings->tl_stat.hard_limit_over_counter++;
    4431              :         tl_settings->tl_stat.hard_limit_over_bytes += size;
    4432              : 
    4433              :         /* Delete size of limit over message from window */
    4434              :         tl_settings->tl_stat.window[tl_settings->tl_stat.curr_slot] -= size;
    4435              :         tl_settings->tl_stat.total_bytes_of_window -= size;
    4436              :         return true;
    4437              :     }
    4438              : 
    4439              :     return false;
    4440              : }
    4441              : 
    4442              : bool dlt_check_trace_load(
    4443              :     DltTraceLoadSettings * const tl_settings,
    4444              :     const int32_t log_level,
    4445              :     const uint32_t timestamp,
    4446              :     const int32_t size,
    4447              :     DltLogInternal internal_dlt_log,
    4448              :     void* const internal_dlt_log_params)
    4449              : {
    4450              :     /* Unconditionally allow message which has log level: Debug/Verbose to be output */
    4451              :     if (log_level == DLT_LOG_DEBUG || log_level == DLT_LOG_VERBOSE)
    4452              :     {
    4453              :         return true;
    4454              :     }
    4455              : 
    4456              :     if (size < 0)
    4457              :     {
    4458              :         dlt_vlog(LOG_ERR, "Invalid size: %d", size);
    4459              :         return false;
    4460              :     }
    4461              : 
    4462              :     /* Switch window slot according to timestamp
    4463              :      * If warning messages for hard/soft limit over are sent,
    4464              :      * the message size will be returned.
    4465              :      */
    4466              :     const int32_t sent_warn_msg_bytes = dlt_switch_slot_if_needed(
    4467              :         tl_settings, internal_dlt_log, internal_dlt_log_params, timestamp);
    4468              : 
    4469              :     /* Record trace load */
    4470              :     dlt_record_trace_load(&tl_settings->tl_stat, size + sent_warn_msg_bytes);
    4471              : 
    4472              :     /* Check if trace load is over the soft limit.
    4473              :      * Even if trace load is over the soft limit, message will not be discarded.
    4474              :      * Only the warning message will be output
    4475              :      */
    4476              :     dlt_is_over_trace_load_soft_limit(tl_settings);
    4477              : 
    4478              :     /* Check if trace load is over hard limit.
    4479              :      * If trace load is over the limit, message will be discarded.
    4480              :      */
    4481              :     const bool allow_output = !dlt_is_over_trace_load_hard_limit(tl_settings, size);
    4482              : 
    4483              :     return allow_output;
    4484              : }
    4485              : 
    4486              : DltTraceLoadSettings*
    4487              : dlt_find_runtime_trace_load_settings(DltTraceLoadSettings *settings, uint32_t settings_count, const char* apid, const char* ctid) {
    4488              :     if ((apid == NULL) || (strlen(apid) == 0))
    4489              :         return NULL;
    4490              : 
    4491              :     DltTraceLoadSettings* app_level = NULL;
    4492              :     size_t ctid_len = (ctid != NULL) ? strlen(ctid) : 0;
    4493              : 
    4494              :     for (uint32_t i = 0; i < settings_count; ++i) {
    4495              :         if (strncmp(apid, settings->apid, DLT_ID_SIZE) != 0) {
    4496              :             if (app_level == NULL)
    4497              :                 continue;
    4498              :             // settings are sorted.
    4499              :             // If we found a configuration entry which matches the app id already
    4500              :             // we can exit here because no more entries with the app id will follow anymore.
    4501              :             break;
    4502              :         }
    4503              : 
    4504              :         if (settings[i].ctid[0] == '\0') {
    4505              :             app_level = &settings[i];
    4506              :             if (ctid_len == 0)
    4507              :                 return &settings[i];
    4508              :             continue;
    4509              :         }
    4510              : 
    4511              :         if ((ctid_len > 0) && (strncmp(ctid, settings[i].ctid, DLT_ID_SIZE) == 0)) {
    4512              :             return &settings[i];
    4513              :         }
    4514              :     }
    4515              : 
    4516              :     return app_level;
    4517              : }
    4518              : 
    4519              : #endif
        

Generated by: LCOV version 2.0-1