LCOV - code coverage report
Current view: top level - shared - dlt_common.c (source / functions) Hit Total Coverage
Test: dlt_final_coverage.info Lines: 1003 1625 61.7 %
Date: 2024-10-22 04:07:23 Functions: 81 95 85.3 %

          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           0 :             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        6207 : size_t dlt_strnlen_s(const char* str, size_t maxsize)
     328             : {
     329        6207 :     if (str == NULL)
     330             :         return 0;
     331             : 
     332       27721 :     for (size_t i = 0; i < maxsize; ++i) {
     333       24857 :         if (str[i] == '\0')
     334        3342 :             return i;
     335             :     }
     336             :     return maxsize;
     337             : }
     338             : 
     339        6205 : void dlt_print_id(char *text, const char *id)
     340             : {
     341             :     /* check nullpointer */
     342        6205 :     if ((text == NULL) || (id == NULL))
     343             :         return;
     344             : 
     345             :     /* Initialize text */
     346             :     memset(text, '-', DLT_ID_SIZE);
     347             : 
     348        6202 :     text[DLT_ID_SIZE] = 0;
     349             : 
     350        6202 :     size_t len = dlt_strnlen_s(id, DLT_ID_SIZE);
     351             : 
     352             :     memcpy(text, id, len);
     353             : }
     354             : 
     355       80662 : void dlt_set_id(char *id, const char *text)
     356             : {
     357             :     /* check nullpointer */
     358       80662 :     if ((id == NULL) || (text == NULL))
     359             :         return;
     360             : 
     361       80659 :     id[0] = 0;
     362       80659 :     id[1] = 0;
     363       80659 :     id[2] = 0;
     364       74119 :     id[3] = 0;
     365             : 
     366       80659 :     if (text[0] != 0)
     367       51219 :         id[0] = text[0];
     368             :     else
     369             :         return;
     370             : 
     371       51219 :     if (text[1] != 0)
     372       51213 :         id[1] = text[1];
     373             :     else
     374             :         return;
     375             : 
     376       51213 :     if (text[2] != 0)
     377       51205 :         id[2] = text[2];
     378             :     else
     379             :         return;
     380             : 
     381       51205 :     if (text[3] != 0)
     382       51028 :         id[3] = text[3];
     383             :     else
     384             :         return;
     385             : }
     386             : 
     387        1549 : void dlt_clean_string(char *text, int length)
     388             : {
     389             :     int num;
     390             : 
     391        1549 :     if (text == NULL)
     392             :         return;
     393             : 
     394       13406 :     for (num = 0; num < length; num++)
     395       11857 :         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        6128 : DltReturnValue dlt_message_init(DltMessage *msg, int verbose)
     649             : {
     650        6128 :     PRINT_FUNCTION_VERBOSE(verbose);
     651             : 
     652        6128 :     if (msg == NULL)
     653             :         return DLT_RETURN_WRONG_PARAMETER;
     654             : 
     655             :     /* initalise structure parameters */
     656        6126 :     msg->headersize = 0;
     657        6126 :     msg->datasize = 0;
     658             : 
     659        6126 :     msg->databuffer = NULL;
     660        6126 :     msg->databuffersize = 0;
     661             : 
     662        6126 :     msg->storageheader = NULL;
     663        6126 :     msg->standardheader = NULL;
     664        6126 :     msg->extendedheader = NULL;
     665             : 
     666        6126 :     msg->found_serialheader = 0;
     667             : 
     668        6126 :     return DLT_RETURN_OK;
     669             : }
     670             : 
     671         127 : DltReturnValue dlt_message_free(DltMessage *msg, int verbose)
     672             : {
     673         127 :     PRINT_FUNCTION_VERBOSE(verbose);
     674             : 
     675         127 :     if (msg == NULL)
     676             :         return DLT_RETURN_WRONG_PARAMETER;
     677             : 
     678             :     /* delete databuffer if exists */
     679         125 :     if (msg->databuffer) {
     680         102 :         free(msg->databuffer);
     681         102 :         msg->databuffer = NULL;
     682         102 :         msg->databuffersize = 0;
     683             :     }
     684             : 
     685             :     return DLT_RETURN_OK;
     686             : }
     687             : 
     688        2615 : DltReturnValue dlt_message_header(DltMessage *msg, char *text, size_t textlength, int verbose)
     689             : {
     690        2615 :     return dlt_message_header_flags(msg, text, textlength, DLT_HEADER_SHOW_ALL, verbose);
     691             : }
     692             : 
     693        5317 : 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        5317 :     PRINT_FUNCTION_VERBOSE(verbose);
     699             : 
     700        5317 :     if ((msg == NULL) || (text == NULL) || (textlength <= 0))
     701             :         return DLT_RETURN_WRONG_PARAMETER;
     702             : 
     703        5121 :     if ((DLT_IS_HTYP_UEH(msg->standardheader->htyp)) && (msg->extendedheader == NULL))
     704             :         return DLT_RETURN_WRONG_PARAMETER;
     705             : 
     706        5121 :     if ((flags < DLT_HEADER_SHOW_NONE) || (flags > DLT_HEADER_SHOW_ALL))
     707             :         return DLT_RETURN_WRONG_PARAMETER;
     708             : 
     709        5121 :     text[0] = 0;
     710             : 
     711        5121 :     if ((flags & DLT_HEADER_SHOW_TIME) == DLT_HEADER_SHOW_TIME) {
     712             :         /* print received time */
     713        3021 :         time_t tt = msg->storageheader->seconds;
     714        3021 :         tzset();
     715        3021 :         localtime_r(&tt, &timeinfo);
     716        3021 :         strftime (buffer, sizeof(buffer), "%Y/%m/%d %H:%M:%S", &timeinfo);
     717        3021 :         snprintf(text, textlength, "%s.%.6d ", buffer, msg->storageheader->microseconds);
     718             :     }
     719             : 
     720        5121 :     if ((flags & DLT_HEADER_SHOW_TMSTP) == DLT_HEADER_SHOW_TMSTP) {
     721             :         /* print timestamp if available */
     722        3021 :         if (DLT_IS_HTYP_WTMS(msg->standardheader->htyp))
     723         842 :             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        5121 :     if ((flags & DLT_HEADER_SHOW_MSGCNT) == DLT_HEADER_SHOW_MSGCNT)
     729             :         /* print message counter */
     730        3021 :         snprintf(text + strlen(text), textlength - strlen(text), "%.3d ", msg->standardheader->mcnt);
     731             : 
     732        5121 :     if ((flags & DLT_HEADER_SHOW_ECUID) == DLT_HEADER_SHOW_ECUID) {
     733             :         /* print ecu id, use header extra if available, else storage header value */
     734        3021 :         if (DLT_IS_HTYP_WEID(msg->standardheader->htyp))
     735         842 :             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        5121 :     if ((flags & DLT_HEADER_SHOW_APID) == DLT_HEADER_SHOW_APID) {
     743        3021 :         snprintf(text + strlen(text), textlength - strlen(text), " ");
     744             : 
     745        3021 :         if ((DLT_IS_HTYP_UEH(msg->standardheader->htyp)) && (msg->extendedheader->apid[0] != 0))
     746        1590 :             dlt_print_id(text + strlen(text), msg->extendedheader->apid);
     747             :         else
     748        1431 :             snprintf(text + strlen(text), textlength - strlen(text), "----");
     749             : 
     750        3021 :         snprintf(text + strlen(text), textlength - strlen(text), " ");
     751             :     }
     752             : 
     753        5121 :     if ((flags & DLT_HEADER_SHOW_CTID) == DLT_HEADER_SHOW_CTID) {
     754        3021 :         if ((DLT_IS_HTYP_UEH(msg->standardheader->htyp)) && (msg->extendedheader->ctid[0] != 0))
     755        1590 :             dlt_print_id(text + strlen(text), msg->extendedheader->ctid);
     756             :         else
     757        1431 :             snprintf(text + strlen(text), textlength - strlen(text), "----");
     758             : 
     759        3021 :         snprintf(text + strlen(text), textlength - strlen(text), " ");
     760             :     }
     761             : 
     762             :     /* print info about message type and length */
     763        5121 :     if (DLT_IS_HTYP_UEH(msg->standardheader->htyp)) {
     764        2630 :         if ((flags & DLT_HEADER_SHOW_MSGTYPE) == DLT_HEADER_SHOW_MSGTYPE) {
     765        1590 :             snprintf(text + strlen(text), textlength - strlen(text), "%s",
     766        1590 :                      message_type[DLT_GET_MSIN_MSTP(msg->extendedheader->msin)]);
     767        1590 :             snprintf(text + strlen(text), textlength - strlen(text), " ");
     768             :         }
     769             : 
     770        2630 :         if ((flags & DLT_HEADER_SHOW_MSGSUBTYPE) == DLT_HEADER_SHOW_MSGSUBTYPE) {
     771        1590 :             if ((DLT_GET_MSIN_MSTP(msg->extendedheader->msin)) == DLT_TYPE_LOG)
     772        1451 :                 snprintf(text + strlen(text), textlength - strlen(text), "%s",
     773        1451 :                          log_info[DLT_GET_MSIN_MTIN(msg->extendedheader->msin)]);
     774             : 
     775        1590 :             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        1590 :             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        1590 :             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        1590 :             snprintf(text + strlen(text), textlength - strlen(text), " ");
     788             :         }
     789             : 
     790        2630 :         if ((flags & DLT_HEADER_SHOW_VNVSTATUS) == DLT_HEADER_SHOW_VNVSTATUS) {
     791             :             /* print verbose status pf message */
     792        1590 :             if (DLT_IS_MSIN_VERB(msg->extendedheader->msin))
     793        1451 :                 snprintf(text + strlen(text), textlength - strlen(text), "V");
     794             :             else
     795         139 :                 snprintf(text + strlen(text), textlength - strlen(text), "N");
     796             : 
     797        1590 :             snprintf(text + strlen(text), textlength - strlen(text), " ");
     798             :         }
     799             : 
     800        2630 :         if ((flags & DLT_HEADER_SHOW_NOARG) == DLT_HEADER_SHOW_NOARG)
     801             :             /* print number of arguments */
     802        1590 :             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        3326 : 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        3326 :     PRINT_FUNCTION_VERBOSE(verbose);
     840             : 
     841        3326 :     if ((msg == NULL) || (msg->databuffer == NULL) || (text == NULL) ||
     842        3267 :         (type < DLT_OUTPUT_HEX) || (type > DLT_OUTPUT_ASCII_LIMITED))
     843             :         return DLT_RETURN_WRONG_PARAMETER;
     844             : 
     845        3136 :     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        3126 :     text[0] = 0;
     852             : 
     853             :     /* print payload only as hex */
     854        3126 :     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        2600 :     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        2074 :     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        1548 :     ptr = msg->databuffer;
     865        1548 :     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        1548 :     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        4336 :     for (num = 0; num < (int)(msg->extendedheader->noar); num++) {
     942        3325 :         if (num != 0) {
     943        2328 :             text_offset = (int)strlen(text);
     944        2328 :             snprintf(text + text_offset, textlength - (size_t)text_offset, " ");
     945             :         }
     946             : 
     947             :         /* first read the type info of the argument */
     948        3325 :         DLT_MSG_READ_VALUE(type_info_tmp, ptr, datalength, uint32_t);
     949        3325 :         type_info = DLT_ENDIAN_GET_32(msg->standardheader->htyp, type_info_tmp);
     950             : 
     951             :         /* print out argument */
     952        3325 :         text_offset = (int)strlen(text);
     953             : 
     954        3325 :         if (dlt_message_argument_print(msg, type_info, pptr, pdatalength,
     955        3325 :                                        (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        6679 : 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        6679 :     PRINT_FUNCTION_VERBOSE(verbose);
     999             : 
    1000        6679 :     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        6041 :     if (msg->databuffer) {
    1110        6027 :         if (msg->datasize > msg->databuffersize) {
    1111           6 :             free(msg->databuffer);
    1112           6 :             msg->databuffer = (uint8_t *)malloc(msg->datasize);
    1113           6 :             msg->databuffersize = msg->datasize;
    1114             :         }
    1115             :     }
    1116             :     else {
    1117             :         /* get new memory for buffer */
    1118          14 :         msg->databuffer = (uint8_t *)malloc(msg->datasize);
    1119          14 :         msg->databuffersize = msg->datasize;
    1120             :     }
    1121             : 
    1122        6041 :     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        6041 :     memcpy(msg->databuffer, buffer + (msg->headersize - sizeof(DltStorageHeader)), msg->datasize);
    1131             : 
    1132        6041 :     return DLT_MESSAGE_ERROR_OK;
    1133             : }
    1134             : 
    1135        7417 : DltReturnValue dlt_message_get_extraparameters(DltMessage *msg, int verbose)
    1136             : {
    1137        7417 :     PRINT_FUNCTION_VERBOSE(verbose);
    1138             : 
    1139        7417 :     if (msg == NULL)
    1140             :         return DLT_RETURN_WRONG_PARAMETER;
    1141             : 
    1142        7415 :     if (DLT_IS_HTYP_WEID(msg->standardheader->htyp))
    1143        7221 :         memcpy(msg->headerextra.ecu,
    1144             :                msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader),
    1145             :                DLT_ID_SIZE);
    1146             : 
    1147        7415 :     if (DLT_IS_HTYP_WSID(msg->standardheader->htyp)) {
    1148        6927 :         memcpy(&(msg->headerextra.seid), msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader)
    1149        6927 :                + (DLT_IS_HTYP_WEID(msg->standardheader->htyp) ? DLT_SIZE_WEID : 0), DLT_SIZE_WSID);
    1150        6927 :         msg->headerextra.seid = DLT_BETOH_32(msg->headerextra.seid);
    1151             :     }
    1152             : 
    1153        7415 :     if (DLT_IS_HTYP_WTMS(msg->standardheader->htyp)) {
    1154       14442 :         memcpy(&(msg->headerextra.tmsp), msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader)
    1155        7221 :                + (DLT_IS_HTYP_WEID(msg->standardheader->htyp) ? DLT_SIZE_WEID : 0)
    1156        7221 :                + (DLT_IS_HTYP_WSID(msg->standardheader->htyp) ? DLT_SIZE_WSID : 0), DLT_SIZE_WTMS);
    1157        7221 :         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          71 : DltReturnValue dlt_file_init(DltFile *file, int verbose)
    1196             : {
    1197          71 :     PRINT_FUNCTION_VERBOSE(verbose);
    1198             : 
    1199          71 :     if (file == NULL)
    1200             :         return DLT_RETURN_WRONG_PARAMETER;
    1201             : 
    1202             :     /* initalise structure parameters */
    1203          71 :     file->handle = NULL;
    1204          71 :     file->counter = 0;
    1205          71 :     file->counter_total = 0;
    1206          71 :     file->index = NULL;
    1207             : 
    1208          71 :     file->filter = NULL;
    1209          71 :     file->filter_counter = 0;
    1210          71 :     file->file_position = 0;
    1211             : 
    1212          71 :     file->position = 0;
    1213             : 
    1214          71 :     file->error_messages = 0;
    1215             : 
    1216          71 :     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        7035 : DltReturnValue dlt_file_read_header(DltFile *file, int verbose)
    1233             : {
    1234        7035 :     PRINT_FUNCTION_VERBOSE(verbose);
    1235             : 
    1236        7035 :     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       14070 :         if (fread(file->msg.headerbuffer,
    1243             :                   sizeof(DltStorageHeader) + sizeof(DltStandardHeader), 1,
    1244             :                   file->handle) != 1) {
    1245          56 :             if (!feof(file->handle))
    1246           0 :                 dlt_log(LOG_WARNING, "Cannot read header from file!\n");
    1247             :             else
    1248          56 :                 dlt_log(LOG_DEBUG, "Reached end of file\n");
    1249             : 
    1250          56 :             return DLT_RETURN_ERROR;
    1251             :         }
    1252             : 
    1253             :         /* set ptrs to structures */
    1254        6979 :         file->msg.storageheader = (DltStorageHeader *)file->msg.headerbuffer;
    1255        6979 :         file->msg.standardheader = (DltStandardHeader *)(file->msg.headerbuffer +
    1256             :                                                          sizeof(DltStorageHeader));
    1257             : 
    1258             :         /* check id of storage header */
    1259        6979 :         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        6979 :     file->msg.headersize = (uint32_t) (sizeof(DltStorageHeader) + sizeof(DltStandardHeader) +
    1276        6979 :         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        6979 :     temp_datasize = DLT_BETOH_16(file->msg.standardheader->len) + (int32_t) sizeof(DltStorageHeader) - (int32_t) file->msg.headersize;
    1282             : 
    1283             :     /* check data size */
    1284        6979 :     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        6979 :         file->msg.datasize = (uint32_t) temp_datasize;
    1291             :     }
    1292             : 
    1293             :     /* check if verbose mode is on */
    1294        6979 :     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        4700 : DltReturnValue dlt_file_read_header_extended(DltFile *file, int verbose)
    1402             : {
    1403        4700 :     PRINT_FUNCTION_VERBOSE(verbose);
    1404             : 
    1405        4700 :     if (file == NULL)
    1406             :         return DLT_RETURN_WRONG_PARAMETER;
    1407             : 
    1408             :     /* load standard header extra parameters if used */
    1409        4700 :     if (DLT_STANDARD_HEADER_EXTRA_SIZE(file->msg.standardheader->htyp)) {
    1410        1920 :         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         960 :         dlt_message_get_extraparameters(&(file->msg), verbose);
    1418             :     }
    1419             : 
    1420             :     /* load Extended header if used */
    1421        4700 :     if (DLT_IS_HTYP_UEH(file->msg.standardheader->htyp) == 0)
    1422             :         /* there is nothing to be loaded */
    1423             :         return DLT_RETURN_OK;
    1424             : 
    1425        2368 :     if (fread(file->msg.headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) +
    1426        2368 :               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        2368 :     if (DLT_IS_HTYP_UEH(file->msg.standardheader->htyp))
    1435        2368 :         file->msg.extendedheader =
    1436        2368 :             (DltExtendedHeader *)(file->msg.headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) +
    1437        2368 :                                   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        4070 : DltReturnValue dlt_file_read_data(DltFile *file, int verbose)
    1445             : {
    1446        4070 :     PRINT_FUNCTION_VERBOSE(verbose);
    1447             : 
    1448        4070 :     if (file == NULL)
    1449             :         return DLT_RETURN_WRONG_PARAMETER;
    1450             : 
    1451             :     /* free last used memory for buffer */
    1452        4070 :     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        4070 :     if (file->msg.databuffer == NULL) {
    1458             :         /* get new memory for buffer */
    1459         186 :         file->msg.databuffer = (uint8_t *)malloc(file->msg.datasize);
    1460         186 :         file->msg.databuffersize = file->msg.datasize;
    1461             :     }
    1462             : 
    1463        4070 :     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        8140 :     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          67 : DltReturnValue dlt_file_open(DltFile *file, const char *filename, int verbose)
    1484             : {
    1485          67 :     PRINT_FUNCTION_VERBOSE(verbose);
    1486             : 
    1487          67 :     if ((file == NULL) || (filename == NULL))
    1488             :         return DLT_RETURN_WRONG_PARAMETER;
    1489             : 
    1490             :     /* reset counters */
    1491          61 :     file->counter = 0;
    1492          61 :     file->counter_total = 0;
    1493          61 :     file->position = 0;
    1494          61 :     file->file_position = 0;
    1495          61 :     file->file_length = 0;
    1496          61 :     file->error_messages = 0;
    1497             : 
    1498          61 :     if (file->handle)
    1499           0 :         fclose(file->handle);
    1500             : 
    1501             :     /* open dlt file */
    1502          61 :     file->handle = fopen(filename, "rb");
    1503             : 
    1504          61 :     if (file->handle == NULL) {
    1505           0 :         dlt_vlog(LOG_WARNING, "File %s cannot be opened!\n", filename);
    1506           0 :         return DLT_RETURN_ERROR;
    1507             :     }
    1508             : 
    1509          61 :     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          61 :     file->file_length = ftell(file->handle);
    1515             : 
    1516          61 :     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          61 :     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        2965 : DltReturnValue dlt_file_read(DltFile *file, int verbose)
    1529             : {
    1530             :     long *ptr;
    1531             :     int found = DLT_RETURN_OK;
    1532             : 
    1533        2965 :     if (file == NULL)
    1534             :         return DLT_RETURN_WRONG_PARAMETER;
    1535             : 
    1536        2965 :     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        2965 :     if (file->counter % DLT_COMMON_INDEX_ALLOC == 0) {
    1541         368 :         ptr = (long *)malloc(((file->counter / DLT_COMMON_INDEX_ALLOC) + 1) * DLT_COMMON_INDEX_ALLOC * sizeof(long));
    1542             : 
    1543         368 :         if (ptr == NULL)
    1544             :             return DLT_RETURN_ERROR;
    1545             : 
    1546         368 :         if (file->index) {
    1547         312 :             memcpy(ptr, file->index, (size_t)(file->counter) * sizeof(long));
    1548         312 :             free(file->index);
    1549             :         }
    1550             : 
    1551         368 :         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        2965 :     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        2965 :     if (verbose)
    1563           0 :         dlt_vlog(LOG_INFO, "Position in file: %" PRIu64 "\n", file->file_position);
    1564             : 
    1565             :     /* read header */
    1566        2965 :     if (dlt_file_read_header(file, verbose) < DLT_RETURN_OK) {
    1567             :         /* go back to last position in file */
    1568          56 :         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          56 :         return DLT_RETURN_ERROR;
    1573             :     }
    1574             : 
    1575        2909 :     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        2279 :         if (fseek(file->handle,
    1613        2279 :                   (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        2279 :         file->index[file->counter] = file->file_position;
    1630        2279 :         file->counter++;
    1631        2279 :         file->position = file->counter - 1;
    1632             : 
    1633             :         found = DLT_RETURN_TRUE;
    1634             :     }
    1635             : 
    1636             :     /* increase total message counter */
    1637        2909 :     file->counter_total++;
    1638             : 
    1639             :     /* store position to next message */
    1640        2909 :     file->file_position = ftell(file->handle);
    1641             : 
    1642        2909 :     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        3965 : DltReturnValue dlt_file_message(DltFile *file, int index, int verbose)
    1737             : {
    1738        3965 :     PRINT_FUNCTION_VERBOSE(verbose);
    1739             : 
    1740        3965 :     if (file == NULL)
    1741             :         return DLT_RETURN_WRONG_PARAMETER;
    1742             : 
    1743             :     /* check if message is in range */
    1744        3965 :     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        3965 :     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        3965 :     if (dlt_file_read_header(file, verbose) < DLT_RETURN_OK)
    1758             :         return DLT_RETURN_ERROR;
    1759             : 
    1760        3965 :     if (dlt_file_read_header_extended(file, verbose) < DLT_RETURN_OK)
    1761             :         return DLT_RETURN_ERROR;
    1762             : 
    1763        3965 :     if (dlt_file_read_data(file, verbose) < DLT_RETURN_OK)
    1764             :         return DLT_RETURN_ERROR;
    1765             : 
    1766             :     /* set current position in file */
    1767        3965 :     file->position = index;
    1768             : 
    1769        3965 :     return DLT_RETURN_OK;
    1770             : }
    1771             : 
    1772          69 : DltReturnValue dlt_file_free(DltFile *file, int verbose)
    1773             : {
    1774          69 :     PRINT_FUNCTION_VERBOSE(verbose);
    1775             : 
    1776          69 :     if (file == NULL)
    1777             :         return DLT_RETURN_WRONG_PARAMETER;
    1778             : 
    1779             :     /* delete index lost if exists */
    1780          69 :     if (file->index)
    1781          54 :         free(file->index);
    1782             : 
    1783          69 :     file->index = NULL;
    1784             : 
    1785             :     /* close file */
    1786          69 :     if (file->handle)
    1787          59 :         fclose(file->handle);
    1788             : 
    1789          69 :     file->handle = NULL;
    1790             : 
    1791          69 :     return dlt_message_free(&(file->msg), verbose);
    1792             : }
    1793             : 
    1794             : #if defined DLT_DAEMON_USE_FIFO_IPC || defined DLT_LIB_USE_FIFO_IPC
    1795       18468 : void dlt_log_set_fifo_basedir(const char *pipe_dir)
    1796             : {
    1797             :     strncpy(dltFifoBaseDir, pipe_dir, DLT_PATH_MAX);
    1798       18468 :     dltFifoBaseDir[DLT_PATH_MAX - 1] = 0;
    1799       18459 : }
    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       18501 : DltReturnValue dlt_receiver_init(DltReceiver *receiver, int fd, DltReceiverType type, int buffersize)
    1816             : {
    1817       18501 :     if (NULL == receiver)
    1818             :         return DLT_RETURN_WRONG_PARAMETER;
    1819             : 
    1820       18501 :     receiver->fd = fd;
    1821       18501 :     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       18501 :     if ((NULL != receiver->buffer) && ( buffersize != receiver->buffersize)) {
    1827           0 :        free(receiver->buffer);
    1828           0 :        receiver->buffer = NULL;
    1829             :     }
    1830             : 
    1831       18501 :     if (NULL == receiver->buffer) {
    1832       18501 :         receiver->lastBytesRcvd = 0;
    1833       18501 :         receiver->bytesRcvd = 0;
    1834       18501 :         receiver->totalBytesRcvd = 0;
    1835       18501 :         receiver->buf = NULL;
    1836       18501 :         receiver->backup_buf = NULL;
    1837       18501 :         receiver->buffer = (char *)calloc(1, (size_t)buffersize);
    1838       18501 :         receiver->buffersize = (uint32_t)buffersize;
    1839             :     }
    1840             : 
    1841       18501 :     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       18501 :         receiver->buf = receiver->buffer;
    1847             :     }
    1848             : 
    1849       18501 :     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       18500 : DltReturnValue dlt_receiver_free(DltReceiver *receiver)
    1881             : {
    1882             : 
    1883       18500 :     if (receiver == NULL)
    1884             :         return DLT_RETURN_WRONG_PARAMETER;
    1885             : 
    1886       18500 :     if (receiver->buffer)
    1887       18498 :         free(receiver->buffer);
    1888             : 
    1889       18500 :     if (receiver->backup_buf)
    1890           0 :         free(receiver->backup_buf);
    1891             : 
    1892       18500 :     receiver->buffer = NULL;
    1893       18500 :     receiver->buf = NULL;
    1894       18500 :     receiver->backup_buf = NULL;
    1895             : 
    1896       18500 :     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        1745 : int dlt_receiver_receive(DltReceiver *receiver)
    1916             : {
    1917             :     socklen_t addrlen;
    1918             : 
    1919        1745 :     if (receiver == NULL)
    1920             :         return -1;
    1921             : 
    1922        1745 :     if (receiver->buffer == NULL)
    1923             :         return -1;
    1924             : 
    1925        1744 :     receiver->buf = (char *)receiver->buffer;
    1926        1744 :     receiver->lastBytesRcvd = receiver->bytesRcvd;
    1927             : 
    1928        1744 :     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        1744 :     if (receiver->type == DLT_RECEIVE_SOCKET)
    1935             :         /* wait for data from socket */
    1936         429 :         receiver->bytesRcvd = recv(receiver->fd,
    1937         429 :                                    receiver->buf + receiver->lastBytesRcvd,
    1938         429 :                                    receiver->buffersize - (uint32_t) receiver->lastBytesRcvd,
    1939             :                                    0);
    1940        1315 :     else if (receiver->type == DLT_RECEIVE_FD)
    1941             :         /* wait for data from fd */
    1942        1315 :         receiver->bytesRcvd = read(receiver->fd,
    1943        1315 :                                    receiver->buf + receiver->lastBytesRcvd,
    1944        1315 :                                    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        1744 :     if (receiver->bytesRcvd <= 0) {
    1958           6 :         receiver->bytesRcvd = 0;
    1959           6 :         return receiver->bytesRcvd;
    1960             :     } /* if */
    1961             : 
    1962        1738 :     receiver->totalBytesRcvd += receiver->bytesRcvd;
    1963        1738 :     receiver->bytesRcvd += receiver->lastBytesRcvd;
    1964             : 
    1965        1738 :     return receiver->bytesRcvd;
    1966             : }
    1967             : 
    1968        6098 : DltReturnValue dlt_receiver_remove(DltReceiver *receiver, int size)
    1969             : {
    1970        6098 :     if (receiver == NULL)
    1971             :         return DLT_RETURN_WRONG_PARAMETER;
    1972             : 
    1973        6141 :     if (receiver->buf == NULL)
    1974             :         return DLT_RETURN_ERROR;
    1975             : 
    1976        6141 :     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        6141 :     receiver->bytesRcvd = receiver->bytesRcvd - size;
    1983         263 :     receiver->buf = receiver->buf + size;
    1984             : 
    1985        6098 :     return DLT_RETURN_OK;
    1986             : }
    1987             : 
    1988        1739 : DltReturnValue dlt_receiver_move_to_begin(DltReceiver *receiver)
    1989             : {
    1990        1739 :     if (receiver == NULL)
    1991             :         return DLT_RETURN_WRONG_PARAMETER;
    1992             : 
    1993        1739 :     if ((receiver->buffer == NULL) || (receiver->buf == NULL))
    1994             :         return DLT_RETURN_ERROR;
    1995             : 
    1996        1739 :     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       12104 : DltReturnValue dlt_set_storageheader(DltStorageHeader *storageheader, const char *ecu)
    2045             : {
    2046             : 
    2047             : #if !defined(_MSC_VER)
    2048             :     struct timeval tv;
    2049             : #endif
    2050             : 
    2051       12104 :     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       12104 :     gettimeofday(&tv, NULL);
    2059             : #endif
    2060             : 
    2061             :     /* prepare storage header */
    2062       12104 :     storageheader->pattern[0] = 'D';
    2063       12104 :     storageheader->pattern[1] = 'L';
    2064       12104 :     storageheader->pattern[2] = 'T';
    2065       12104 :     storageheader->pattern[3] = 0x01;
    2066             : 
    2067       12104 :     dlt_set_id(storageheader->ecu, ecu);
    2068             : 
    2069             :     /* Set current time */
    2070             : #if defined(_MSC_VER)
    2071             :     storageheader->microseconds = 0;
    2072             : #else
    2073       12104 :     storageheader->seconds = (uint32_t) tv.tv_sec; /* value is long */
    2074       12104 :     storageheader->microseconds = (int32_t) tv.tv_usec; /* value is long */
    2075             : #endif
    2076             : 
    2077       12104 :     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        6979 : DltReturnValue dlt_check_storageheader(DltStorageHeader *storageheader)
    2092             : {
    2093        6979 :     if (storageheader == NULL)
    2094             :         return DLT_RETURN_WRONG_PARAMETER;
    2095             : 
    2096       13958 :     return ((storageheader->pattern[0] == 'D') &&
    2097        6979 :             (storageheader->pattern[1] == 'L') &&
    2098        6979 :             (storageheader->pattern[2] == 'T') &&
    2099        6979 :             (storageheader->pattern[3] == 1))
    2100       13958 :            ? 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       18589 : 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       18589 :     if (buf == NULL)
    2163             :         return DLT_RETURN_WRONG_PARAMETER;
    2164             : 
    2165             :     /* catch 0 logical errors */
    2166       18581 :     if ((min_size == 0) || (max_size == 0) || (step_size == 0))
    2167             :         return DLT_RETURN_WRONG_PARAMETER;
    2168             : 
    2169       18574 :     if (min_size > max_size)
    2170             :         return DLT_RETURN_WRONG_PARAMETER;
    2171             : 
    2172       18574 :     if (step_size > max_size)
    2173             :         return DLT_RETURN_WRONG_PARAMETER;
    2174             : 
    2175             :     /* Init parameters */
    2176       18574 :     buf->min_size = min_size;
    2177       18574 :     buf->max_size = max_size;
    2178       18574 :     buf->step_size = step_size;
    2179             : 
    2180             :     /* allocat memory */
    2181       18574 :     buf->shm = malloc(buf->min_size);
    2182             : 
    2183       18574 :     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       18574 :     head->read = 0;
    2193       18574 :     head->write = 0;
    2194       18574 :     head->count = 0;
    2195       18574 :     buf->mem = (unsigned char *)(buf->shm + sizeof(DltBufferHead));
    2196             : 
    2197       18574 :     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       18574 :     buf->size = (uint32_t) (buf->min_size - sizeof(DltBufferHead));
    2205             : 
    2206       18574 :     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       18574 :     memset(buf->mem, 0, (size_t)buf->size);
    2212             : 
    2213       18574 :     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       18564 : DltReturnValue dlt_buffer_free_dynamic(DltBuffer *buf)
    2232             : {
    2233             :     /* catch null pointer */
    2234       18564 :     if (buf == NULL)
    2235             :         return DLT_RETURN_WRONG_PARAMETER;
    2236             : 
    2237       18563 :     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       18563 :     free(buf->shm);
    2244       18563 :     buf->shm = NULL;
    2245       18563 :     buf->mem = NULL;
    2246             : 
    2247       18563 :     return DLT_RETURN_OK;
    2248             : }
    2249             : 
    2250       41034 : void dlt_buffer_write_block(DltBuffer *buf, int *write, const unsigned char *data, unsigned int size)
    2251             : {
    2252             :     /* catch null pointer */
    2253       41034 :     if ((buf != NULL) && (write != NULL) && (data != NULL)) {
    2254       40015 :         if (size <= buf->size){
    2255       40015 :             if (( (unsigned int) (*write ) + size) <= buf->size) {
    2256             :                 /* write one block */
    2257       40014 :                 memcpy(buf->mem + *write, data, size);
    2258       40014 :                 *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       41034 : }
    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         859 : int dlt_buffer_check_size(DltBuffer *buf, int needed)
    2308             : {
    2309         859 :     if (buf == NULL)
    2310             :         return DLT_RETURN_WRONG_PARAMETER;
    2311             : 
    2312         859 :     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       15285 : 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       15285 :     if (buf == NULL)
    2473             :         return DLT_RETURN_WRONG_PARAMETER;
    2474             : 
    2475       15217 :     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       15217 :     write = ((int *)(buf->shm))[0];
    2483       15217 :     read = ((int *)(buf->shm))[1];
    2484       15217 :     count = ((int *)(buf->shm))[2];
    2485             : 
    2486             :     /* check pointers */
    2487       15217 :     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       15217 :     if (read > write)
    2497           0 :         free_size = read - write;
    2498       15217 :     else if (count && (write == read))
    2499             :         free_size = 0;
    2500             :     else
    2501       15217 :         free_size = (int)buf->size - write + read;
    2502             : 
    2503             :     /* check size */
    2504       15221 :     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       15217 :     head.status = 2;
    2528       15217 :     head.size = (int)(size1 + size2 + size3);
    2529             : 
    2530             :     /* write data */
    2531       15217 :     dlt_buffer_write_block(buf, &write, (unsigned char *)&head, sizeof(DltBufferBlockHead));
    2532             : 
    2533       15217 :     if (size1)
    2534       15217 :         dlt_buffer_write_block(buf, &write, data1, size1);
    2535             : 
    2536       15217 :     if (size2)
    2537        7703 :         dlt_buffer_write_block(buf, &write, data2, size2);
    2538             : 
    2539       15217 :     if (size3)
    2540        1877 :         dlt_buffer_write_block(buf, &write, data3, size3);
    2541             : 
    2542             :     /* update global shm pointers */
    2543       15217 :     ((int *)(buf->shm))[0] = write; /* set new write pointer */
    2544       15217 :     ((int *)(buf->shm))[2] += 1; /* increase counter */
    2545             : 
    2546       15217 :     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          19 :     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        8528 : int dlt_buffer_get_message_count(DltBuffer *buf)
    2756             : {
    2757             :     /* catch null pointer */
    2758        8528 :     if (buf == NULL)
    2759             :         return DLT_RETURN_WRONG_PARAMETER;
    2760             : 
    2761             :     /* check if buffer available */
    2762        8528 :     if (buf->shm == NULL)
    2763             :         return DLT_RETURN_OK;
    2764             : 
    2765        8528 :     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           0 :         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           0 :     case  115200:
    2924             :     {
    2925             :         ret = B115200;
    2926           0 :         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           0 :     default:
    3004             :     {
    3005             :         ret = B115200;
    3006           0 :         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        3551 : 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        3551 :     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        3536 :     float32_t value32f = 0, value32f_tmp = 0;
    3186        3536 :     int32_t value32f_tmp_int32i = 0, value32f_tmp_int32i_swaped = 0;
    3187        3536 :     float64_t value64f = 0, value64f_tmp = 0;
    3188        3536 :     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        3536 :     if ((type_info & DLT_TYPE_INFO_STRG) &&
    3205        1549 :         (((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        1549 :         if (byteLength < 0) {
    3208        1549 :             DLT_MSG_READ_VALUE(value16u_tmp, *ptr, *datalength, uint16_t);
    3209             : 
    3210        1549 :             if ((*datalength) < 0)
    3211             :                 return DLT_RETURN_ERROR;
    3212             : 
    3213        1549 :             length = (uint16_t) DLT_ENDIAN_GET_16(msg->standardheader->htyp, value16u_tmp);
    3214             :         }
    3215             :         else {
    3216           0 :             length = (uint16_t)byteLength;
    3217             :         }
    3218             : 
    3219        1549 :         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        1549 :         DLT_MSG_READ_STRING(value_text, *ptr, *datalength, textlength, length);
    3244             : 
    3245        1549 :         if ((*datalength) < 0)
    3246             :             return DLT_RETURN_ERROR;
    3247             :     }
    3248        1987 :     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        1875 :     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        1875 :     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        1875 :     else if ((type_info & DLT_TYPE_INFO_SINT) || (type_info & DLT_TYPE_INFO_UINT))
    3371             :     {
    3372             :         /* signed or unsigned argument received */
    3373        1748 :         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        1748 :         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        1748 :         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        1699 :         case DLT_TYLE_32BIT:
    3508             :         {
    3509        1699 :             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        1412 :                 DLT_MSG_READ_VALUE(value32u_tmp, *ptr, *datalength, uint32_t);
    3524             : 
    3525        1412 :                 if ((*datalength) < 0)
    3526             :                     return DLT_RETURN_ERROR;
    3527             : 
    3528        1412 :                 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        3430 :     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        3430 :     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       18459 : void dlt_check_envvar()
    3809             : {
    3810       18459 :     char *env_log_filename = getenv("DLT_LOG_FILENAME");
    3811             : 
    3812       18459 :     if (env_log_filename != NULL)
    3813           0 :         dlt_log_set_filename(env_log_filename);
    3814             : 
    3815       18459 :     char *env_log_level_str = getenv("DLT_LOG_LEVEL");
    3816             : 
    3817       18459 :     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       18459 :     char *env_log_mode = getenv("DLT_LOG_MODE");
    3825             : 
    3826       18459 :     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       18459 :     char *env_pipe_dir = getenv("DLT_PIPE_DIR");
    3835             : 
    3836       18459 :     if (env_pipe_dir != NULL)
    3837           0 :         dlt_log_set_fifo_basedir(env_pipe_dir);
    3838             :     else
    3839       18459 :         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       18459 : }
    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 1.14