LCOV - code coverage report
Current view: top level - shared - dlt_common.c (source / functions) Coverage Total Hit
Test: dlt_final_coverage.info Lines: 46.5 % 2587 1204
Test Date: 2026-08-27 10:11:10 Functions: 79.7 % 128 102

            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(), clock_gettime() */
      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              : #ifndef CLOCK_REALTIME
      55              : #define CLOCK_REALTIME 0
      56              : #endif
      57              : #ifndef CLOCK_MONOTONIC
      58              : #define CLOCK_MONOTONIC 1
      59              : #endif
      60              : #endif
      61              : 
      62              : #if defined(_MSC_VER)
      63              : #include <io.h>
      64              : #else
      65              : #include <unistd.h> /* for read(), close() */
      66              : #include <fcntl.h>
      67              : #include <sys/time.h> /* for gettimeofday() */
      68              : #endif
      69              : 
      70              : #if defined(__MSDOS__) || defined(_MSC_VER)
      71              : #pragma warning(disable : 4996) /* Switch off C4996 warnings */
      72              : #include <windows.h>
      73              : #include <winbase.h>
      74              : #endif
      75              : 
      76              : #define MSGCONTENT_MASK 0x03
      77              : 
      78              : const char dltSerialHeader[DLT_ID_SIZE] = {'D', 'L', 'S', 1};
      79              : char dltSerialHeaderChar[DLT_ID_SIZE] = {'D', 'L', 'S', 1};
      80              : 
      81              : #if defined DLT_DAEMON_USE_FIFO_IPC || defined DLT_LIB_USE_FIFO_IPC
      82              : char dltFifoBaseDir[DLT_PATH_MAX] = "/tmp";
      83              : #endif
      84              : 
      85              : #ifdef DLT_SHM_ENABLE
      86              : char dltShmName[NAME_MAX + 1] = "/dlt-shm";
      87              : #endif
      88              : 
      89              : static bool print_with_attributes = false;
      90              : 
      91              : char* message_type[] = {"log", "app_trace", "nw_trace", "control", "", "", "", ""};
      92              : char* log_info[] = {"", "fatal", "error", "warn", "info", "debug", "verbose", "", "", "", "", "", "", "", "", ""};
      93              : char* trace_type[] = {"", "variable", "func_in", "func_out", "state", "vfb", "", "", "", "", "", "", "", "", "", ""};
      94              : char* nw_trace_type[] = {"", "ipc", "can", "flexray", "most", "vfb", "", "", "", "", "", "", "", "", "", ""};
      95              : char* control_type[] = {"", "request", "response", "time", "", "", "", "", "", "", "", "", "", "", "", ""};
      96              : static char* service_id_name[] = {
      97              :     "",
      98              :     "set_log_level",
      99              :     "set_trace_status",
     100              :     "get_log_info",
     101              :     "get_default_log_level",
     102              :     "store_config",
     103              :     "reset_to_factory_default",
     104              :     "set_com_interface_status",
     105              :     "set_com_interface_max_bandwidth",
     106              :     "set_verbose_mode",
     107              :     "set_message_filtering",
     108              :     "set_timing_packets",
     109              :     "get_local_time",
     110              :     "use_ecu_id",
     111              :     "use_session_id",
     112              :     "use_timestamp",
     113              :     "use_extended_header",
     114              :     "set_default_log_level",
     115              :     "set_default_trace_status",
     116              :     "get_software_version",
     117              :     "message_buffer_overflow"};
     118              : static char* return_type[] = {
     119              :     "ok", "not_supported", "error", "perm_denied", "warning", "", "", "", "no_matching_context_id"};
     120              : 
     121              : /* internal function definitions */
     122              : int dlt_buffer_get(DltBuffer* buf, unsigned char* data, int max_size, int delete);
     123              : int dlt_buffer_reset(DltBuffer* buf);
     124              : int dlt_buffer_increase_size(DltBuffer* buf);
     125              : int dlt_buffer_minimize_size(DltBuffer* buf);
     126              : void dlt_buffer_write_block(DltBuffer* buf, int* write, const unsigned char* data, unsigned int size);
     127              : void dlt_buffer_read_block(DltBuffer* buf, int* read, unsigned char* data, unsigned int size);
     128              : 
     129              : static DltReturnValue dlt_message_get_extraparameters_from_recievedbuffer_v2(
     130              :     DltMessageV2* msg, uint8_t* buffer, DltHtyp2ContentType msgcontent);
     131              : DltReturnValue dlt_message_get_extendedparameters_from_recievedbuffer_v2(
     132              :     DltMessageV2* msg, uint8_t* buffer, DltHtyp2ContentType msgcontent);
     133              : 
     134              : #ifdef DLT_TRACE_LOAD_CTRL_ENABLE
     135              : static int32_t dlt_output_soft_limit_over_warning(
     136              :     DltTraceLoadSettings* tl_settings, DltLogInternal log_internal, void* log_params);
     137              : 
     138              : static int32_t dlt_output_hard_limit_warning(
     139              :     DltTraceLoadSettings* tl_settings, DltLogInternal log_internal, void* log_params);
     140              : 
     141              : static bool dlt_user_cleanup_window(DltTraceLoadStat* tl_stat);
     142              : 
     143              : static int32_t dlt_switch_slot_if_needed(
     144              :     DltTraceLoadSettings* tl_settings, DltLogInternal log_internal, void* log_internal_params, uint32_t timestamp);
     145              : 
     146              : static void dlt_record_trace_load(DltTraceLoadStat* const tl_stat, int32_t size);
     147              : static inline bool dlt_is_over_trace_load_soft_limit(DltTraceLoadSettings* tl_settings);
     148              : static inline bool dlt_is_over_trace_load_hard_limit(DltTraceLoadSettings* tl_settings, int size);
     149              : #endif
     150              : 
     151            0 : void dlt_print_hex(uint8_t* ptr, int size)
     152              : {
     153              :     int num;
     154              : 
     155            0 :     if (ptr == NULL)
     156              :         return;
     157              : 
     158            0 :     for (num = 0; num < size; num++) {
     159            0 :         if (num > 0)
     160            0 :             dlt_user_printf(" ");
     161              : 
     162            0 :         dlt_user_printf("%.2x", ((uint8_t*)ptr)[num]);
     163              :     }
     164              : }
     165              : 
     166         2742 : static DltReturnValue dlt_print_hex_string_delim(char* text, int textlength, uint8_t* ptr, int size, char delim)
     167              : {
     168              :     int num;
     169              : 
     170         2742 :     if ((ptr == NULL) || (text == NULL) || (textlength <= 0) || (size < 0) || (delim == '\0'))
     171              :         return DLT_RETURN_WRONG_PARAMETER;
     172              : 
     173              :     /* Length 3: AB_ , A is first digit of hex number, B is second digit of hex number, _ is space */
     174         2739 :     if (textlength < (size * 3)) {
     175            0 :         dlt_vlog(LOG_WARNING, "String does not fit hex data (available=%d, required=%d) !\n", textlength, size * 3);
     176            0 :         return DLT_RETURN_ERROR;
     177              :     }
     178              : 
     179        36622 :     for (num = 0; num < size; num++) {
     180        33883 :         if (num > 0) {
     181        31171 :             snprintf(text, 2, "%c", delim);
     182        31171 :             text++;
     183              :         }
     184              : 
     185        33883 :         snprintf(text, 3, "%.2x", ((uint8_t*)ptr)[num]);
     186        33883 :         text += 2; /* 2 chars */
     187              :     }
     188              : 
     189              :     return DLT_RETURN_OK;
     190              : }
     191              : 
     192         2733 : DltReturnValue dlt_print_hex_string(char* text, int textlength, uint8_t* ptr, int size)
     193              : {
     194         2733 :     return dlt_print_hex_string_delim(text, textlength, ptr, size, ' ');
     195              : }
     196              : 
     197         1066 : DltReturnValue dlt_print_mixed_string(char* text, int textlength, uint8_t* ptr, int size, int html)
     198              : {
     199              :     int required_size = 0;
     200              :     int lines, rest, i;
     201              : 
     202         1066 :     if ((ptr == NULL) || (text == NULL) || (textlength <= 0) || (size < 0))
     203              :         return DLT_RETURN_WRONG_PARAMETER;
     204              : 
     205              :     /* Check maximum required size and do a length check */
     206         1060 :     if (html == 0)
     207          530 :         required_size = (DLT_COMMON_HEX_LINELEN + (2 * DLT_COMMON_HEX_CHARS + (DLT_COMMON_HEX_CHARS - 1))
     208              :                          + DLT_COMMON_CHARLEN + DLT_COMMON_HEX_CHARS + DLT_COMMON_CHARLEN)
     209          530 :                         * ((size / DLT_COMMON_HEX_CHARS) + 1);
     210              :     /* Example: (8 chars line number + (2*16 chars + 15 spaces) + space + 16 ascii chars + CR) *
     211              :      * ((size/16) lines + extra line for the rest) */
     212              :     else
     213          530 :         required_size = (DLT_COMMON_HEX_LINELEN + (2 * DLT_COMMON_HEX_CHARS + (DLT_COMMON_HEX_CHARS - 1))
     214              :                          + DLT_COMMON_CHARLEN + DLT_COMMON_HEX_CHARS + 4 * DLT_COMMON_CHARLEN)
     215          530 :                         * ((size / DLT_COMMON_HEX_CHARS) + 1);
     216              : 
     217              :     /* Example: (8 chars line number + (2*16 chars + 15 spaces) + space + 16 ascii chars + 4 [HTML CR: <BR>]) *
     218              :      * ((size/16) lines + extra line for the rest) */
     219              : 
     220         1060 :     if (textlength < required_size) {
     221            0 :         dlt_vlog(
     222              :             LOG_WARNING, "String does not fit mixed data (available=%d, required=%d) !\n", textlength, required_size);
     223            0 :         return DLT_RETURN_ERROR;
     224              :     }
     225              : 
     226              :     /* print full lines */
     227         1740 :     for (lines = 0; lines < (size / DLT_COMMON_HEX_CHARS); lines++) {
     228              :         int ret = 0;
     229              :         /* Line number */
     230          680 :         ret = snprintf(text, DLT_COMMON_HEX_LINELEN + 1, "%.6x: ", (uint32_t)lines * DLT_COMMON_HEX_CHARS);
     231              : 
     232          680 :         if ((ret < 0) || (ret >= (DLT_COMMON_HEX_LINELEN + 1)))
     233            0 :             dlt_log(LOG_WARNING, "line was truncated\n");
     234              : 
     235          680 :         text += DLT_COMMON_HEX_LINELEN; /* 'XXXXXX: ' */
     236              : 
     237              :         /* Hex-Output */
     238              :         /* It is not required to decrement textlength, as it was already checked, that
     239              :          * there is enough space for the complete output */
     240          680 :         if (dlt_print_hex_string(
     241          680 :                 text, textlength, (uint8_t*)(ptr + (lines * DLT_COMMON_HEX_CHARS)), DLT_COMMON_HEX_CHARS)
     242              :             < DLT_RETURN_OK)
     243              :             return DLT_RETURN_ERROR;
     244          680 :         text += ((2 * DLT_COMMON_HEX_CHARS) + (DLT_COMMON_HEX_CHARS - 1)); /* 32 characters + 15 spaces */
     245              : 
     246              :         snprintf(text, 2, " ");
     247          680 :         text += DLT_COMMON_CHARLEN;
     248              : 
     249              :         /* Char-Output */
     250              :         /* It is not required to decrement textlength, as it was already checked, that
     251              :          * there is enough space for the complete output */
     252          680 :         if (dlt_print_char_string(
     253              :                 &text, textlength, (uint8_t*)(ptr + (lines * DLT_COMMON_HEX_CHARS)), DLT_COMMON_HEX_CHARS)
     254              :             < DLT_RETURN_OK)
     255              :             return DLT_RETURN_ERROR;
     256              : 
     257          680 :         if (html == 0) {
     258          340 :             snprintf(text, 2, "\n");
     259          340 :             text += DLT_COMMON_CHARLEN;
     260              :         } else {
     261          340 :             snprintf(text, 5, "<BR>");
     262          340 :             text += (4 * DLT_COMMON_CHARLEN);
     263              :         }
     264              :     }
     265              : 
     266              :     /* print partial line */
     267         1060 :     rest = size % DLT_COMMON_HEX_CHARS;
     268              : 
     269         1060 :     if (rest > 0) {
     270              :         /* Line number */
     271              :         int ret = 0;
     272          986 :         ret = snprintf(text, 9, "%.6x: ", (uint32_t)(size / DLT_COMMON_HEX_CHARS) * DLT_COMMON_HEX_CHARS);
     273              : 
     274          986 :         if ((ret < 0) || (ret >= 9))
     275            0 :             dlt_log(LOG_WARNING, "line number was truncated");
     276              : 
     277          986 :         text += DLT_COMMON_HEX_LINELEN; /* 'XXXXXX: ' */
     278              : 
     279              :         /* Hex-Output */
     280              :         /* It is not required to decrement textlength, as it was already checked, that
     281              :          * there is enough space for the complete output */
     282          986 :         if (dlt_print_hex_string(
     283          986 :                 text, textlength, (uint8_t*)(ptr + ((size / DLT_COMMON_HEX_CHARS) * DLT_COMMON_HEX_CHARS)), rest)
     284              :             < DLT_RETURN_OK)
     285              :             return DLT_RETURN_ERROR;
     286          986 :         text += 2 * rest + (rest - 1);
     287              : 
     288         9472 :         for (i = 0; i < (DLT_COMMON_HEX_CHARS - rest); i++) {
     289         8486 :             snprintf(text, 4, " xx");
     290         8486 :             text += (3 * DLT_COMMON_CHARLEN);
     291              :         }
     292              : 
     293          986 :         snprintf(text, 2, " ");
     294          986 :         text += DLT_COMMON_CHARLEN;
     295              : 
     296              :         /* Char-Output */
     297              :         /* It is not required to decrement textlength, as it was already checked, that
     298              :          * there is enough space for the complete output */
     299          986 :         if (dlt_print_char_string(
     300              :                 &text, textlength, (uint8_t*)(ptr + ((size / DLT_COMMON_HEX_CHARS) * DLT_COMMON_HEX_CHARS)), rest)
     301              :             < DLT_RETURN_OK)
     302              :             return DLT_RETURN_ERROR;
     303              :     }
     304              : 
     305              :     return DLT_RETURN_OK;
     306              : }
     307              : 
     308         1671 : DltReturnValue dlt_print_char_string(char** text, int textlength, uint8_t* ptr, int size)
     309              : {
     310              :     int num;
     311              : 
     312         1671 :     if ((text == NULL) || (ptr == NULL) || (*text == NULL) || (textlength <= 0) || (size < 0))
     313              :         return DLT_RETURN_WRONG_PARAMETER;
     314              : 
     315         1668 :     if (textlength < size) {
     316            0 :         dlt_vlog(LOG_WARNING, "String does not fit character data (available=%d, required=%d) !\n", textlength, size);
     317            0 :         return DLT_RETURN_WRONG_PARAMETER;
     318              :     }
     319              : 
     320        19879 :     for (num = 0; num < size; num++) {
     321        18211 :         if ((((char*)ptr)[num] < DLT_COMMON_ASCII_CHAR_SPACE) || (((char*)ptr)[num] > DLT_COMMON_ASCII_CHAR_TILDE)) {
     322        10314 :             snprintf(*text, 2, ".");
     323              :         } else {
     324              :             /* replace < with . */
     325         7897 :             if (((char*)ptr)[num] != DLT_COMMON_ASCII_CHAR_LT)
     326         7895 :                 snprintf(*text, 2, "%c", ((char*)ptr)[num]);
     327              :             else
     328            2 :                 snprintf(*text, 2, ".");
     329              :         }
     330              : 
     331        18211 :         (*text)++;
     332              :     }
     333              : 
     334              :     return DLT_RETURN_OK;
     335              : }
     336              : 
     337        27263 : size_t dlt_strnlen_s(const char* str, size_t maxsize)
     338              : {
     339        27263 :     if (str == NULL)
     340              :         return 0;
     341              : 
     342       133013 :     for (size_t i = 0; i < maxsize; ++i) {
     343       109089 :         if (str[i] == '\0')
     344         3340 :             return i;
     345              :     }
     346              :     return maxsize;
     347              : }
     348              : 
     349         5926 : void dlt_print_id(char* text, const char* id)
     350              : {
     351              :     /* check nullpointer */
     352         5926 :     if ((text == NULL) || (id == NULL))
     353              :         return;
     354              : 
     355              :     /* Initialize text */
     356              :     memset(text, '-', DLT_ID_SIZE);
     357              : 
     358         5923 :     text[DLT_ID_SIZE] = 0;
     359              : 
     360         5923 :     size_t len = dlt_strnlen_s(id, DLT_ID_SIZE);
     361              : 
     362              :     memcpy(text, id, len);
     363              : }
     364              : 
     365              : /* TODO: Do memcpy instead */
     366            0 : void dlt_print_id_v2(char* text, const char* id, uint8_t length)
     367              : {
     368              :     /* check nullpointer */
     369            0 :     if ((text == NULL) || (id == NULL) || (length == 0))
     370              :         return;
     371              : 
     372              :     /* Initialize text */
     373            0 :     memset(text, '-', length);
     374              : 
     375            0 :     text[length] = 0;
     376              : 
     377            0 :     size_t len = dlt_strnlen_s(id, length);
     378              : 
     379              :     memcpy(text, id, len);
     380              : }
     381              : 
     382        79758 : void dlt_set_id(char* id, const char* text)
     383              : {
     384              :     /* check nullpointer */
     385        79758 :     if ((id == NULL) || (text == NULL))
     386              :         return;
     387              : 
     388              :     memset(id, 0, DLT_ID_SIZE);
     389              : 
     390        79755 :     if (text[0] != 0)
     391        47727 :         id[0] = text[0];
     392              :     else
     393              :         return;
     394              : 
     395        47727 :     if (text[1] != 0)
     396        47721 :         id[1] = text[1];
     397              :     else
     398              :         return;
     399              : 
     400        47721 :     if (text[2] != 0)
     401        47713 :         id[2] = text[2];
     402              :     else
     403              :         return;
     404              : 
     405        47713 :     if (text[3] != 0)
     406        47580 :         id[3] = text[3];
     407              :     else
     408              :         return;
     409              : }
     410              : 
     411        21379 : void dlt_set_id_v2(char* id, const char* text, uint8_t len)
     412              : {
     413              :     /* check nullpointer */
     414        21379 :     if ((id == NULL) || (text == NULL) || (len == 0))
     415              :         return;
     416              : 
     417              :     /* cap length to destination buffer */
     418              :     if (len >= DLT_V2_ID_SIZE)
     419              :         len = DLT_V2_ID_SIZE;
     420              : 
     421              :     /* initialize id with zeros */
     422              :     memset(id, 0, DLT_V2_ID_SIZE);
     423              : 
     424              :     /* copy up to the actual text length (but not more than len) */
     425        21337 :     size_t copy_len = dlt_strnlen_s(text, (size_t)len);
     426        21337 :     if (copy_len > 0)
     427              :         memcpy(id, text, copy_len);
     428              : }
     429              : 
     430         1365 : void dlt_clean_string(char* text, int length)
     431              : {
     432              :     int num;
     433              : 
     434         1365 :     if (text == NULL)
     435              :         return;
     436              : 
     437        11934 :     for (num = 0; num < length; num++)
     438        10569 :         if ((text[num] == '\r') || (text[num] == '\n'))
     439            0 :             text[num] = ' ';
     440              : }
     441              : 
     442           12 : DltReturnValue dlt_filter_init(DltFilter* filter, int verbose)
     443              : {
     444           12 :     PRINT_FUNCTION_VERBOSE(verbose);
     445              : 
     446           12 :     if (filter == NULL)
     447              :         return DLT_RETURN_WRONG_PARAMETER;
     448              : 
     449           12 :     filter->counter = 0;
     450              : 
     451           12 :     return DLT_RETURN_OK;
     452              : }
     453              : 
     454            1 : DltReturnValue dlt_filter_free(DltFilter* filter, int verbose)
     455              : {
     456            1 :     PRINT_FUNCTION_VERBOSE(verbose);
     457              : 
     458            1 :     if (filter == NULL)
     459            0 :         return DLT_RETURN_WRONG_PARAMETER;
     460              : 
     461              :     return DLT_RETURN_OK;
     462              : }
     463              : 
     464            6 : DltReturnValue dlt_filter_load(DltFilter* filter, const char* filename, int verbose)
     465              : {
     466            6 :     if ((filter == NULL) || (filename == NULL))
     467              :         return DLT_RETURN_WRONG_PARAMETER;
     468              : 
     469              :     FILE* handle;
     470              :     char str1[DLT_COMMON_BUFFER_LENGTH + 1];
     471              :     char apid[DLT_ID_SIZE], ctid[DLT_ID_SIZE];
     472              : 
     473            6 :     PRINT_FUNCTION_VERBOSE(verbose);
     474              : 
     475            6 :     handle = fopen(filename, "r");
     476              : 
     477            6 :     if (handle == NULL) {
     478            0 :         dlt_vlog(LOG_WARNING, "Filter file %s cannot be opened!\n", filename);
     479            0 :         return DLT_RETURN_ERROR;
     480              :     }
     481              : 
     482              : #define FORMAT_STRING_(x) "%" #x "s"
     483              : #define FORMAT_STRING(x) FORMAT_STRING_(x)
     484              : 
     485              :     /* Reset filters */
     486            6 :     filter->counter = 0;
     487              : 
     488           18 :     while (!feof(handle)) {
     489           18 :         str1[0] = 0;
     490              : 
     491           18 :         if (fscanf(handle, FORMAT_STRING(DLT_COMMON_BUFFER_LENGTH), str1) != 1)
     492              :             break;
     493              : 
     494           12 :         if (str1[0] == 0)
     495              :             break;
     496              : 
     497              :         printf(" %s", str1);
     498              : 
     499           12 :         if (strcmp(str1, "----") == 0 || strcmp(str1, "*") == 0)
     500            0 :             dlt_set_id(apid, "");
     501              :         else
     502           12 :             dlt_set_id(apid, str1);
     503              : 
     504           12 :         str1[0] = 0;
     505              : 
     506           12 :         if (fscanf(handle, FORMAT_STRING(DLT_COMMON_BUFFER_LENGTH), str1) != 1)
     507              :             break;
     508              : 
     509           12 :         if (str1[0] == 0)
     510              :             break;
     511              : 
     512              :         printf(" %s\r\n", str1);
     513              : 
     514           12 :         if (strcmp(str1, "----") == 0)
     515            0 :             dlt_set_id(ctid, "");
     516              :         else
     517           12 :             dlt_set_id(ctid, str1);
     518              : 
     519           12 :         if (filter->counter < DLT_FILTER_MAX)
     520           12 :             dlt_filter_add(filter, apid, ctid, 0, 0, INT32_MAX, verbose);
     521              :         else
     522            0 :             dlt_vlog(
     523              :                 LOG_WARNING, "Maximum number (%d) of allowed filters reached, ignoring rest of filters!\n",
     524              :                 DLT_FILTER_MAX);
     525              :     }
     526              : 
     527            6 :     fclose(handle);
     528              : 
     529            6 :     return DLT_RETURN_OK;
     530              : }
     531              : 
     532            5 : DltReturnValue dlt_filter_load_v2(DltFilter* filter, const char* filename, int verbose)
     533              : {
     534            5 :     if ((filter == NULL) || (filename == NULL))
     535              :         return DLT_RETURN_WRONG_PARAMETER;
     536              : 
     537              :     FILE* handle;
     538              :     char str1[DLT_COMMON_BUFFER_LENGTH + 1];
     539              :     char apid[DLT_V2_ID_SIZE];
     540              :     char ctid[DLT_V2_ID_SIZE];
     541              :     uint8_t apidlen, ctidlen;
     542              : 
     543            5 :     PRINT_FUNCTION_VERBOSE(verbose);
     544              : 
     545            5 :     handle = fopen(filename, "r");
     546              : 
     547            5 :     if (handle == NULL) {
     548            0 :         dlt_vlog(LOG_WARNING, "Filter file %s cannot be opened!\n", filename);
     549            0 :         return DLT_RETURN_ERROR;
     550              :     }
     551              : 
     552              : #define FORMAT_STRING_(x) "%" #x "s"
     553              : #define FORMAT_STRING(x) FORMAT_STRING_(x)
     554              : 
     555              :     /* Reset filters */
     556            5 :     filter->counter = 0;
     557              : 
     558           15 :     while (!feof(handle)) {
     559           15 :         str1[0] = 0;
     560              : 
     561           15 :         if (fscanf(handle, FORMAT_STRING(DLT_COMMON_BUFFER_LENGTH), str1) != 1)
     562              :             break;
     563              : 
     564           10 :         if (str1[0] == 0)
     565              :             break;
     566              : 
     567              :         printf(" %s", str1);
     568              : 
     569           10 :         if (strcmp(str1, "----") == 0) {
     570              :             apidlen = 0;
     571              :         } else {
     572           10 :             apidlen = (uint8_t)strlen(str1);
     573           10 :             dlt_set_id_v2(apid, str1, apidlen);
     574              :         }
     575              : 
     576           10 :         str1[0] = 0;
     577              : 
     578           10 :         if (fscanf(handle, FORMAT_STRING(DLT_COMMON_BUFFER_LENGTH), str1) != 1)
     579              :             break;
     580              : 
     581           10 :         if (str1[0] == 0)
     582              :             break;
     583              : 
     584              :         printf(" %s\r\n", str1);
     585              : 
     586           10 :         if (strcmp(str1, "----") == 0) {
     587              :             ctidlen = 0;
     588              :         } else {
     589           10 :             ctidlen = (uint8_t)strlen(str1);
     590           10 :             dlt_set_id_v2(ctid, str1, ctidlen);
     591              :         }
     592              : 
     593           10 :         if (filter->counter < DLT_FILTER_MAX) {
     594           10 :             dlt_filter_add(filter, apid, ctid, 0, 0, INT32_MAX, verbose);
     595              :         } else {
     596            0 :             dlt_vlog(
     597              :                 LOG_WARNING, "Maximum number (%d) of allowed filters reached, ignoring rest of filters!\n",
     598              :                 DLT_FILTER_MAX);
     599              :         }
     600              :     }
     601              : 
     602            5 :     fclose(handle);
     603              : 
     604            5 :     return DLT_RETURN_OK;
     605              : }
     606              : 
     607            0 : DltReturnValue dlt_filter_save(DltFilter* filter, const char* filename, int verbose)
     608              : {
     609            0 :     if ((filter == NULL) || (filename == NULL))
     610              :         return DLT_RETURN_WRONG_PARAMETER;
     611              : 
     612              :     FILE* handle;
     613              :     int num;
     614              :     char buf[DLT_COMMON_BUFFER_LENGTH];
     615              : 
     616            0 :     PRINT_FUNCTION_VERBOSE(verbose);
     617              : 
     618            0 :     handle = fopen(filename, "w");
     619              : 
     620            0 :     if (handle == NULL) {
     621            0 :         dlt_vlog(LOG_WARNING, "Filter file %s cannot be opened!\n", filename);
     622            0 :         return DLT_RETURN_ERROR;
     623              :     }
     624              : 
     625            0 :     for (num = 0; num < filter->counter; num++) {
     626            0 :         if (filter->apid[num][0] == 0) {
     627              :             fprintf(handle, "---- ");
     628              :         } else {
     629            0 :             dlt_print_id(buf, filter->apid[num]);
     630              :             fprintf(handle, "%s ", buf);
     631              :         }
     632              : 
     633            0 :         if (filter->ctid[num][0] == 0) {
     634              :             fprintf(handle, "---- ");
     635              :         } else {
     636            0 :             dlt_print_id(buf, filter->ctid[num]);
     637              :             fprintf(handle, "%s ", buf);
     638              :         }
     639              :     }
     640              : 
     641            0 :     fclose(handle);
     642              : 
     643            0 :     return DLT_RETURN_OK;
     644              : }
     645              : 
     646            0 : DltReturnValue dlt_filter_save_v2(DltFilter* filter, const char* filename, int verbose)
     647              : {
     648            0 :     if ((filter == NULL) || (filename == NULL))
     649              :         return DLT_RETURN_WRONG_PARAMETER;
     650              : 
     651              :     FILE* handle;
     652              :     int num;
     653              :     char buf[DLT_COMMON_BUFFER_LENGTH];
     654              : 
     655            0 :     PRINT_FUNCTION_VERBOSE(verbose);
     656              : 
     657            0 :     handle = fopen(filename, "w");
     658              : 
     659            0 :     if (handle == NULL) {
     660            0 :         dlt_vlog(LOG_WARNING, "Filter file %s cannot be opened!\n", filename);
     661            0 :         return DLT_RETURN_ERROR;
     662              :     }
     663              : 
     664            0 :     for (num = 0; num < filter->counter; num++) {
     665            0 :         if (filter->apid2[num] == NULL) {
     666              :             fprintf(handle, "---- ");
     667              :         } else {
     668            0 :             memcpy(buf, filter->apid2[num], filter->apid2len[num]);
     669            0 :             memset(buf + (filter->ctid2len[num]), '\0', 1);
     670              :             fprintf(handle, "%s ", buf);
     671              :         }
     672              : 
     673            0 :         if (filter->ctid2[num] == NULL) {
     674              :             fprintf(handle, "---- ");
     675              :         } else {
     676            0 :             memcpy(buf, filter->ctid2[num], filter->ctid2len[num]);
     677            0 :             memset(buf + (filter->ctid2len[num]), '\0', 1);
     678              :             fprintf(handle, "%s ", buf);
     679              :         }
     680              :     }
     681              : 
     682            0 :     fclose(handle);
     683              : 
     684            0 :     return DLT_RETURN_OK;
     685              : }
     686              : 
     687           22 : int dlt_filter_find(
     688              :     DltFilter* filter, const char* apid, const char* ctid, const int log_level, const int32_t payload_min,
     689              :     const int32_t payload_max, int verbose)
     690              : {
     691              :     int num;
     692              : 
     693           22 :     PRINT_FUNCTION_VERBOSE(verbose);
     694              : 
     695           22 :     if ((filter == NULL) || (apid == NULL))
     696              :         return -1;
     697              : 
     698           33 :     for (num = 0; num < filter->counter; num++)
     699           11 :         if (memcmp(filter->apid[num], apid, DLT_ID_SIZE) == 0) {
     700              :             /* apid matches, now check for ctid */
     701            0 :             if (ctid == NULL) {
     702              :                 /* check if empty ctid matches */
     703              :                 /*if (memcmp(filter->ctid[num],"",DLT_ID_SIZE)==0)//coverity complains here about Out-of-bounds access.
     704              :                  */
     705            0 :                 char empty_ctid[DLT_ID_SIZE] = "";
     706              : 
     707            0 :                 if (memcmp(filter->ctid[num], empty_ctid, DLT_ID_SIZE) == 0)
     708            0 :                     if ((filter->log_level[num] == log_level) || (filter->log_level[num] == 0))
     709            0 :                         if (filter->payload_min[num] <= payload_min)
     710            0 :                             if (filter->payload_max[num] >= payload_max)
     711            0 :                                 return num;
     712            0 :             } else if (memcmp(filter->ctid[num], ctid, DLT_ID_SIZE) == 0) {
     713            0 :                 if ((filter->log_level[num] == log_level) || (filter->log_level[num] == 0))
     714            0 :                     if (filter->payload_min[num] <= payload_min)
     715            0 :                         if (filter->payload_max[num] >= payload_max)
     716            0 :                             return num;
     717              :             }
     718              :         }
     719              : 
     720              :     return -1; /* Not found */
     721              : }
     722              : 
     723            0 : int dlt_filter_find_v2(
     724              :     DltFilter* filter, const char* apid, const char* ctid, const int log_level, const int32_t payload_min,
     725              :     const int32_t payload_max, int verbose)
     726              : {
     727              :     int num;
     728              : 
     729            0 :     PRINT_FUNCTION_VERBOSE(verbose);
     730              : 
     731            0 :     if ((filter == NULL) || (apid == NULL))
     732              :         return -1;
     733              : 
     734            0 :     for (num = 0; num < filter->counter; num++)
     735            0 :         if (memcmp(filter->apid2[num], apid, filter->apid2len[num]) == 0) {
     736              :             /* apid matches, now check for ctid */
     737            0 :             if (ctid == NULL) {
     738              :                 /* check if empty ctid matches */
     739              : 
     740            0 :                 if (filter->ctid2[num] == NULL)
     741            0 :                     if ((filter->log_level[num] == log_level) || (filter->log_level[num] == 0))
     742            0 :                         if (filter->payload_min[num] <= payload_min)
     743            0 :                             if (filter->payload_max[num] >= payload_max)
     744            0 :                                 return num;
     745            0 :             } else if (memcmp(filter->ctid2[num], ctid, filter->ctid2len[num]) == 0) {
     746            0 :                 if ((filter->log_level[num] == log_level) || (filter->log_level[num] == 0))
     747            0 :                     if (filter->payload_min[num] <= payload_min)
     748            0 :                         if (filter->payload_max[num] >= payload_max)
     749            0 :                             return num;
     750              :             }
     751              :         }
     752              : 
     753              :     return -1; /* Not found */
     754              : }
     755              : 
     756           22 : DltReturnValue dlt_filter_add(
     757              :     DltFilter* filter, const char* apid, const char* ctid, const int log_level, const int32_t payload_min,
     758              :     const int32_t payload_max, int verbose)
     759              : {
     760           22 :     PRINT_FUNCTION_VERBOSE(verbose);
     761              : 
     762           22 :     if ((filter == NULL) || (apid == NULL))
     763              :         return DLT_RETURN_WRONG_PARAMETER;
     764              : 
     765           22 :     if (filter->counter >= DLT_FILTER_MAX) {
     766            0 :         dlt_vlog(LOG_WARNING, "Maximum number (%d) of allowed filters reached, ignoring filter!\n", DLT_FILTER_MAX);
     767            0 :         return DLT_RETURN_ERROR;
     768              :     }
     769              : 
     770              :     /* add each filter (apid, ctid, log_level, payload_min, payload_max) only once to filter array */
     771           22 :     if (dlt_filter_find(filter, apid, ctid, log_level, payload_min, payload_max, verbose) < 0) {
     772              :         /* filter not found, so add it to filter array */
     773           22 :         dlt_set_id(filter->apid[filter->counter], apid);
     774           22 :         dlt_set_id(filter->ctid[filter->counter], (ctid ? ctid : ""));
     775           22 :         filter->log_level[filter->counter] = log_level;
     776           22 :         filter->payload_min[filter->counter] = payload_min;
     777           22 :         filter->payload_max[filter->counter] = payload_max;
     778              : 
     779           22 :         filter->counter++;
     780              : 
     781           22 :         return DLT_RETURN_OK;
     782              :     }
     783              : 
     784              :     return DLT_RETURN_ERROR;
     785              : }
     786              : 
     787            0 : DltReturnValue dlt_filter_add_v2(
     788              :     DltFilter* filter, const char* apid, const char* ctid, const int log_level, const int32_t payload_min,
     789              :     const int32_t payload_max, int verbose)
     790              : {
     791            0 :     PRINT_FUNCTION_VERBOSE(verbose);
     792              : 
     793            0 :     if ((filter == NULL) || (apid == NULL))
     794              :         return DLT_RETURN_WRONG_PARAMETER;
     795              : 
     796            0 :     if (filter->counter >= DLT_FILTER_MAX) {
     797            0 :         dlt_vlog(LOG_WARNING, "Maximum number (%d) of allowed filters reached, ignoring filter!\n", DLT_FILTER_MAX);
     798            0 :         return DLT_RETURN_ERROR;
     799              :     }
     800              : 
     801              :     /* add each filter (apid, ctid, log_level, payload_min, payload_max) only once to filter array */
     802            0 :     if (dlt_filter_find(filter, apid, ctid, log_level, payload_min, payload_max, verbose) < 0) {
     803              :         /* filter not found, so add it to filter array */
     804            0 :         filter->apid2[filter->counter] = (char*)malloc(DLT_V2_ID_SIZE * sizeof(char));
     805            0 :         if (filter->apid2[filter->counter] == NULL) {
     806              :             return DLT_RETURN_ERROR;
     807              :         }
     808            0 :         filter->ctid2[filter->counter] = (char*)malloc(DLT_V2_ID_SIZE * sizeof(char));
     809            0 :         if (filter->ctid2[filter->counter] == NULL) {
     810            0 :             free(filter->apid2[filter->counter]);
     811            0 :             filter->apid2[filter->counter] = NULL;
     812            0 :             return DLT_RETURN_ERROR;
     813              :         }
     814            0 :         filter->apid2len[filter->counter] = (uint8_t)strlen(apid);
     815            0 :         dlt_set_id_v2(filter->apid2[filter->counter], apid, filter->apid2len[filter->counter]);
     816            0 :         filter->ctid2len[filter->counter] = (uint8_t)strlen(ctid);
     817            0 :         dlt_set_id_v2(filter->ctid2[filter->counter], (ctid ? ctid : NULL), filter->ctid2len[filter->counter]);
     818            0 :         filter->log_level[filter->counter] = log_level;
     819            0 :         filter->payload_min[filter->counter] = payload_min;
     820            0 :         filter->payload_max[filter->counter] = payload_max;
     821              : 
     822            0 :         filter->counter++;
     823              : 
     824            0 :         return DLT_RETURN_OK;
     825              :     }
     826              : 
     827              :     return DLT_RETURN_ERROR;
     828              : }
     829              : 
     830            0 : DltReturnValue dlt_filter_delete(
     831              :     DltFilter* filter, const char* apid, const char* ctid, const int log_level, const int32_t payload_min,
     832              :     const int32_t payload_max, int verbose)
     833              : {
     834              :     int j, k;
     835              :     int found = 0;
     836              : 
     837            0 :     PRINT_FUNCTION_VERBOSE(verbose);
     838              : 
     839            0 :     if ((filter == NULL) || (apid == NULL) || (ctid == NULL))
     840              :         return DLT_RETURN_WRONG_PARAMETER;
     841              : 
     842            0 :     if (filter->counter > 0) {
     843              :         /* Get first occurence of apid and ctid in filter array */
     844            0 :         for (j = 0; j < filter->counter; j++)
     845            0 :             if ((memcmp(filter->apid[j], apid, DLT_ID_SIZE) == 0) && (memcmp(filter->ctid[j], ctid, DLT_ID_SIZE) == 0)
     846            0 :                 && ((filter->log_level[j] == log_level) || (filter->log_level[j] == 0))
     847            0 :                 && (filter->payload_min[j] == payload_min) && (filter->payload_max[j] == payload_max)) {
     848              :                 found = 1;
     849              :                 break;
     850              :             }
     851              : 
     852            0 :         if (found) {
     853              :             /* j is index */
     854              :             /* Copy from j+1 til end to j til end-1 */
     855              : 
     856            0 :             dlt_set_id(filter->apid[j], "");
     857            0 :             dlt_set_id(filter->ctid[j], "");
     858            0 :             filter->log_level[j] = 0;
     859            0 :             filter->payload_min[j] = 0;
     860            0 :             filter->payload_max[j] = INT32_MAX;
     861              : 
     862            0 :             for (k = j; k < (filter->counter - 1); k++) {
     863            0 :                 dlt_set_id(filter->apid[k], filter->apid[k + 1]);
     864            0 :                 dlt_set_id(filter->ctid[k], filter->ctid[k + 1]);
     865            0 :                 filter->log_level[k] = filter->log_level[k + 1];
     866            0 :                 filter->payload_min[k] = filter->payload_min[k + 1];
     867            0 :                 filter->payload_max[k] = filter->payload_max[k + 1];
     868              :             }
     869              : 
     870            0 :             filter->counter--;
     871            0 :             return DLT_RETURN_OK;
     872              :         }
     873              :     }
     874              : 
     875              :     return DLT_RETURN_ERROR;
     876              : }
     877              : 
     878            0 : DltReturnValue dlt_filter_delete_v2(
     879              :     DltFilter* filter, const char* apid, const char* ctid, const int log_level, const int32_t payload_min,
     880              :     const int32_t payload_max, int verbose)
     881              : {
     882              :     int j, k;
     883              :     int found = 0;
     884              : 
     885            0 :     PRINT_FUNCTION_VERBOSE(verbose);
     886              : 
     887            0 :     if ((filter == NULL) || (apid == NULL) || (ctid == NULL))
     888              :         return DLT_RETURN_WRONG_PARAMETER;
     889              : 
     890            0 :     if (filter->counter > 0) {
     891              :         /* Get first occurence of apid and ctid in filter array */
     892            0 :         for (j = 0; j < filter->counter; j++)
     893            0 :             if ((memcmp(filter->apid2[j], apid, filter->apid2len[j]) == 0)
     894            0 :                 && (memcmp(filter->ctid2[j], ctid, filter->ctid2len[j]) == 0)
     895            0 :                 && ((filter->log_level[j] == log_level) || (filter->log_level[j] == 0))
     896            0 :                 && (filter->payload_min[j] == payload_min) && (filter->payload_max[j] == payload_max)) {
     897              :                 found = 1;
     898              :                 break;
     899              :             }
     900              : 
     901            0 :         if (found) {
     902              :             /* j is index */
     903              :             /* Copy from j+1 til end to j til end-1 */
     904              : 
     905            0 :             filter->apid2len[j] = 0;
     906            0 :             free(filter->apid2[j]);
     907            0 :             filter->apid2[j] = NULL;
     908            0 :             filter->ctid2len[j] = 0;
     909            0 :             free(filter->ctid2[j]);
     910            0 :             filter->ctid2[j] = NULL;
     911            0 :             filter->log_level[j] = 0;
     912            0 :             filter->payload_min[j] = 0;
     913            0 :             filter->payload_max[j] = INT32_MAX;
     914              : 
     915            0 :             for (k = j; k < (filter->counter - 1); k++) {
     916            0 :                 filter->apid2len[k] = filter->apid2len[k + 1];
     917            0 :                 dlt_set_id_v2(filter->apid2[k], filter->apid2[k + 1], filter->apid2len[k + 1]);
     918            0 :                 filter->ctid2len[k] = filter->ctid2len[k + 1];
     919            0 :                 dlt_set_id_v2(filter->ctid2[k], filter->ctid2[k + 1], filter->ctid2len[k + 1]);
     920            0 :                 filter->log_level[k] = filter->log_level[k + 1];
     921            0 :                 filter->payload_min[k] = filter->payload_min[k + 1];
     922            0 :                 filter->payload_max[k] = filter->payload_max[k + 1];
     923              :             }
     924              : 
     925            0 :             filter->apid2len[filter->counter] = 0;
     926            0 :             free(filter->apid2[filter->counter]);
     927            0 :             filter->apid2[filter->counter] = NULL;
     928            0 :             filter->ctid2len[filter->counter] = 0;
     929            0 :             free(filter->ctid2[filter->counter]);
     930            0 :             filter->ctid2[filter->counter] = NULL;
     931              : 
     932            0 :             filter->counter--;
     933            0 :             return DLT_RETURN_OK;
     934              :         }
     935              :     }
     936              : 
     937              :     return DLT_RETURN_ERROR;
     938              : }
     939              : 
     940              : 
     941         6058 : DltReturnValue dlt_message_init(DltMessage* msg, int verbose)
     942              : {
     943         6058 :     PRINT_FUNCTION_VERBOSE(verbose);
     944              : 
     945         6058 :     if (msg == NULL)
     946              :         return DLT_RETURN_WRONG_PARAMETER;
     947              : 
     948              :     /* initalise structure parameters */
     949         6054 :     msg->headersize = 0;
     950         6054 :     msg->datasize = 0;
     951              : 
     952         6054 :     msg->databuffer = NULL;
     953         6054 :     msg->databuffersize = 0;
     954              : 
     955         6054 :     msg->storageheader = NULL;
     956         6054 :     msg->standardheader = NULL;
     957         6054 :     msg->extendedheader = NULL;
     958              : 
     959         6054 :     msg->found_serialheader = 0;
     960              : 
     961         6054 :     return DLT_RETURN_OK;
     962              : }
     963              : 
     964           48 : DltReturnValue dlt_message_init_v2(DltMessageV2* msg, int verbose)
     965              : {
     966           48 :     PRINT_FUNCTION_VERBOSE(verbose);
     967              : 
     968           48 :     if (msg == NULL)
     969              :         return DLT_RETURN_WRONG_PARAMETER;
     970              : 
     971              :     /* initalise structure parameters */
     972           46 :     msg->headerbufferv2 = NULL;
     973           46 :     msg->headersizev2 = 0;
     974           46 :     msg->datasize = 0;
     975              : 
     976           46 :     msg->databuffer = NULL;
     977           46 :     msg->databuffersize = 0;
     978              : 
     979           46 :     memset(&(msg->storageheaderv2), 0, sizeof(msg->storageheaderv2));
     980           46 :     memset(&(msg->extendedheaderv2), 0, sizeof(msg->extendedheaderv2));
     981           46 :     msg->baseheaderv2 = NULL;
     982           46 :     msg->found_serialheader = 0;
     983           46 :     return DLT_RETURN_OK;
     984              : }
     985              : 
     986           55 : DltReturnValue dlt_message_free(DltMessage* msg, int verbose)
     987              : {
     988           55 :     PRINT_FUNCTION_VERBOSE(verbose);
     989              : 
     990           55 :     if (msg == NULL)
     991              :         return DLT_RETURN_WRONG_PARAMETER;
     992              : 
     993              :     /* delete databuffer if exists */
     994           53 :     if (msg->databuffer) {
     995           40 :         free(msg->databuffer);
     996           40 :         msg->databuffer = NULL;
     997           40 :         msg->databuffersize = 0;
     998              :     }
     999              : 
    1000              :     return DLT_RETURN_OK;
    1001              : }
    1002              : 
    1003           26 : DltReturnValue dlt_message_free_v2(DltMessageV2* msg, int verbose)
    1004              : {
    1005           26 :     PRINT_FUNCTION_VERBOSE(verbose);
    1006              : 
    1007           26 :     if (msg == NULL)
    1008              :         return DLT_RETURN_WRONG_PARAMETER;
    1009              : 
    1010              :     /* delete headerbuffer if exists */
    1011           24 :     if (msg->headerbufferv2) {
    1012            2 :         free(msg->headerbufferv2);
    1013            2 :         msg->headerbufferv2 = NULL;
    1014            2 :         msg->headersizev2 = 0;
    1015              :     }
    1016              : 
    1017              :     /* delete tags if exists */
    1018           24 :     if (msg->extendedheaderv2.tag) {
    1019            0 :         free(msg->extendedheaderv2.tag);
    1020            0 :         msg->extendedheaderv2.tag = NULL;
    1021              :     }
    1022              : 
    1023              :     /* delete databuffer if exists */
    1024           24 :     if (msg->databuffer) {
    1025            0 :         free(msg->databuffer);
    1026            0 :         msg->databuffer = NULL;
    1027            0 :         msg->databuffersize = 0;
    1028              :     }
    1029              : 
    1030              :     /* delete tags if exists */
    1031           24 :     if (msg->extendedheaderv2.tag) {
    1032            0 :         free(msg->extendedheaderv2.tag);
    1033            0 :         msg->extendedheaderv2.tag = NULL;
    1034            0 :         msg->extendedheaderv2.notg = 0;
    1035              :     }
    1036              : 
    1037              :     return DLT_RETURN_OK;
    1038              : }
    1039              : 
    1040         2522 : DltReturnValue dlt_message_header(DltMessage* msg, char* text, size_t textlength, int verbose)
    1041              : {
    1042         2522 :     return dlt_message_header_flags(msg, text, textlength, DLT_HEADER_SHOW_ALL, verbose);
    1043              : }
    1044              : 
    1045           14 : DltReturnValue dlt_message_header_v2(DltMessageV2* msg, char* text, size_t textlength, int verbose)
    1046              : {
    1047           14 :     return dlt_message_header_flags_v2(msg, text, textlength, DLT_HEADER_SHOW_ALL, verbose);
    1048              : }
    1049              : 
    1050         5224 : DltReturnValue dlt_message_header_flags(DltMessage* msg, char* text, size_t textlength, int flags, int verbose)
    1051              : {
    1052              :     struct tm timeinfo;
    1053              :     char buffer[DLT_COMMON_BUFFER_LENGTH];
    1054              : 
    1055         5224 :     PRINT_FUNCTION_VERBOSE(verbose);
    1056              : 
    1057         5224 :     if ((msg == NULL) || (text == NULL) || (textlength <= 0))
    1058              :         return DLT_RETURN_WRONG_PARAMETER;
    1059              : 
    1060         5028 :     if ((DLT_IS_HTYP_UEH(msg->standardheader->htyp)) && (msg->extendedheader == NULL))
    1061              :         return DLT_RETURN_WRONG_PARAMETER;
    1062              : 
    1063         5028 :     if ((flags < DLT_HEADER_SHOW_NONE) || (flags > DLT_HEADER_SHOW_ALL))
    1064              :         return DLT_RETURN_WRONG_PARAMETER;
    1065              : 
    1066         5028 :     text[0] = 0;
    1067              : 
    1068         5028 :     if ((flags & DLT_HEADER_SHOW_TIME) == DLT_HEADER_SHOW_TIME) {
    1069              :         /* print received time */
    1070         2928 :         time_t tt = (time_t)msg->storageheader->seconds;
    1071         2928 :         tzset();
    1072         2928 :         localtime_r(&tt, &timeinfo);
    1073         2928 :         strftime(buffer, sizeof(buffer), "%Y/%m/%d %H:%M:%S", &timeinfo);
    1074         2928 :         snprintf(text, textlength, "%s.%.6d ", buffer, msg->storageheader->microseconds);
    1075              :     }
    1076              : 
    1077         5028 :     if ((flags & DLT_HEADER_SHOW_TMSTP) == DLT_HEADER_SHOW_TMSTP) {
    1078              :         /* print timestamp if available */
    1079         2928 :         if (DLT_IS_HTYP_WTMS(msg->standardheader->htyp))
    1080          749 :             snprintf(text + strlen(text), textlength - strlen(text), "%10u ", msg->headerextra.tmsp);
    1081              :         else
    1082         2179 :             snprintf(text + strlen(text), textlength - strlen(text), "---------- ");
    1083              :     }
    1084              : 
    1085         5028 :     if ((flags & DLT_HEADER_SHOW_MSGCNT) == DLT_HEADER_SHOW_MSGCNT)
    1086              :         /* print message counter */
    1087         2928 :         snprintf(text + strlen(text), textlength - strlen(text), "%.3d ", msg->standardheader->mcnt);
    1088              : 
    1089         5028 :     if ((flags & DLT_HEADER_SHOW_ECUID) == DLT_HEADER_SHOW_ECUID) {
    1090              :         /* print ecu id, use header extra if available, else storage header value */
    1091         2928 :         if (DLT_IS_HTYP_WEID(msg->standardheader->htyp))
    1092          749 :             dlt_print_id(text + strlen(text), msg->headerextra.ecu);
    1093              :         else
    1094         2179 :             dlt_print_id(text + strlen(text), msg->storageheader->ecu);
    1095              :     }
    1096              : 
    1097              : /* print app id and context id if extended header available, else '----' */ #
    1098              : 
    1099         5028 :     if ((flags & DLT_HEADER_SHOW_APID) == DLT_HEADER_SHOW_APID) {
    1100         2928 :         snprintf(text + strlen(text), textlength - strlen(text), " ");
    1101              : 
    1102         2928 :         if ((DLT_IS_HTYP_UEH(msg->standardheader->htyp)) && (msg->extendedheader->apid[0] != 0))
    1103         1497 :             dlt_print_id(text + strlen(text), msg->extendedheader->apid);
    1104              :         else
    1105         1431 :             snprintf(text + strlen(text), textlength - strlen(text), "----");
    1106              : 
    1107         2928 :         snprintf(text + strlen(text), textlength - strlen(text), " ");
    1108              :     }
    1109              : 
    1110         5028 :     if ((flags & DLT_HEADER_SHOW_CTID) == DLT_HEADER_SHOW_CTID) {
    1111         2928 :         if ((DLT_IS_HTYP_UEH(msg->standardheader->htyp)) && (msg->extendedheader->ctid[0] != 0))
    1112         1497 :             dlt_print_id(text + strlen(text), msg->extendedheader->ctid);
    1113              :         else
    1114         1431 :             snprintf(text + strlen(text), textlength - strlen(text), "----");
    1115              : 
    1116         2928 :         snprintf(text + strlen(text), textlength - strlen(text), " ");
    1117              :     }
    1118              : 
    1119              :     /* print info about message type and length */
    1120         5028 :     if (DLT_IS_HTYP_UEH(msg->standardheader->htyp)) {
    1121         2537 :         if ((flags & DLT_HEADER_SHOW_MSGTYPE) == DLT_HEADER_SHOW_MSGTYPE) {
    1122         1497 :             snprintf(
    1123         1497 :                 text + strlen(text), textlength - strlen(text), "%s",
    1124         1497 :                 message_type[DLT_GET_MSIN_MSTP(msg->extendedheader->msin)]);
    1125         1497 :             snprintf(text + strlen(text), textlength - strlen(text), " ");
    1126              :         }
    1127              : 
    1128         2537 :         if ((flags & DLT_HEADER_SHOW_MSGSUBTYPE) == DLT_HEADER_SHOW_MSGSUBTYPE) {
    1129         1497 :             if ((DLT_GET_MSIN_MSTP(msg->extendedheader->msin)) == DLT_TYPE_LOG)
    1130         1359 :                 snprintf(
    1131         1359 :                     text + strlen(text), textlength - strlen(text), "%s",
    1132         1359 :                     log_info[DLT_GET_MSIN_MTIN(msg->extendedheader->msin)]);
    1133              : 
    1134         1497 :             if ((DLT_GET_MSIN_MSTP(msg->extendedheader->msin)) == DLT_TYPE_APP_TRACE)
    1135            0 :                 snprintf(
    1136            0 :                     text + strlen(text), textlength - strlen(text), "%s",
    1137            0 :                     trace_type[DLT_GET_MSIN_MTIN(msg->extendedheader->msin)]);
    1138              : 
    1139         1497 :             if ((DLT_GET_MSIN_MSTP(msg->extendedheader->msin)) == DLT_TYPE_NW_TRACE)
    1140            0 :                 snprintf(
    1141            0 :                     text + strlen(text), textlength - strlen(text), "%s",
    1142            0 :                     nw_trace_type[DLT_GET_MSIN_MTIN(msg->extendedheader->msin)]);
    1143              : 
    1144         1497 :             if ((DLT_GET_MSIN_MSTP(msg->extendedheader->msin)) == DLT_TYPE_CONTROL)
    1145          138 :                 snprintf(
    1146          138 :                     text + strlen(text), textlength - strlen(text), "%s",
    1147          138 :                     control_type[DLT_GET_MSIN_MTIN(msg->extendedheader->msin)]);
    1148              : 
    1149         1497 :             snprintf(text + strlen(text), textlength - strlen(text), " ");
    1150              :         }
    1151              : 
    1152         2537 :         if ((flags & DLT_HEADER_SHOW_VNVSTATUS) == DLT_HEADER_SHOW_VNVSTATUS) {
    1153              :             /* print verbose status pf message */
    1154         1497 :             if (DLT_IS_MSIN_VERB(msg->extendedheader->msin))
    1155         1359 :                 snprintf(text + strlen(text), textlength - strlen(text), "V");
    1156              :             else
    1157          138 :                 snprintf(text + strlen(text), textlength - strlen(text), "N");
    1158              : 
    1159         1497 :             snprintf(text + strlen(text), textlength - strlen(text), " ");
    1160              :         }
    1161              : 
    1162         2537 :         if ((flags & DLT_HEADER_SHOW_NOARG) == DLT_HEADER_SHOW_NOARG)
    1163              :             /* print number of arguments */
    1164         1497 :             snprintf(text + strlen(text), textlength - strlen(text), "%d", msg->extendedheader->noar);
    1165              :     } else {
    1166         2491 :         if ((flags & DLT_HEADER_SHOW_MSGTYPE) == DLT_HEADER_SHOW_MSGTYPE)
    1167         1431 :             snprintf(text + strlen(text), textlength - strlen(text), "--- ");
    1168              : 
    1169         2491 :         if ((flags & DLT_HEADER_SHOW_MSGSUBTYPE) == DLT_HEADER_SHOW_MSGSUBTYPE)
    1170         1431 :             snprintf(text + strlen(text), textlength - strlen(text), "--- ");
    1171              : 
    1172         2491 :         if ((flags & DLT_HEADER_SHOW_VNVSTATUS) == DLT_HEADER_SHOW_VNVSTATUS)
    1173         1431 :             snprintf(text + strlen(text), textlength - strlen(text), "N ");
    1174              : 
    1175         2491 :         if ((flags & DLT_HEADER_SHOW_NOARG) == DLT_HEADER_SHOW_NOARG)
    1176         1431 :             snprintf(text + strlen(text), textlength - strlen(text), "-");
    1177              :     }
    1178              : 
    1179              :     return DLT_RETURN_OK;
    1180              : }
    1181              : 
    1182          196 : DltReturnValue dlt_message_header_flags_v2(DltMessageV2* msg, char* text, size_t textlength, int flags, int verbose)
    1183              : {
    1184              :     struct tm timeinfo;
    1185              :     char buffer[DLT_COMMON_BUFFER_LENGTH];
    1186              :     int currtextlength = 0;
    1187              : 
    1188          196 :     PRINT_FUNCTION_VERBOSE(verbose);
    1189              : 
    1190          196 :     if ((msg == NULL) || (text == NULL) || (textlength <= 0))
    1191              :         return DLT_RETURN_WRONG_PARAMETER;
    1192              : 
    1193            0 :     DltHtyp2ContentType msgcontent = msg->baseheaderv2->htyp2 & MSGCONTENT_MASK;
    1194              : 
    1195            0 :     if ((flags < DLT_HEADER_SHOW_NONE) || (flags > DLT_HEADER_SHOW_ALL))
    1196              :         return DLT_RETURN_WRONG_PARAMETER;
    1197              : 
    1198            0 :     text[0] = 0;
    1199              : 
    1200            0 :     if ((flags & DLT_HEADER_SHOW_TIME) == DLT_HEADER_SHOW_TIME) {
    1201              :         /* print received time */
    1202            0 :         time_t tt = 0;
    1203            0 :         for (int i = 0; i < 5; ++i) {
    1204            0 :             tt = (tt << 8) | msg->storageheaderv2.seconds[i];
    1205              :         }
    1206            0 :         tzset();
    1207            0 :         localtime_r(&tt, &timeinfo);
    1208            0 :         strftime(buffer, sizeof(buffer), "%Y/%m/%d %H:%M:%S", &timeinfo);
    1209            0 :         snprintf(text, textlength, "%s.%.9d ", buffer, msg->storageheaderv2.nanoseconds);
    1210              :     }
    1211              : 
    1212            0 :     if ((flags & DLT_HEADER_SHOW_TMSTP) == DLT_HEADER_SHOW_TMSTP) {
    1213              :         /* print timestamp if available */
    1214            0 :         if ((msgcontent == DLT_VERBOSE_DATA_MSG) || (msgcontent == DLT_NON_VERBOSE_DATA_MSG)) {
    1215              :             time_t tt = 0;
    1216            0 :             for (int i = 0; i < 5; ++i) {
    1217            0 :                 tt = (tt << 8) | msg->headerextrav2.seconds[i];
    1218              :             }
    1219            0 :             snprintf(
    1220            0 :                 text + strlen(text), textlength - strlen(text), "%lld.%.9u ", (long long int)tt,
    1221              :                 msg->headerextrav2.nanoseconds);
    1222              :         } else
    1223            0 :             snprintf(text + strlen(text), textlength - strlen(text), "---------- ");
    1224              :     }
    1225              : 
    1226            0 :     if ((flags & DLT_HEADER_SHOW_MSGCNT) == DLT_HEADER_SHOW_MSGCNT)
    1227              :         /* print message counter */
    1228            0 :         snprintf(text + strlen(text), textlength - strlen(text), "%.3d ", msg->baseheaderv2->mcnt);
    1229              : 
    1230            0 :     currtextlength = (int)strlen(text);
    1231              : 
    1232            0 :     if ((flags & DLT_HEADER_SHOW_ECUID) == DLT_HEADER_SHOW_ECUID) {
    1233              :         /* print ecu id, use header extra if available, else storage header value */
    1234            0 :         if (DLT_IS_HTYP2_WEID(msg->baseheaderv2->htyp2)) {
    1235            0 :             uint8_t display_len = (msg->extendedheaderv2.ecidlen > DLT_CLIENT_MAX_ID_LENGTH) ?
    1236              :                                       DLT_CLIENT_MAX_ID_LENGTH :
    1237              :                                       msg->extendedheaderv2.ecidlen;
    1238            0 :             memcpy(text + currtextlength, msg->extendedheaderv2.ecid, (size_t)display_len);
    1239            0 :             text[currtextlength + display_len] = '\0';
    1240              :             currtextlength = currtextlength + display_len;
    1241              :         } else {
    1242            0 :             uint8_t display_len = (msg->storageheaderv2.ecidlen > DLT_CLIENT_MAX_ID_LENGTH) ?
    1243              :                                       DLT_CLIENT_MAX_ID_LENGTH :
    1244              :                                       msg->storageheaderv2.ecidlen;
    1245            0 :             memcpy(text + (size_t)currtextlength, msg->storageheaderv2.ecid, (size_t)display_len);
    1246            0 :             text[currtextlength + display_len] = '\0';
    1247              :             currtextlength = currtextlength + display_len;
    1248              :         }
    1249              :     }
    1250              : /* print app id and context id if extended header available, else '----' */ #
    1251              : 
    1252            0 :     if ((flags & DLT_HEADER_SHOW_APID) == DLT_HEADER_SHOW_APID) {
    1253            0 :         snprintf(text + currtextlength, textlength - (size_t)currtextlength, " ");
    1254            0 :         currtextlength++;
    1255              : 
    1256            0 :         if ((DLT_IS_HTYP2_WACID(msg->baseheaderv2->htyp2)) && (msg->extendedheaderv2.apidlen != 0)) {
    1257            0 :             uint8_t display_len = (msg->extendedheaderv2.apidlen > DLT_CLIENT_MAX_ID_LENGTH) ?
    1258              :                                       DLT_CLIENT_MAX_ID_LENGTH :
    1259              :                                       msg->extendedheaderv2.apidlen;
    1260            0 :             memcpy(text + currtextlength, msg->extendedheaderv2.apid, (size_t)display_len);
    1261            0 :             text[currtextlength + display_len] = '\0';
    1262              :             currtextlength = currtextlength + display_len;
    1263              :         } else {
    1264            0 :             snprintf(text + currtextlength, textlength - (size_t)currtextlength, "----");
    1265            0 :             currtextlength = currtextlength + 4;
    1266              :         }
    1267            0 :         snprintf(text + currtextlength, textlength - (size_t)currtextlength, " ");
    1268            0 :         currtextlength++;
    1269              :     }
    1270              : 
    1271            0 :     if ((flags & DLT_HEADER_SHOW_CTID) == DLT_HEADER_SHOW_CTID) {
    1272            0 :         if ((DLT_IS_HTYP2_WACID(msg->baseheaderv2->htyp2)) && (msg->extendedheaderv2.ctidlen != 0)) {
    1273            0 :             uint8_t display_len = (msg->extendedheaderv2.ctidlen > DLT_CLIENT_MAX_ID_LENGTH) ?
    1274              :                                       DLT_CLIENT_MAX_ID_LENGTH :
    1275              :                                       msg->extendedheaderv2.ctidlen;
    1276            0 :             memcpy(text + currtextlength, msg->extendedheaderv2.ctid, (size_t)display_len);
    1277            0 :             text[currtextlength + display_len] = '\0';
    1278              :             currtextlength = currtextlength + display_len;
    1279              :         } else {
    1280            0 :             snprintf(text + currtextlength, textlength - (size_t)currtextlength, "----");
    1281            0 :             currtextlength = currtextlength + 4;
    1282              :         }
    1283            0 :         snprintf(text + currtextlength, textlength - (size_t)currtextlength, " ");
    1284            0 :         currtextlength++;
    1285              :     }
    1286              : 
    1287            0 :     if ((flags & DLT_HEADER_SHOW_FLNA_LNR) == DLT_HEADER_SHOW_FLNA_LNR) {
    1288            0 :         if ((DLT_IS_HTYP2_WSFLN(msg->baseheaderv2->htyp2)) && (msg->extendedheaderv2.finalen != 0)) {
    1289            0 :             memcpy(text + currtextlength, msg->extendedheaderv2.fina, (size_t)msg->extendedheaderv2.finalen);
    1290            0 :             currtextlength = currtextlength + (int)msg->extendedheaderv2.finalen;
    1291            0 :             snprintf(text + currtextlength, textlength - (size_t)currtextlength, " ");
    1292            0 :             currtextlength++;
    1293              :         }
    1294              : 
    1295            0 :         if ((DLT_IS_HTYP2_WSFLN(msg->baseheaderv2->htyp2)) && (msg->extendedheaderv2.linr != 0)) {
    1296            0 :             snprintf(text + currtextlength, textlength - (size_t)currtextlength, "%.5u", msg->extendedheaderv2.linr);
    1297            0 :             currtextlength = currtextlength + 5;
    1298            0 :             snprintf(text + currtextlength, textlength - (size_t)currtextlength, " ");
    1299            0 :             currtextlength++;
    1300              :         }
    1301              :     }
    1302              : 
    1303            0 :     if ((flags & DLT_HEADER_SHOW_PRLV) == DLT_HEADER_SHOW_PRLV) {
    1304            0 :         if (DLT_IS_HTYP2_WPVL(msg->baseheaderv2->htyp2)) {
    1305            0 :             snprintf(text + currtextlength, textlength - (size_t)currtextlength, "%.3u", msg->extendedheaderv2.prlv);
    1306            0 :             currtextlength = currtextlength + 3;
    1307            0 :             snprintf(text + currtextlength, textlength - (size_t)currtextlength, " ");
    1308            0 :             currtextlength++;
    1309              :         }
    1310              :     }
    1311              : 
    1312            0 :     if ((flags & DLT_HEADER_SHOW_TAG) == DLT_HEADER_SHOW_TAG) {
    1313            0 :         if ((DLT_IS_HTYP2_WTGS(msg->baseheaderv2->htyp2)) && (msg->extendedheaderv2.notg != 0)) {
    1314            0 :             for (int i = 0; i < msg->extendedheaderv2.notg; i++) {
    1315            0 :                 memcpy(
    1316            0 :                     text + currtextlength, msg->extendedheaderv2.tag[i].tagname,
    1317            0 :                     (size_t)msg->extendedheaderv2.tag[i].taglen + 1);
    1318            0 :                 currtextlength = currtextlength + (int)msg->extendedheaderv2.tag[i].taglen;
    1319            0 :                 snprintf(text + currtextlength, textlength - (size_t)currtextlength, " ");
    1320            0 :                 currtextlength++;
    1321              :             }
    1322              :         }
    1323              :     }
    1324              : 
    1325              :     /* print info about message type and length */
    1326            0 :     if ((msgcontent == DLT_VERBOSE_DATA_MSG) || (msgcontent == DLT_CONTROL_MSG)) {
    1327            0 :         if ((flags & DLT_HEADER_SHOW_MSGTYPE) == DLT_HEADER_SHOW_MSGTYPE) {
    1328            0 :             snprintf(
    1329            0 :                 text + strlen(text), textlength - strlen(text), "%s",
    1330            0 :                 message_type[DLT_GET_MSIN_MSTP(msg->headerextrav2.msin)]);
    1331            0 :             snprintf(text + strlen(text), textlength - strlen(text), " ");
    1332              :         }
    1333              : 
    1334            0 :         if ((flags & DLT_HEADER_SHOW_MSGSUBTYPE) == DLT_HEADER_SHOW_MSGSUBTYPE) {
    1335            0 :             if ((DLT_GET_MSIN_MSTP(msg->headerextrav2.msin)) == DLT_TYPE_LOG)
    1336            0 :                 snprintf(
    1337            0 :                     text + strlen(text), textlength - strlen(text), "%s",
    1338            0 :                     log_info[DLT_GET_MSIN_MTIN(msg->headerextrav2.msin)]);
    1339              : 
    1340            0 :             if ((DLT_GET_MSIN_MSTP(msg->headerextrav2.msin)) == DLT_TYPE_APP_TRACE)
    1341            0 :                 snprintf(
    1342            0 :                     text + strlen(text), textlength - strlen(text), "%s",
    1343            0 :                     trace_type[DLT_GET_MSIN_MTIN(msg->headerextrav2.msin)]);
    1344              : 
    1345            0 :             if ((DLT_GET_MSIN_MSTP(msg->headerextrav2.msin)) == DLT_TYPE_NW_TRACE)
    1346            0 :                 snprintf(
    1347            0 :                     text + strlen(text), textlength - strlen(text), "%s",
    1348            0 :                     nw_trace_type[DLT_GET_MSIN_MTIN(msg->headerextrav2.msin)]);
    1349              : 
    1350            0 :             if ((DLT_GET_MSIN_MSTP(msg->headerextrav2.msin)) == DLT_TYPE_CONTROL)
    1351            0 :                 snprintf(
    1352            0 :                     text + strlen(text), textlength - strlen(text), "%s",
    1353            0 :                     control_type[DLT_GET_MSIN_MTIN(msg->headerextrav2.msin)]);
    1354              : 
    1355            0 :             snprintf(text + strlen(text), textlength - strlen(text), " ");
    1356              :         }
    1357              : 
    1358            0 :         if ((flags & DLT_HEADER_SHOW_VNVSTATUS) == DLT_HEADER_SHOW_VNVSTATUS) {
    1359              :             /* print verbose status of message */
    1360            0 :             if (msgcontent == DLT_VERBOSE_DATA_MSG)
    1361            0 :                 snprintf(text + strlen(text), textlength - strlen(text), "V");
    1362              :             else
    1363            0 :                 snprintf(text + strlen(text), textlength - strlen(text), "N");
    1364              : 
    1365            0 :             snprintf(text + strlen(text), textlength - strlen(text), " ");
    1366              :         }
    1367              : 
    1368            0 :         if ((flags & DLT_HEADER_SHOW_NOARG) == DLT_HEADER_SHOW_NOARG)
    1369              :             /* print number of arguments */
    1370            0 :             snprintf(text + strlen(text), textlength - strlen(text), "%d", msg->headerextrav2.noar);
    1371              :     } else {
    1372            0 :         if ((flags & DLT_HEADER_SHOW_MSGTYPE) == DLT_HEADER_SHOW_MSGTYPE)
    1373            0 :             snprintf(text + strlen(text), textlength - strlen(text), "--- ");
    1374              : 
    1375            0 :         if ((flags & DLT_HEADER_SHOW_MSGSUBTYPE) == DLT_HEADER_SHOW_MSGSUBTYPE)
    1376            0 :             snprintf(text + strlen(text), textlength - strlen(text), "--- ");
    1377              : 
    1378            0 :         if ((flags & DLT_HEADER_SHOW_VNVSTATUS) == DLT_HEADER_SHOW_VNVSTATUS)
    1379            0 :             snprintf(text + strlen(text), textlength - strlen(text), "N ");
    1380              : 
    1381            0 :         if ((flags & DLT_HEADER_SHOW_NOARG) == DLT_HEADER_SHOW_NOARG)
    1382            0 :             snprintf(text + strlen(text), textlength - strlen(text), "-");
    1383              :     }
    1384              : 
    1385              :     return DLT_RETURN_OK;
    1386              : }
    1387              : 
    1388         3233 : DltReturnValue dlt_message_payload(DltMessage* msg, char* text, size_t textlength, int type, int verbose)
    1389              : {
    1390              :     uint32_t id = 0, id_tmp = 0;
    1391              :     uint8_t retval = 0;
    1392              : 
    1393              :     uint8_t* ptr;
    1394              :     int32_t datalength;
    1395              : 
    1396              :     /* Pointer to ptr and datalength */
    1397              :     uint8_t** pptr;
    1398              :     int32_t* pdatalength;
    1399              : 
    1400              :     int ret = 0;
    1401              : 
    1402              :     int num;
    1403              :     uint32_t type_info = 0, type_info_tmp = 0;
    1404              :     int text_offset = 0;
    1405              : 
    1406         3233 :     PRINT_FUNCTION_VERBOSE(verbose);
    1407              : 
    1408         3233 :     if ((msg == NULL) || (msg->databuffer == NULL) || (text == NULL) || (type < DLT_OUTPUT_HEX)
    1409         3148 :         || (type > DLT_OUTPUT_ASCII_LIMITED))
    1410              :         return DLT_RETURN_WRONG_PARAMETER;
    1411              : 
    1412         3043 :     if (textlength <= 0) {
    1413           10 :         dlt_log(LOG_WARNING, "String does not fit binary data!\n");
    1414           10 :         return DLT_RETURN_WRONG_PARAMETER;
    1415              :     }
    1416              : 
    1417              :     /* start with empty string */
    1418         3033 :     text[0] = 0;
    1419              : 
    1420              :     /* print payload only as hex */
    1421         3033 :     if (type == DLT_OUTPUT_HEX)
    1422          526 :         return dlt_print_hex_string(text, (int)textlength, msg->databuffer, (int)msg->datasize);
    1423              : 
    1424              :     /* print payload as mixed */
    1425         2507 :     if (type == DLT_OUTPUT_MIXED_FOR_PLAIN)
    1426          526 :         return dlt_print_mixed_string(text, (int)textlength, msg->databuffer, (int)msg->datasize, 0);
    1427              : 
    1428         1981 :     if (type == DLT_OUTPUT_MIXED_FOR_HTML)
    1429          526 :         return dlt_print_mixed_string(text, (int)textlength, msg->databuffer, (int)msg->datasize, 1);
    1430              : 
    1431         1455 :     ptr = msg->databuffer;
    1432         1455 :     datalength = (int32_t)msg->datasize;
    1433              : 
    1434              :     /* Pointer to ptr and datalength */
    1435              :     pptr = &ptr;
    1436              :     pdatalength = &datalength;
    1437              : 
    1438              :     /* non-verbose mode */
    1439              : 
    1440              :     /* print payload as hex */
    1441         1455 :     if (DLT_MSG_IS_NONVERBOSE(msg)) {
    1442          536 :         DLT_MSG_READ_VALUE(id_tmp, ptr, datalength, uint32_t);
    1443          536 :         id = DLT_ENDIAN_GET_32(msg->standardheader->htyp, id_tmp);
    1444              : 
    1445          536 :         if ((datalength < 0) || (textlength < (((unsigned int)datalength * 3) + 20))) {
    1446            0 :             dlt_vlog(
    1447              :                 LOG_WARNING, "String does not fit binary data (available=%zu, required=%zu) !\n", (size_t)textlength,
    1448            0 :                 ((size_t)datalength * 3U) + 20U);
    1449            0 :             return DLT_RETURN_ERROR;
    1450              :         }
    1451              : 
    1452              :         /* process message id / service id */
    1453          536 :         if (DLT_MSG_IS_CONTROL(msg)) {
    1454           59 :             if ((id > 0) && (id < DLT_SERVICE_ID_LAST_ENTRY))
    1455           57 :                 snprintf(text + strlen(text), textlength - strlen(text), "%s", service_id_name[id]); /* service id */
    1456            2 :             else if (!(DLT_MSG_IS_CONTROL_TIME(msg)))
    1457            2 :                 snprintf(text + strlen(text), textlength - strlen(text), "service(%u)", id); /* service id */
    1458              : 
    1459           59 :             if (datalength > 0)
    1460           59 :                 snprintf(text + strlen(text), textlength - strlen(text), ", ");
    1461              :         } else {
    1462          477 :             snprintf(text + strlen(text), textlength - strlen(text), "%u, ", id); /* message id */
    1463              :         }
    1464              : 
    1465              :         /* process return value */
    1466          536 :         if (DLT_MSG_IS_CONTROL_RESPONSE(msg)) {
    1467            3 :             if (datalength > 0) {
    1468            3 :                 DLT_MSG_READ_VALUE(retval, ptr, datalength, uint8_t); /* No endian conversion necessary */
    1469              : 
    1470            3 :                 if ((retval < DLT_SERVICE_RESPONSE_LAST) || (retval == 8))
    1471            2 :                     snprintf(text + strlen(text), textlength - strlen(text), "%s", return_type[retval]);
    1472              :                 else
    1473            1 :                     snprintf(text + strlen(text), textlength - strlen(text), "%.2x", retval);
    1474              : 
    1475            3 :                 if (datalength >= 1)
    1476            2 :                     snprintf(text + strlen(text), textlength - strlen(text), ", ");
    1477              :             }
    1478              :         }
    1479              : 
    1480          536 :         if (type == DLT_OUTPUT_ASCII_LIMITED) {
    1481          122 :             ret = dlt_print_hex_string(
    1482          122 :                 text + strlen(text), (int)((size_t)textlength - strlen(text)), ptr,
    1483          122 :                 (datalength > DLT_COMMON_ASCII_LIMIT_MAX_CHARS ? DLT_COMMON_ASCII_LIMIT_MAX_CHARS : datalength));
    1484              : 
    1485          122 :             if ((datalength > DLT_COMMON_ASCII_LIMIT_MAX_CHARS) && ((textlength - strlen(text)) > 4))
    1486            6 :                 snprintf(text + strlen(text), textlength - strlen(text), " ...");
    1487              :         } else {
    1488          414 :             ret = dlt_print_hex_string(text + strlen(text), (int)((size_t)textlength - strlen(text)), ptr, datalength);
    1489              :         }
    1490              : 
    1491          536 :         return ret;
    1492              :     }
    1493              : 
    1494              :     /* At this point, it is ensured that a extended header is available */
    1495              : 
    1496              :     /* verbose mode */
    1497              :     type_info = 0;
    1498              :     type_info_tmp = 0;
    1499              : 
    1500         3876 :     for (num = 0; num < (int)(msg->extendedheader->noar); num++) {
    1501         2957 :         if (num != 0) {
    1502         2052 :             text_offset = (int)strlen(text);
    1503         2052 :             snprintf(text + text_offset, textlength - (size_t)text_offset, " ");
    1504              :         }
    1505              : 
    1506              :         /* first read the type info of the argument */
    1507         2957 :         DLT_MSG_READ_VALUE(type_info_tmp, ptr, datalength, uint32_t);
    1508         2957 :         type_info = DLT_ENDIAN_GET_32(msg->standardheader->htyp, type_info_tmp);
    1509              : 
    1510              :         /* print out argument */
    1511         2957 :         text_offset = (int)strlen(text);
    1512              : 
    1513         2957 :         if (dlt_message_argument_print(
    1514         2957 :                 msg, type_info, pptr, pdatalength, (text + text_offset), (textlength - (size_t)text_offset), -1, 0)
    1515              :             == DLT_RETURN_ERROR)
    1516              :             return DLT_RETURN_ERROR;
    1517              :     }
    1518              : 
    1519              :     return DLT_RETURN_OK;
    1520              : }
    1521              : 
    1522           95 : DltReturnValue dlt_message_payload_v2(DltMessageV2* msg, char* text, size_t textlength, int type, int verbose)
    1523              : {
    1524              :     uint32_t id = 0;
    1525              :     uint32_t id_tmp = 0;
    1526              :     uint8_t retval = 0;
    1527              : 
    1528              :     uint8_t* ptr;
    1529              :     int32_t datalength;
    1530              : 
    1531              :     /* Pointer to ptr and datalength */
    1532              :     uint8_t** pptr;
    1533              :     int32_t* pdatalength;
    1534              : 
    1535              :     int ret = 0;
    1536              : 
    1537              :     int num;
    1538              :     uint32_t type_info = 0, type_info_tmp = 0;
    1539              :     int text_offset = 0;
    1540              : 
    1541           95 :     PRINT_FUNCTION_VERBOSE(verbose);
    1542              : 
    1543           95 :     if ((msg == NULL) || (msg->databuffer == NULL) || (text == NULL) || (type < DLT_OUTPUT_HEX)
    1544           10 :         || (type > DLT_OUTPUT_ASCII_LIMITED))
    1545              :         return DLT_RETURN_WRONG_PARAMETER;
    1546              : 
    1547           10 :     if (textlength <= 0) {
    1548           10 :         dlt_log(LOG_WARNING, "String does not fit binary data!\n");
    1549           10 :         return DLT_RETURN_WRONG_PARAMETER;
    1550              :     }
    1551              : 
    1552              :     /* start with empty string */
    1553            0 :     text[0] = 0;
    1554              : 
    1555              :     /* print payload only as hex */
    1556            0 :     if (type == DLT_OUTPUT_HEX)
    1557            0 :         return dlt_print_hex_string(text, (int)textlength, msg->databuffer, (int)msg->datasize);
    1558              : 
    1559              :     /* print payload as mixed */
    1560            0 :     if (type == DLT_OUTPUT_MIXED_FOR_PLAIN)
    1561            0 :         return dlt_print_mixed_string(text, (int)textlength, msg->databuffer, (int)msg->datasize, 0);
    1562              : 
    1563            0 :     if (type == DLT_OUTPUT_MIXED_FOR_HTML)
    1564            0 :         return dlt_print_mixed_string(text, (int)textlength, msg->databuffer, (int)msg->datasize, 1);
    1565              : 
    1566            0 :     ptr = msg->databuffer;
    1567            0 :     datalength = (int32_t)msg->datasize;
    1568              : 
    1569              :     /* Pointer to ptr and datalength */
    1570              :     pptr = &ptr;
    1571              :     pdatalength = &datalength;
    1572              : 
    1573              :     /* non-verbose mode */
    1574              : 
    1575              :     /* print payload as hex */
    1576            0 :     if (DLT_MSG_IS_NONVERBOSE_V2(msg)) {
    1577              :         // In version 2, message ID is not part of payload but stored in header conditional parameters
    1578              :         id = DLT_LETOH_32(msg->headerextrav2.msid);
    1579              : 
    1580            0 :         if (textlength < (((unsigned int)datalength * 3) + 20)) {
    1581            0 :             dlt_vlog(
    1582              :                 LOG_WARNING, "String does not fit binary data (available=%d, required=%d) !\n", (int)textlength,
    1583            0 :                 (datalength * 3) + 20);
    1584            0 :             return DLT_RETURN_ERROR;
    1585              :         }
    1586              : 
    1587            0 :         if (type == DLT_OUTPUT_ASCII_LIMITED) {
    1588            0 :             ret = dlt_print_hex_string(
    1589            0 :                 text + strlen(text), (int)(textlength - strlen(text)), ptr,
    1590            0 :                 (datalength > DLT_COMMON_ASCII_LIMIT_MAX_CHARS ? DLT_COMMON_ASCII_LIMIT_MAX_CHARS : datalength));
    1591              : 
    1592            0 :             if ((datalength > DLT_COMMON_ASCII_LIMIT_MAX_CHARS) && ((textlength - strlen(text)) > 4))
    1593            0 :                 snprintf(text + strlen(text), textlength - strlen(text), " ...");
    1594              :         } else {
    1595            0 :             ret = dlt_print_hex_string(text + strlen(text), (int)(textlength - strlen(text)), ptr, datalength);
    1596              :         }
    1597            0 :         return ret;
    1598              :     }
    1599              : 
    1600              :     /* process control message */
    1601            0 :     if (DLT_MSG_IS_CONTROL_V2(msg)) {
    1602            0 :         DLT_MSG_READ_VALUE(id_tmp, ptr, datalength, uint32_t);
    1603              :         id = DLT_LETOH_32(id_tmp);
    1604              : 
    1605            0 :         if ((id > 0) && (id < DLT_SERVICE_ID_LAST_ENTRY))
    1606            0 :             snprintf(text + strlen(text), textlength - strlen(text), "%s", service_id_name[id]); /* service id */
    1607            0 :         else if (!(DLT_MSG_IS_CONTROL_TIME_V2(msg)))
    1608            0 :             snprintf(text + strlen(text), textlength - strlen(text), "service(%u)", id); /* service id */
    1609              : 
    1610            0 :         if (datalength > 0)
    1611            0 :             snprintf(text + strlen(text), textlength - strlen(text), ", ");
    1612              : 
    1613              :         /* process return value */
    1614            0 :         if (DLT_MSG_IS_CONTROL_RESPONSE_V2(msg)) {
    1615            0 :             if (datalength > 0) {
    1616            0 :                 DLT_MSG_READ_VALUE(retval, ptr, datalength, uint8_t); /* No endian conversion necessary */
    1617              : 
    1618            0 :                 if ((retval < DLT_SERVICE_RESPONSE_LAST) || (retval == 8))
    1619            0 :                     snprintf(text + strlen(text), textlength - strlen(text), "%s", return_type[retval]);
    1620              :                 else
    1621            0 :                     snprintf(text + strlen(text), textlength - strlen(text), "%.2x", retval);
    1622              : 
    1623            0 :                 if (datalength >= 1)
    1624            0 :                     snprintf(text + strlen(text), textlength - strlen(text), ", ");
    1625              :             }
    1626              :         }
    1627              : 
    1628            0 :         if (type == DLT_OUTPUT_ASCII_LIMITED) {
    1629            0 :             ret = dlt_print_hex_string(
    1630            0 :                 text + strlen(text), (int)(textlength - strlen(text)), ptr,
    1631            0 :                 (datalength > DLT_COMMON_ASCII_LIMIT_MAX_CHARS ? DLT_COMMON_ASCII_LIMIT_MAX_CHARS : datalength));
    1632              : 
    1633            0 :             if ((datalength > DLT_COMMON_ASCII_LIMIT_MAX_CHARS) && ((textlength - strlen(text)) > 4))
    1634            0 :                 snprintf(text + strlen(text), textlength - strlen(text), " ...");
    1635              :         } else {
    1636            0 :             ret = dlt_print_hex_string(text + strlen(text), (int)(textlength - strlen(text)), ptr, datalength);
    1637              :         }
    1638            0 :         return ret;
    1639              :     }
    1640              : 
    1641              :     /* verbose mode */
    1642              :     type_info = 0;
    1643              :     type_info_tmp = 0;
    1644              : 
    1645            0 :     for (num = 0; num < (int)(msg->headerextrav2.noar); num++) {
    1646            0 :         if (num != 0) {
    1647            0 :             text_offset = (int)strlen(text);
    1648            0 :             snprintf(text + text_offset, textlength - (size_t)text_offset, " ");
    1649              :         }
    1650              : 
    1651              :         /* first read the type info of the argument */
    1652            0 :         DLT_MSG_READ_VALUE(type_info_tmp, ptr, datalength, uint32_t);
    1653              : 
    1654              :         type_info = DLT_LETOH_32(type_info_tmp);
    1655              :         /* print out argument */
    1656            0 :         text_offset = (int)strlen(text);
    1657              : 
    1658            0 :         if (dlt_message_argument_print_v2(
    1659            0 :                 msg, type_info, pptr, pdatalength, (text + text_offset), (textlength - (size_t)text_offset), -1, 0)
    1660              :             == DLT_RETURN_ERROR) {
    1661              :             return DLT_RETURN_ERROR;
    1662              :         }
    1663              :     }
    1664              : 
    1665              :     return DLT_RETURN_OK;
    1666              : }
    1667              : 
    1668          742 : DltReturnValue dlt_message_filter_check(DltMessage* msg, DltFilter* filter, int verbose)
    1669              : {
    1670              :     /* check the filters if message is used */
    1671              :     int num;
    1672              :     DltReturnValue found = DLT_RETURN_OK;
    1673              : 
    1674          742 :     PRINT_FUNCTION_VERBOSE(verbose);
    1675              : 
    1676          742 :     if ((msg == NULL) || (filter == NULL))
    1677              :         return DLT_RETURN_WRONG_PARAMETER;
    1678              : 
    1679          736 :     if ((filter->counter == 0) || (!(DLT_IS_HTYP_UEH(msg->standardheader->htyp))))
    1680              :         /* no filter is set, or no extended header is available, so do as filter is matching */
    1681              :         return DLT_RETURN_TRUE;
    1682              : 
    1683          936 :     for (num = 0; num < filter->counter; num++)
    1684              :         /* check each filter if it matches */
    1685              :         if ((DLT_IS_HTYP_UEH(msg->standardheader->htyp))
    1686          624 :             && ((filter->apid[num][0] == 0) || (memcmp(filter->apid[num], msg->extendedheader->apid, DLT_ID_SIZE) == 0))
    1687            0 :             && ((filter->ctid[num][0] == 0) || (memcmp(filter->ctid[num], msg->extendedheader->ctid, DLT_ID_SIZE) == 0))
    1688            0 :             && ((filter->log_level[num] == 0)
    1689            0 :                 || (filter->log_level[num] == DLT_GET_MSIN_MTIN(msg->extendedheader->msin)))
    1690            0 :             && ((filter->payload_min[num] == 0) || (filter->payload_min[num] <= msg->datasize))
    1691            0 :             && ((filter->payload_max[num] == 0) || (filter->payload_max[num] >= msg->datasize))) {
    1692              :             found = DLT_RETURN_TRUE;
    1693              :             break;
    1694              :         }
    1695              : 
    1696              :     return found;
    1697              : }
    1698              : 
    1699            6 : DltReturnValue dlt_message_filter_check_v2(DltMessageV2* msg, DltFilter* filter, int verbose)
    1700              : {
    1701              :     /* check the filters if message is used */
    1702              :     int num;
    1703              :     DltReturnValue found = DLT_RETURN_OK;
    1704              : 
    1705            6 :     PRINT_FUNCTION_VERBOSE(verbose);
    1706              : 
    1707            6 :     if ((msg == NULL) || (filter == NULL))
    1708              :         return DLT_RETURN_WRONG_PARAMETER;
    1709              : 
    1710            0 :     if ((filter->counter == 0) || (!(DLT_IS_HTYP2_EH(msg->baseheaderv2->htyp2))))
    1711              :         /* no filter is set, or no extended header is available, so do as filter is matching */
    1712              :         return DLT_RETURN_TRUE;
    1713              : 
    1714            0 :     for (num = 0; num < filter->counter; num++)
    1715              :         /* check each filter if it matches */
    1716              :         if ((DLT_IS_HTYP2_EH(msg->baseheaderv2->htyp2))
    1717            0 :             && ((filter->apid2[num] == NULL)
    1718            0 :                 || (memcmp(filter->apid2[num], msg->extendedheaderv2.apid, msg->extendedheaderv2.apidlen) == 0))
    1719            0 :             && ((filter->ctid2[num] == NULL)
    1720            0 :                 || (memcmp(filter->ctid2[num], msg->extendedheaderv2.ctid, msg->extendedheaderv2.ctidlen) == 0))
    1721            0 :             && ((filter->log_level[num] == 0) || (filter->log_level[num] == DLT_GET_MSIN_MTIN(msg->headerextrav2.msin)))
    1722            0 :             && ((filter->payload_min[num] == 0) || (filter->payload_min[num] <= msg->datasize))
    1723            0 :             && ((filter->payload_max[num] == 0) || (filter->payload_max[num] >= msg->datasize))) {
    1724              :             found = DLT_RETURN_TRUE;
    1725              :             break;
    1726              :         }
    1727              : 
    1728              :     return found;
    1729              : }
    1730              : 
    1731         1206 : int dlt_message_read(DltMessage* msg, uint8_t* buffer, unsigned int length, int resync, int verbose)
    1732              : {
    1733              :     uint32_t extra_size = 0;
    1734              : 
    1735         1206 :     PRINT_FUNCTION_VERBOSE(verbose);
    1736              : 
    1737         1206 :     if ((msg == NULL) || (buffer == NULL) || (length <= 0))
    1738              :         return DLT_MESSAGE_ERROR_UNKNOWN;
    1739              : 
    1740              :     /* initialize resync_offset */
    1741          805 :     msg->resync_offset = 0;
    1742              : 
    1743              :     /* check if message contains serial header, smaller than standard header */
    1744          805 :     if (length < sizeof(dltSerialHeader))
    1745              :         /* dlt_log(LOG_ERR, "Length smaller than serial header!\n"); */
    1746              :         return DLT_MESSAGE_ERROR_SIZE;
    1747              : 
    1748          805 :     if (memcmp(buffer, dltSerialHeader, sizeof(dltSerialHeader)) == 0) {
    1749              :         /* serial header found */
    1750            0 :         msg->found_serialheader = 1;
    1751            0 :         buffer += sizeof(dltSerialHeader);
    1752            0 :         length -= (unsigned int)sizeof(dltSerialHeader);
    1753              :     } else {
    1754              :         /* serial header not found */
    1755          805 :         msg->found_serialheader = 0;
    1756              : 
    1757          805 :         if (resync) {
    1758              :             /* resync if necessary */
    1759              :             msg->resync_offset = 0;
    1760              : 
    1761              :             do {
    1762            0 :                 if (memcmp(buffer + msg->resync_offset, dltSerialHeader, sizeof(dltSerialHeader)) == 0) {
    1763              :                     /* serial header found */
    1764            0 :                     msg->found_serialheader = 1;
    1765            0 :                     buffer += sizeof(dltSerialHeader);
    1766            0 :                     length -= (unsigned int)sizeof(dltSerialHeader);
    1767            0 :                     break;
    1768              :                 }
    1769              : 
    1770            0 :                 msg->resync_offset++;
    1771            0 :             } while ((sizeof(dltSerialHeader) + (size_t)msg->resync_offset) <= length);
    1772              : 
    1773              :             /* Set new start offset */
    1774            0 :             if (msg->resync_offset > 0) {
    1775              :                 /* Resyncing connection */
    1776            0 :                 buffer += msg->resync_offset;
    1777            0 :                 length -= (unsigned int)msg->resync_offset;
    1778              :             }
    1779              :         }
    1780              :     }
    1781              : 
    1782              :     /* check that standard header fits buffer */
    1783          805 :     if (length < sizeof(DltStandardHeader))
    1784              :         /* dlt_log(LOG_ERR, "Length smaller than standard header!\n"); */
    1785              :         return DLT_MESSAGE_ERROR_SIZE;
    1786              : 
    1787          805 :     memcpy(msg->headerbuffer + sizeof(DltStorageHeader), buffer, sizeof(DltStandardHeader));
    1788              : 
    1789              :     /* set ptrs to structures */
    1790          805 :     msg->storageheader = (DltStorageHeader*)msg->headerbuffer;
    1791          805 :     msg->standardheader = (DltStandardHeader*)(msg->headerbuffer + sizeof(DltStorageHeader));
    1792              : 
    1793              :     /* calculate complete size of headers */
    1794          805 :     extra_size = (uint32_t)(DLT_STANDARD_HEADER_EXTRA_SIZE(msg->standardheader->htyp)
    1795              :                             + (DLT_IS_HTYP_UEH(msg->standardheader->htyp) ? sizeof(DltExtendedHeader) : 0));
    1796          805 :     msg->headersize = (int32_t)(sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + extra_size);
    1797          805 :     msg->datasize = (int32_t)((uint32_t)DLT_BETOH_16(msg->standardheader->len) - (uint32_t)msg->headersize
    1798          805 :                               + (uint32_t)sizeof(DltStorageHeader));
    1799              : 
    1800              :     /* calculate complete size of payload */
    1801              :     int32_t temp_datasize;
    1802          805 :     temp_datasize =
    1803          805 :         DLT_BETOH_16(msg->standardheader->len) - (int32_t)msg->headersize + (int32_t)sizeof(DltStorageHeader);
    1804              : 
    1805              :     /* check data size */
    1806          805 :     if (temp_datasize < 0) {
    1807            0 :         dlt_vlog(LOG_WARNING, "Plausibility check failed. Complete message size too short (%d)!\n", temp_datasize);
    1808            0 :         return DLT_MESSAGE_ERROR_CONTENT;
    1809              :     } else {
    1810          805 :         msg->datasize = (int32_t)temp_datasize;
    1811              :     }
    1812              : 
    1813              :     /* check if verbose mode is on*/
    1814          805 :     if (verbose) {
    1815            0 :         dlt_vlog(LOG_DEBUG, "BufferLength=%u, HeaderSize=%u, DataSize=%u\n", length, msg->headersize, msg->datasize);
    1816              :     }
    1817              : 
    1818              :     /* load standard header extra parameters and Extended header if used */
    1819          805 :     if (extra_size > 0) {
    1820          805 :         if (length < (size_t)((int32_t)msg->headersize - (int32_t)sizeof(DltStorageHeader)))
    1821              :             return DLT_MESSAGE_ERROR_SIZE;
    1822              : 
    1823          805 :         memcpy(
    1824              :             msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader),
    1825          805 :             buffer + sizeof(DltStandardHeader), (size_t)extra_size);
    1826              : 
    1827              :         /* set extended header ptr and get standard header extra parameters */
    1828          805 :         if (DLT_IS_HTYP_UEH(msg->standardheader->htyp))
    1829          805 :             msg->extendedheader =
    1830          805 :                 (DltExtendedHeader*)(msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader)
    1831          805 :                                      + DLT_STANDARD_HEADER_EXTRA_SIZE(msg->standardheader->htyp));
    1832              :         else
    1833            0 :             msg->extendedheader = NULL;
    1834              : 
    1835          805 :         dlt_message_get_extraparameters(msg, verbose);
    1836              :     }
    1837              : 
    1838              :     /* check if payload fits length */
    1839          805 :     if (length < (size_t)((int32_t)msg->headersize - (int32_t)sizeof(DltStorageHeader) + msg->datasize))
    1840              :         /* dlt_log(LOG_ERR,"length does not fit!\n"); */
    1841              :         return DLT_MESSAGE_ERROR_SIZE;
    1842              : 
    1843              :     /* free last used memory for buffer */
    1844          628 :     if (msg->databuffer) {
    1845          625 :         if (msg->datasize > msg->databuffersize) {
    1846            4 :             free(msg->databuffer);
    1847            4 :             msg->databuffer = (uint8_t*)malloc((size_t)msg->datasize);
    1848            4 :             msg->databuffersize = msg->datasize;
    1849              :         }
    1850              :     } else {
    1851              :         /* get new memory for buffer */
    1852            3 :         msg->databuffer = (uint8_t*)malloc((size_t)msg->datasize);
    1853            3 :         msg->databuffersize = msg->datasize;
    1854              :     }
    1855              : 
    1856          628 :     if (msg->databuffer == NULL) {
    1857            0 :         dlt_vlog(LOG_WARNING, "Cannot allocate memory for payload buffer of size %u!\n", msg->datasize);
    1858            0 :         return DLT_MESSAGE_ERROR_UNKNOWN;
    1859              :     }
    1860              : 
    1861              :     /* load payload data from buffer */
    1862          628 :     memcpy(
    1863          628 :         msg->databuffer, buffer + (size_t)((int32_t)msg->headersize - (int32_t)sizeof(DltStorageHeader)),
    1864          628 :         (size_t)msg->datasize);
    1865              : 
    1866          628 :     return DLT_MESSAGE_ERROR_OK;
    1867              : }
    1868              : 
    1869            4 : int dlt_message_read_v2(DltMessageV2* msg, uint8_t* buffer, unsigned int length, int resync, int verbose)
    1870              : {
    1871              :     DltHtyp2ContentType msgcontent = 0x00;
    1872            4 :     const char dltStorageHeaderV2Pattern[DLT_ID_SIZE] = {'D', 'L', 'T', 0x02};
    1873              : 
    1874            4 :     PRINT_FUNCTION_VERBOSE(verbose);
    1875              : 
    1876            4 :     if ((msg == NULL) || (buffer == NULL) || (length <= 0)) {
    1877              :         return DLT_MESSAGE_ERROR_UNKNOWN;
    1878              :     }
    1879              : 
    1880              :     /* Free any existing buffers before reinitializing */
    1881            0 :     if (msg->headerbufferv2) {
    1882            0 :         free(msg->headerbufferv2);
    1883            0 :         msg->headerbufferv2 = NULL;
    1884              :     }
    1885            0 :     if (msg->databuffer) {
    1886            0 :         free(msg->databuffer);
    1887            0 :         msg->databuffer = NULL;
    1888              :     }
    1889            0 :     if (msg->extendedheaderv2.tag) {
    1890            0 :         free(msg->extendedheaderv2.tag);
    1891            0 :         msg->extendedheaderv2.tag = NULL;
    1892              :     }
    1893              : 
    1894              :     /* Initialize message structure */
    1895            0 :     msg->headersizev2 = 0;
    1896            0 :     msg->datasize = 0;
    1897            0 :     msg->databuffersize = 0;
    1898            0 :     memset(&(msg->storageheaderv2), 0, sizeof(msg->storageheaderv2));
    1899            0 :     memset(&(msg->extendedheaderv2), 0, sizeof(msg->extendedheaderv2));
    1900            0 :     msg->baseheaderv2 = NULL;
    1901            0 :     msg->found_serialheader = 0;
    1902              : 
    1903              :     /* initialize resync_offset */
    1904            0 :     msg->resync_offset = 0;
    1905              : 
    1906              :     /* check if message contains storage header V2 */
    1907            0 :     if ((length >= STORAGE_HEADER_V2_FIXED_SIZE)
    1908            0 :         && (memcmp(buffer, dltStorageHeaderV2Pattern, sizeof(dltStorageHeaderV2Pattern)) == 0)) {
    1909              :         /* Storage header V2 found - parse ECU ID length and calculate storage header size */
    1910            0 :         memcpy(&(msg->storageheaderv2.ecidlen), buffer + 13, 1);
    1911            0 :         msg->storageheadersizev2 = (uint32_t)STORAGE_HEADER_V2_FIXED_SIZE + msg->storageheaderv2.ecidlen;
    1912              : 
    1913              :         /* Skip storage header in buffer */
    1914            0 :         if (length < msg->storageheadersizev2) {
    1915              :             return DLT_MESSAGE_ERROR_SIZE;
    1916              :         }
    1917            0 :         buffer += msg->storageheadersizev2;
    1918            0 :         length -= msg->storageheadersizev2;
    1919              :     } else {
    1920            0 :         msg->storageheadersizev2 = 0;
    1921              :     }
    1922              : 
    1923              :     /* check if message contains serial header */
    1924            0 :     if (length < sizeof(dltSerialHeader)) {
    1925              :         /* Length smaller than serial header */
    1926              :         return DLT_MESSAGE_ERROR_SIZE;
    1927              :     }
    1928              : 
    1929            0 :     if (memcmp(buffer, dltSerialHeader, sizeof(dltSerialHeader)) == 0) {
    1930              :         /* serial header found */
    1931            0 :         msg->found_serialheader = 1;
    1932            0 :         buffer += sizeof(dltSerialHeader);
    1933            0 :         length -= (unsigned int)sizeof(dltSerialHeader);
    1934              :     } else {
    1935              :         /* serial header not found */
    1936              :         msg->found_serialheader = 0;
    1937              : 
    1938            0 :         if (resync) {
    1939              :             /* resync if necessary */
    1940              :             msg->resync_offset = 0;
    1941              : 
    1942              :             do {
    1943            0 :                 if (memcmp(buffer + msg->resync_offset, dltSerialHeader, sizeof(dltSerialHeader)) == 0) {
    1944              :                     /* serial header found */
    1945            0 :                     msg->found_serialheader = 1;
    1946            0 :                     buffer += sizeof(dltSerialHeader);
    1947            0 :                     length -= (unsigned int)sizeof(dltSerialHeader);
    1948            0 :                     break;
    1949              :                 }
    1950              : 
    1951            0 :                 msg->resync_offset++;
    1952            0 :             } while ((sizeof(dltSerialHeader) + (size_t)msg->resync_offset) <= length);
    1953              : 
    1954              :             /* Set new start offset */
    1955            0 :             if (msg->resync_offset > 0) {
    1956              :                 /* Resyncing connection */
    1957            0 :                 buffer += msg->resync_offset;
    1958            0 :                 length -= (unsigned int)msg->resync_offset;
    1959              :             }
    1960              :         }
    1961              :     }
    1962              : 
    1963              :     /* check that standard header fits buffer */
    1964            0 :     if (length < BASE_HEADER_V2_FIXED_SIZE)
    1965              :         /* dlt_log(LOG_ERR, "Length smaller than standard header!\n"); */
    1966              :         return DLT_MESSAGE_ERROR_SIZE;
    1967              : 
    1968              :     /* Extract Base header */
    1969            0 :     msg->baseheaderv2 = (DltBaseHeaderV2*)buffer;
    1970            0 :     msgcontent = (((uint32_t)msg->baseheaderv2->htyp2) & MSGCONTENT_MASK);
    1971              : 
    1972            0 :     msg->storageheadersizev2 = 0;
    1973            0 :     msg->baseheadersizev2 = BASE_HEADER_V2_FIXED_SIZE;
    1974            0 :     msg->baseheaderextrasizev2 = dlt_message_get_extraparameters_size_v2(msgcontent);
    1975              :     /* Fill extra parameters */
    1976            0 :     if (dlt_message_get_extraparameters_from_recievedbuffer_v2(msg, buffer, msgcontent) != DLT_RETURN_OK)
    1977              :         return DLT_RETURN_ERROR;
    1978              : 
    1979              :     /* Fill extended parameters and extended parameters size */
    1980            0 :     if (dlt_message_get_extendedparameters_from_recievedbuffer_v2(msg, buffer, msgcontent) != DLT_RETURN_OK)
    1981              :         return DLT_RETURN_ERROR;
    1982              : 
    1983              :     /* calculate complete size of headers without storage header */
    1984            0 :     msg->headersizev2 = (int32_t)(msg->baseheadersizev2 + msg->baseheaderextrasizev2 + msg->extendedheadersizev2);
    1985              : 
    1986            0 :     if (msg->headerbufferv2) {
    1987            0 :         free(msg->headerbufferv2);
    1988              :     }
    1989              : 
    1990            0 :     msg->headerbufferv2 = (uint8_t*)calloc((size_t)msg->headersizev2, 1);
    1991              : 
    1992            0 :     if (msg->headerbufferv2 == NULL) {
    1993              :         return DLT_RETURN_ERROR;
    1994              :     }
    1995              :     memcpy(msg->headerbufferv2, buffer, (size_t)msg->headersizev2);
    1996              : 
    1997              :     /* calculate complete size of payload */
    1998              :     int32_t temp_datasize;
    1999              : 
    2000              :     // Assign a temp_baseheader_len of int32_t from msg->baseheaderv2->len and use below
    2001            0 :     temp_datasize = DLT_BETOH_16(msg->baseheaderv2->len) - msg->headersizev2;
    2002              : 
    2003              :     /* check data size */
    2004            0 :     if (temp_datasize < 0) {
    2005            0 :         dlt_vlog(LOG_WARNING, "Plausibility check failed. Complete message size too short (%d)!\n", temp_datasize);
    2006            0 :         return DLT_MESSAGE_ERROR_CONTENT;
    2007              :     } else {
    2008            0 :         msg->datasize = temp_datasize;
    2009              :     }
    2010              :     /* check if verbose mode is on*/
    2011            0 :     if (verbose) {
    2012            0 :         dlt_vlog(LOG_DEBUG, "BufferLength=%u, HeaderSize=%u, DataSize=%u\n", length, msg->headersizev2, msg->datasize);
    2013              :     }
    2014              : 
    2015              :     /* check if payload fits length */
    2016            0 :     if (length < (unsigned int)(msg->headersizev2 + msg->datasize))
    2017              :         /* dlt_log(LOG_ERR,"length does not fit!\n"); */
    2018              :         return DLT_MESSAGE_ERROR_SIZE;
    2019              : 
    2020              :     /* free last used memory for buffer */
    2021            0 :     if (msg->databuffer) {
    2022            0 :         if (msg->datasize > msg->databuffersize) {
    2023            0 :             free(msg->databuffer);
    2024            0 :             msg->databuffer = (uint8_t*)malloc((size_t)msg->datasize);
    2025            0 :             msg->databuffersize = msg->datasize;
    2026              :         }
    2027              :     } else {
    2028              :         /* get new memory for buffer */
    2029            0 :         msg->databuffer = (uint8_t*)malloc((size_t)msg->datasize);
    2030            0 :         msg->databuffersize = msg->datasize;
    2031              :     }
    2032              : 
    2033            0 :     if (msg->databuffer == NULL) {
    2034            0 :         dlt_vlog(LOG_WARNING, "Cannot allocate memory for payload buffer of size %u!\n", msg->datasize);
    2035            0 :         return DLT_MESSAGE_ERROR_UNKNOWN;
    2036              :     }
    2037              : 
    2038              :     /* load payload data from buffer */
    2039            0 :     memcpy(msg->databuffer, buffer + msg->headersizev2, (size_t)msg->datasize);
    2040            0 :     return DLT_MESSAGE_ERROR_OK;
    2041              : }
    2042              : 
    2043            0 : DltReturnValue dlt_message_get_storageparameters_v2(DltMessageV2* msg, int verbose)
    2044              : {
    2045            0 :     PRINT_FUNCTION_VERBOSE(verbose);
    2046              : 
    2047            0 :     if (msg == NULL)
    2048              :         return DLT_RETURN_WRONG_PARAMETER;
    2049              : 
    2050            0 :     memcpy(msg->storageheaderv2.pattern, msg->headerbufferv2, 4);
    2051            0 :     memcpy(msg->storageheaderv2.seconds, msg->headerbufferv2 + 4, 5);
    2052            0 :     memcpy(&(msg->storageheaderv2.nanoseconds), msg->headerbufferv2 + 9, 4);
    2053            0 :     msg->storageheaderv2.nanoseconds = (int32_t)DLT_BETOH_32((uint32_t)msg->storageheaderv2.nanoseconds);
    2054            0 :     memcpy(&(msg->storageheaderv2.ecidlen), msg->headerbufferv2 + 13, 1);
    2055            0 :     memcpy(msg->storageheaderv2.ecid, msg->headerbufferv2 + 14, msg->storageheaderv2.ecidlen);
    2056              :     /* Add Null pointer in the end of ECUID */
    2057            0 :     memset(msg->storageheaderv2.ecid + msg->storageheaderv2.ecidlen, '\0', 1);
    2058              : 
    2059            0 :     return DLT_RETURN_OK;
    2060              : }
    2061              : 
    2062           21 : DltReturnValue dlt_message_set_storageparameters_v2(DltMessageV2* msg, int verbose)
    2063              : {
    2064           21 :     PRINT_FUNCTION_VERBOSE(verbose);
    2065              : 
    2066           21 :     if (msg == NULL)
    2067              :         return DLT_RETURN_WRONG_PARAMETER;
    2068              : 
    2069           21 :     memcpy(msg->headerbufferv2, msg->storageheaderv2.pattern, 4);
    2070           21 :     memcpy(msg->headerbufferv2 + 4, msg->storageheaderv2.seconds, 5);
    2071           21 :     memcpy(msg->headerbufferv2 + 9, &(msg->storageheaderv2.nanoseconds), 4);
    2072           21 :     memcpy(msg->headerbufferv2 + 13, &(msg->storageheaderv2.ecidlen), 1);
    2073           21 :     memcpy(msg->headerbufferv2 + 14, msg->storageheaderv2.ecid, msg->storageheaderv2.ecidlen);
    2074              : 
    2075           21 :     return DLT_RETURN_OK;
    2076              : }
    2077              : 
    2078         1885 : DltReturnValue dlt_message_get_extraparameters(DltMessage* msg, int verbose)
    2079              : {
    2080         1885 :     PRINT_FUNCTION_VERBOSE(verbose);
    2081              : 
    2082         1885 :     if (msg == NULL)
    2083              :         return DLT_RETURN_WRONG_PARAMETER;
    2084              : 
    2085         1883 :     if (DLT_IS_HTYP_WEID(msg->standardheader->htyp))
    2086         1689 :         memcpy(
    2087         1689 :             msg->headerextra.ecu, msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader),
    2088              :             DLT_ID_SIZE);
    2089              : 
    2090         1883 :     if (DLT_IS_HTYP_WSID(msg->standardheader->htyp)) {
    2091         1412 :         memcpy(
    2092         1412 :             &(msg->headerextra.seid),
    2093         1412 :             msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader)
    2094         1412 :                 + (DLT_IS_HTYP_WEID(msg->standardheader->htyp) ? DLT_SIZE_WEID : 0),
    2095              :             DLT_SIZE_WSID);
    2096         1412 :         msg->headerextra.seid = DLT_BETOH_32(msg->headerextra.seid);
    2097              :     }
    2098              : 
    2099         1883 :     if (DLT_IS_HTYP_WTMS(msg->standardheader->htyp)) {
    2100         1689 :         memcpy(
    2101         1689 :             &(msg->headerextra.tmsp),
    2102         1689 :             msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader)
    2103         1689 :                 + (DLT_IS_HTYP_WEID(msg->standardheader->htyp) ? DLT_SIZE_WEID : 0)
    2104         1689 :                 + (DLT_IS_HTYP_WSID(msg->standardheader->htyp) ? DLT_SIZE_WSID : 0),
    2105              :             DLT_SIZE_WTMS);
    2106         1689 :         msg->headerextra.tmsp = DLT_BETOH_32(msg->headerextra.tmsp);
    2107              :     }
    2108              : 
    2109              :     return DLT_RETURN_OK;
    2110              : }
    2111              : 
    2112            0 : DltReturnValue dlt_message_get_extraparameters_v2(DltMessageV2* msg, int verbose)
    2113              : {
    2114            0 :     PRINT_FUNCTION_VERBOSE(verbose);
    2115              : 
    2116            0 :     if (msg == NULL)
    2117              :         return DLT_RETURN_WRONG_PARAMETER;
    2118              : 
    2119              :     DltHtyp2ContentType msgcontent;
    2120            0 :     msgcontent = ((*(msg->headerbufferv2 + msg->storageheadersizev2)) & MSGCONTENT_MASK);
    2121              : 
    2122            0 :     if (msgcontent == DLT_VERBOSE_DATA_MSG) {
    2123            0 :         memcpy(&(msg->headerextrav2.msin), msg->headerbufferv2 + msg->storageheadersizev2 + msg->baseheadersizev2, 1);
    2124              :         memcpy(
    2125            0 :             &(msg->headerextrav2.noar), msg->headerbufferv2 + msg->storageheadersizev2 + msg->baseheadersizev2 + 1, 1);
    2126              :         memcpy(
    2127            0 :             &(msg->headerextrav2.nanoseconds),
    2128            0 :             msg->headerbufferv2 + msg->storageheadersizev2 + msg->baseheadersizev2 + 2, 4);
    2129            0 :         msg->headerextrav2.nanoseconds = DLT_BETOH_32(msg->headerextrav2.nanoseconds);
    2130              :         memcpy(
    2131            0 :             msg->headerextrav2.seconds, msg->headerbufferv2 + msg->storageheadersizev2 + msg->baseheadersizev2 + 6, 5);
    2132              :     }
    2133              : 
    2134            0 :     if (msgcontent == DLT_NON_VERBOSE_DATA_MSG) {
    2135              :         memcpy(
    2136            0 :             &(msg->headerextrav2.nanoseconds), msg->headerbufferv2 + msg->storageheadersizev2 + msg->baseheadersizev2,
    2137              :             4);
    2138            0 :         msg->headerextrav2.nanoseconds = DLT_BETOH_32(msg->headerextrav2.nanoseconds);
    2139              :         memcpy(
    2140            0 :             msg->headerextrav2.seconds, msg->headerbufferv2 + msg->storageheadersizev2 + msg->baseheadersizev2 + 4, 5);
    2141              :         memcpy(
    2142            0 :             &(msg->headerextrav2.msid), msg->headerbufferv2 + msg->storageheadersizev2 + msg->baseheadersizev2 + 9, 4);
    2143            0 :         msg->headerextrav2.msid = DLT_BETOH_32(msg->headerextrav2.msid);
    2144              :     }
    2145              : 
    2146            0 :     if (msgcontent == DLT_CONTROL_MSG) {
    2147            0 :         memcpy(&(msg->headerextrav2.msin), msg->headerbufferv2 + msg->storageheadersizev2 + msg->baseheadersizev2, 1);
    2148              :         memcpy(
    2149            0 :             &(msg->headerextrav2.noar), msg->headerbufferv2 + msg->storageheadersizev2 + msg->baseheadersizev2 + 1, 1);
    2150              :     }
    2151              :     return DLT_RETURN_OK;
    2152              : }
    2153              : 
    2154            0 : static DltReturnValue dlt_message_get_extraparameters_from_recievedbuffer_v2(
    2155              :     DltMessageV2* msg, uint8_t* buffer, DltHtyp2ContentType msgcontent)
    2156              : {
    2157              :     // Buffer should be starting from Baseheader
    2158            0 :     if (msg == NULL)
    2159              :         return DLT_RETURN_WRONG_PARAMETER;
    2160              : 
    2161            0 :     if (msgcontent == DLT_VERBOSE_DATA_MSG) {
    2162            0 :         memcpy(&(msg->headerextrav2.msin), buffer + BASE_HEADER_V2_FIXED_SIZE, 1);
    2163            0 :         memcpy(&(msg->headerextrav2.noar), buffer + BASE_HEADER_V2_FIXED_SIZE + 1, 1);
    2164            0 :         memcpy(&(msg->headerextrav2.nanoseconds), buffer + BASE_HEADER_V2_FIXED_SIZE + 2, 4);
    2165            0 :         msg->headerextrav2.nanoseconds = DLT_BETOH_32(msg->headerextrav2.nanoseconds);
    2166            0 :         memcpy(msg->headerextrav2.seconds, buffer + BASE_HEADER_V2_FIXED_SIZE + 6, 5);
    2167              :     }
    2168              : 
    2169            0 :     if (msgcontent == DLT_NON_VERBOSE_DATA_MSG) {
    2170            0 :         memcpy(&(msg->headerextrav2.nanoseconds), buffer + BASE_HEADER_V2_FIXED_SIZE, 4);
    2171            0 :         msg->headerextrav2.nanoseconds = DLT_BETOH_32(msg->headerextrav2.nanoseconds);
    2172            0 :         memcpy(msg->headerextrav2.seconds, buffer + BASE_HEADER_V2_FIXED_SIZE + 4, 5);
    2173            0 :         memcpy(&(msg->headerextrav2.msid), buffer + BASE_HEADER_V2_FIXED_SIZE + 9, 4);
    2174            0 :         msg->headerextrav2.msid = DLT_BETOH_32(msg->headerextrav2.msid);
    2175              :     }
    2176              : 
    2177            0 :     if (msgcontent == DLT_CONTROL_MSG) {
    2178            0 :         memcpy(&(msg->headerextrav2.msin), buffer + BASE_HEADER_V2_FIXED_SIZE, 1);
    2179            0 :         memcpy(&(msg->headerextrav2.noar), buffer + BASE_HEADER_V2_FIXED_SIZE + 1, 1);
    2180              :     }
    2181              :     return DLT_RETURN_OK;
    2182              : }
    2183              : 
    2184         6225 : DltReturnValue dlt_message_set_extraparameters(DltMessage* msg, int verbose)
    2185              : {
    2186         6225 :     PRINT_FUNCTION_VERBOSE(verbose);
    2187              : 
    2188         6225 :     if (msg == NULL)
    2189              :         return DLT_RETURN_WRONG_PARAMETER;
    2190              : 
    2191         6223 :     if (DLT_IS_HTYP_WEID(msg->standardheader->htyp))
    2192         6027 :         memcpy(
    2193         6027 :             msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader), msg->headerextra.ecu,
    2194              :             DLT_ID_SIZE);
    2195              : 
    2196         6223 :     if (DLT_IS_HTYP_WSID(msg->standardheader->htyp)) {
    2197         5999 :         msg->headerextra.seid = DLT_HTOBE_32(msg->headerextra.seid);
    2198         5999 :         memcpy(
    2199         5999 :             msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader)
    2200         5999 :                 + (DLT_IS_HTYP_WEID(msg->standardheader->htyp) ? DLT_SIZE_WEID : 0),
    2201         5999 :             &(msg->headerextra.seid), DLT_SIZE_WSID);
    2202              :     }
    2203              : 
    2204         6223 :     if (DLT_IS_HTYP_WTMS(msg->standardheader->htyp)) {
    2205         6027 :         msg->headerextra.tmsp = DLT_HTOBE_32(msg->headerextra.tmsp);
    2206         6027 :         memcpy(
    2207         6027 :             msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader)
    2208         6027 :                 + (DLT_IS_HTYP_WEID(msg->standardheader->htyp) ? DLT_SIZE_WEID : 0)
    2209         6027 :                 + (DLT_IS_HTYP_WSID(msg->standardheader->htyp) ? DLT_SIZE_WSID : 0),
    2210         6027 :             &(msg->headerextra.tmsp), DLT_SIZE_WTMS);
    2211              :     }
    2212              : 
    2213              :     return DLT_RETURN_OK;
    2214              : }
    2215              : 
    2216           23 : DltReturnValue dlt_message_set_extraparameters_v2(DltMessageV2* msg, int verbose)
    2217              : {
    2218           23 :     PRINT_FUNCTION_VERBOSE(verbose);
    2219              : 
    2220           23 :     if (msg == NULL)
    2221              :         return DLT_RETURN_WRONG_PARAMETER;
    2222              : 
    2223              :     DltHtyp2ContentType msgcontent;
    2224           23 :     msgcontent = ((msg->baseheaderv2->htyp2) & MSGCONTENT_MASK);
    2225              : 
    2226           23 :     if (msgcontent == DLT_VERBOSE_DATA_MSG) {
    2227           23 :         memcpy(msg->headerbufferv2 + msg->storageheadersizev2 + msg->baseheadersizev2, &(msg->headerextrav2.msin), 1);
    2228              :         memcpy(
    2229           23 :             msg->headerbufferv2 + msg->storageheadersizev2 + msg->baseheadersizev2 + 1, &(msg->headerextrav2.noar), 1);
    2230           23 :         uint32_t nanoseconds_be = DLT_HTOBE_32(msg->headerextrav2.nanoseconds);
    2231           23 :         memcpy(msg->headerbufferv2 + msg->storageheadersizev2 + msg->baseheadersizev2 + 2, &nanoseconds_be, 4);
    2232              :         memcpy(
    2233           23 :             msg->headerbufferv2 + msg->storageheadersizev2 + msg->baseheadersizev2 + 6, msg->headerextrav2.seconds, 5);
    2234              :     }
    2235              : 
    2236           23 :     if (msgcontent == DLT_NON_VERBOSE_DATA_MSG) {
    2237            0 :         uint32_t nanoseconds_be = DLT_HTOBE_32(msg->headerextrav2.nanoseconds);
    2238            0 :         memcpy(msg->headerbufferv2 + msg->storageheadersizev2 + msg->baseheadersizev2, &nanoseconds_be, 4);
    2239              :         memcpy(
    2240            0 :             msg->headerbufferv2 + msg->storageheadersizev2 + msg->baseheadersizev2 + 4, msg->headerextrav2.seconds, 5);
    2241            0 :         uint32_t msid_be = DLT_HTOBE_32(msg->headerextrav2.msid);
    2242            0 :         memcpy(msg->headerbufferv2 + msg->storageheadersizev2 + msg->baseheadersizev2 + 9, &msid_be, 4);
    2243              :     }
    2244              : 
    2245           23 :     if (msgcontent == DLT_CONTROL_MSG) {
    2246            0 :         memcpy(msg->headerbufferv2 + msg->storageheadersizev2 + msg->baseheadersizev2, &(msg->headerextrav2.msin), 1);
    2247              :         memcpy(
    2248            0 :             msg->headerbufferv2 + msg->storageheadersizev2 + msg->baseheadersizev2 + 1, &(msg->headerextrav2.noar), 1);
    2249              :     }
    2250              :     return DLT_RETURN_OK;
    2251              : }
    2252              : 
    2253           21 : uint8_t dlt_message_get_extraparameters_size_v2(DltHtyp2ContentType msgcontent)
    2254              : {
    2255              :     uint8_t size = 0;
    2256           21 :     if (msgcontent == DLT_VERBOSE_DATA_MSG) {
    2257              :         size = DLT_SIZE_VERBOSE_DATA_MSG;
    2258            0 :     } else if (msgcontent == DLT_NON_VERBOSE_DATA_MSG) {
    2259              :         size = DLT_SIZE_NONVERBOSE_DATA_MSG;
    2260            0 :     } else if (msgcontent == DLT_CONTROL_MSG) {
    2261              :         size = DLT_SIZE_CONTROL_MSG;
    2262              :     }
    2263           21 :     return size;
    2264              : }
    2265              : 
    2266           21 : DltReturnValue dlt_message_set_extendedparameters_v2(DltMessageV2* msg)
    2267              : {
    2268           21 :     if (msg == NULL)
    2269              :         return DLT_RETURN_WRONG_PARAMETER;
    2270              : 
    2271           21 :     uint32_t pntroffset = msg->storageheadersizev2 + msg->baseheadersizev2 + msg->baseheaderextrasizev2;
    2272              : 
    2273           21 :     if (DLT_IS_HTYP2_WEID(msg->baseheaderv2->htyp2)) {
    2274           21 :         memcpy(msg->headerbufferv2 + pntroffset, &(msg->extendedheaderv2.ecidlen), 1);
    2275           21 :         if (msg->extendedheaderv2.ecidlen > 0) {
    2276           21 :             if (msg->extendedheaderv2.ecid == NULL) {
    2277              :                 return DLT_RETURN_ERROR;
    2278              :             }
    2279              :             /* copy ecid into header buffer and update pointer to point into headerbufferv2 */
    2280           21 :             memcpy(msg->headerbufferv2 + pntroffset + 1, msg->extendedheaderv2.ecid, msg->extendedheaderv2.ecidlen);
    2281           21 :             msg->extendedheaderv2.ecid = (char*)(msg->headerbufferv2 + pntroffset + 1);
    2282              :         }
    2283           21 :         pntroffset = pntroffset + msg->extendedheaderv2.ecidlen + 1;
    2284              :     }
    2285              : 
    2286           21 :     if (DLT_IS_HTYP2_WACID(msg->baseheaderv2->htyp2)) {
    2287           21 :         memcpy(msg->headerbufferv2 + pntroffset, &(msg->extendedheaderv2.apidlen), 1);
    2288           21 :         if (msg->extendedheaderv2.apidlen > 0) {
    2289           21 :             if (msg->extendedheaderv2.apid == NULL) {
    2290              :                 return DLT_RETURN_ERROR;
    2291              :             }
    2292              :             /* copy apid into header buffer and update pointer to point into headerbufferv2 */
    2293           21 :             memcpy(msg->headerbufferv2 + pntroffset + 1, msg->extendedheaderv2.apid, msg->extendedheaderv2.apidlen);
    2294           21 :             msg->extendedheaderv2.apid = (char*)(msg->headerbufferv2 + pntroffset + 1);
    2295              :         }
    2296           21 :         pntroffset = pntroffset + (msg->extendedheaderv2.apidlen) + 1;
    2297              : 
    2298           21 :         memcpy(msg->headerbufferv2 + pntroffset, &(msg->extendedheaderv2.ctidlen), 1);
    2299           21 :         if (msg->extendedheaderv2.ctidlen > 0) {
    2300           21 :             if (msg->extendedheaderv2.ctid == NULL) {
    2301              :                 return DLT_RETURN_ERROR;
    2302              :             }
    2303              :             /* copy ctid into header buffer and update pointer to point into headerbufferv2 */
    2304           21 :             memcpy(msg->headerbufferv2 + pntroffset + 1, msg->extendedheaderv2.ctid, msg->extendedheaderv2.ctidlen);
    2305           21 :             msg->extendedheaderv2.ctid = (char*)(msg->headerbufferv2 + pntroffset + 1);
    2306              :         }
    2307           21 :         pntroffset = pntroffset + msg->extendedheaderv2.ctidlen + 1;
    2308              :     }
    2309              : 
    2310           21 :     if (DLT_IS_HTYP2_WSID(msg->baseheaderv2->htyp2)) {
    2311           21 :         uint32_t seid_be = DLT_HTOBE_32(msg->extendedheaderv2.seid);
    2312           21 :         memcpy(msg->headerbufferv2 + pntroffset, &seid_be, 4);
    2313              : 
    2314           21 :         pntroffset = pntroffset + 4;
    2315              :     }
    2316              : 
    2317           21 :     if (DLT_IS_HTYP2_WSFLN(msg->baseheaderv2->htyp2)) {
    2318            0 :         memcpy(msg->headerbufferv2 + pntroffset, &(msg->extendedheaderv2.finalen), 1);
    2319              : 
    2320              :         /* copy filename into header buffer and update pointer to point into headerbufferv2 */
    2321            0 :         if (msg->extendedheaderv2.finalen > 0 && msg->extendedheaderv2.fina != NULL) {
    2322            0 :             memcpy(msg->headerbufferv2 + pntroffset + 1, msg->extendedheaderv2.fina, msg->extendedheaderv2.finalen);
    2323            0 :             msg->extendedheaderv2.fina = (char*)(msg->headerbufferv2 + pntroffset + 1);
    2324              :         }
    2325              : 
    2326            0 :         pntroffset = pntroffset + msg->extendedheaderv2.finalen + 1;
    2327              : 
    2328            0 :         uint32_t linr_be = DLT_HTOBE_32(msg->extendedheaderv2.linr);
    2329            0 :         memcpy(msg->headerbufferv2 + pntroffset, &linr_be, 4);
    2330              : 
    2331            0 :         pntroffset = pntroffset + 4;
    2332              :     }
    2333              : 
    2334           21 :     if (DLT_IS_HTYP2_WTGS(msg->baseheaderv2->htyp2)) {
    2335            0 :         memcpy(msg->headerbufferv2 + pntroffset, &(msg->extendedheaderv2.notg), 1);
    2336            0 :         pntroffset = pntroffset + 1;
    2337              : 
    2338            0 :         for (int j = 0; j < msg->extendedheaderv2.notg; j++) {
    2339            0 :             memset(msg->headerbufferv2 + pntroffset, msg->extendedheaderv2.tag[j].taglen, 1);
    2340              : 
    2341            0 :             memcpy(
    2342            0 :                 msg->headerbufferv2 + pntroffset + 1, msg->extendedheaderv2.tag[j].tagname,
    2343            0 :                 msg->extendedheaderv2.tag[j].taglen);
    2344              :             /* ensure NUL termination for tag name consumers that expect len+1 bytes */
    2345            0 :             msg->headerbufferv2[pntroffset + 1 + msg->extendedheaderv2.tag[j].taglen] = '\0';
    2346              : 
    2347            0 :             pntroffset = pntroffset + (msg->extendedheaderv2.tag[j].taglen) + 1;
    2348              :         }
    2349              :     }
    2350              : 
    2351           21 :     if (DLT_IS_HTYP2_WPVL(msg->baseheaderv2->htyp2)) {
    2352            0 :         memcpy(msg->headerbufferv2 + pntroffset, &(msg->extendedheaderv2.prlv), 1);
    2353              : 
    2354            0 :         pntroffset = pntroffset + 1;
    2355              :     }
    2356              : 
    2357           21 :     if (DLT_IS_HTYP2_WSGM(msg->baseheaderv2->htyp2)) {
    2358              :         uint8_t sgmtLength = 0;
    2359            0 :         memcpy(msg->headerbufferv2 + pntroffset, &(msg->extendedheaderv2.sgmtinfo), 1);
    2360              : 
    2361            0 :         memcpy(msg->headerbufferv2 + pntroffset + 1, &(msg->extendedheaderv2.frametype), 1);
    2362              : 
    2363            0 :         if (msg->extendedheaderv2.frametype == DLT_FIRST_FRAME) {
    2364              :             sgmtLength = 8;
    2365            0 :         } else if (msg->extendedheaderv2.frametype == DLT_CONSECUTIVE_FRAME) {
    2366              :             sgmtLength = 4;
    2367            0 :         } else if (msg->extendedheaderv2.frametype == DLT_LAST_FRAME) {
    2368              :             sgmtLength = 0;
    2369            0 :         } else if (msg->extendedheaderv2.frametype == DLT_ABORT_FRAME) {
    2370              :             sgmtLength = 1;
    2371              :         }
    2372              : 
    2373            0 :         memcpy(msg->headerbufferv2 + pntroffset + 2, &(msg->extendedheaderv2.sgmtdetails), sgmtLength);
    2374              : 
    2375              :         pntroffset = pntroffset + sgmtLength + 2;
    2376              :     }
    2377              : 
    2378              :     return DLT_RETURN_OK;
    2379              : }
    2380              : 
    2381            0 : uint32_t dlt_message_get_extendedparameters_size_v2(DltMessageV2* msg)
    2382              : {
    2383              :     uint32_t size = 0;
    2384              :     uint8_t sgmtLength = 0;
    2385              : 
    2386            0 :     if (DLT_IS_HTYP2_WEID(msg->baseheaderv2->htyp2)) {
    2387            0 :         size = size + msg->extendedheaderv2.ecidlen + 1;
    2388              :     };
    2389            0 :     if (DLT_IS_HTYP2_WACID(msg->baseheaderv2->htyp2)) {
    2390            0 :         size = size + msg->extendedheaderv2.apidlen + 1;
    2391            0 :         size = size + msg->extendedheaderv2.ctidlen + 1;
    2392              :     };
    2393            0 :     if (DLT_IS_HTYP2_WSID(msg->baseheaderv2->htyp2)) {
    2394            0 :         size = size + 4;
    2395              :     };
    2396            0 :     if (DLT_IS_HTYP2_WSFLN(msg->baseheaderv2->htyp2)) {
    2397            0 :         size = size + msg->extendedheaderv2.finalen + 1 + 4;
    2398              :     };
    2399            0 :     if (DLT_IS_HTYP2_WTGS(msg->baseheaderv2->htyp2)) {
    2400            0 :         size = size + 1;
    2401            0 :         for (int j = 0; j < msg->extendedheaderv2.notg; j++) {
    2402            0 :             size = size + (msg->extendedheaderv2.tag[j].taglen) + 1;
    2403              :         };
    2404              :     };
    2405            0 :     if (DLT_IS_HTYP2_WPVL(msg->baseheaderv2->htyp2)) {
    2406            0 :         size = size + 1;
    2407              :     };
    2408            0 :     if (DLT_IS_HTYP2_WSGM(msg->baseheaderv2->htyp2)) {
    2409            0 :         if (msg->extendedheaderv2.frametype == DLT_FIRST_FRAME) {
    2410              :             sgmtLength = 8;
    2411            0 :         } else if (msg->extendedheaderv2.frametype == DLT_CONSECUTIVE_FRAME) {
    2412              :             sgmtLength = 4;
    2413            0 :         } else if (msg->extendedheaderv2.frametype == DLT_LAST_FRAME) {
    2414              :             sgmtLength = 0;
    2415            0 :         } else if (msg->extendedheaderv2.frametype == DLT_ABORT_FRAME) {
    2416              :             sgmtLength = 1;
    2417              :         }
    2418            0 :         size = size + sgmtLength + 2;
    2419              :     };
    2420            0 :     return size;
    2421              : }
    2422              : 
    2423            0 : DltReturnValue dlt_message_get_extendedparameters_from_recievedbuffer_v2(
    2424              :     DltMessageV2* msg, uint8_t* buffer, DltHtyp2ContentType msgcontent)
    2425              : {
    2426            0 :     if (msg == NULL)
    2427              :         return DLT_RETURN_WRONG_PARAMETER;
    2428              : 
    2429            0 :     uint16_t headerExtraSize = dlt_message_get_extraparameters_size_v2(msgcontent);
    2430            0 :     msg->baseheaderv2 = (DltBaseHeaderV2*)buffer;
    2431              : 
    2432            0 :     int32_t pntroffset = BASE_HEADER_V2_FIXED_SIZE + headerExtraSize;
    2433              : 
    2434            0 :     if (DLT_IS_HTYP2_WEID(msg->baseheaderv2->htyp2)) {
    2435            0 :         memcpy(&(msg->extendedheaderv2.ecidlen), buffer + pntroffset, 1);
    2436            0 :         msg->extendedheaderv2.ecid = (char*)(buffer + pntroffset + 1);
    2437            0 :         pntroffset = pntroffset + msg->extendedheaderv2.ecidlen + 1;
    2438              :     }
    2439              : 
    2440            0 :     if (DLT_IS_HTYP2_WACID(msg->baseheaderv2->htyp2)) {
    2441            0 :         memcpy(&(msg->extendedheaderv2.apidlen), buffer + pntroffset, 1);
    2442            0 :         msg->extendedheaderv2.apid = (char*)(buffer + pntroffset + 1);
    2443              : 
    2444            0 :         pntroffset = pntroffset + (msg->extendedheaderv2.apidlen) + 1;
    2445              : 
    2446            0 :         memcpy(&(msg->extendedheaderv2.ctidlen), buffer + pntroffset, 1);
    2447            0 :         msg->extendedheaderv2.ctid = (char*)(buffer + pntroffset + 1);
    2448              : 
    2449            0 :         pntroffset = pntroffset + msg->extendedheaderv2.ctidlen + 1;
    2450              :     }
    2451              : 
    2452            0 :     if (DLT_IS_HTYP2_WSID(msg->baseheaderv2->htyp2)) {
    2453            0 :         memcpy(&(msg->extendedheaderv2.seid), buffer + pntroffset, 4);
    2454            0 :         msg->extendedheaderv2.seid = DLT_BETOH_32(msg->extendedheaderv2.seid);
    2455            0 :         pntroffset = pntroffset + 4;
    2456              :     }
    2457              : 
    2458            0 :     if (DLT_IS_HTYP2_WSFLN(msg->baseheaderv2->htyp2)) {
    2459            0 :         memcpy(&(msg->extendedheaderv2.finalen), buffer + pntroffset, 1);
    2460            0 :         msg->extendedheaderv2.fina = (char*)(buffer + pntroffset + 1);
    2461              : 
    2462            0 :         pntroffset = pntroffset + msg->extendedheaderv2.finalen + 1;
    2463              : 
    2464            0 :         memcpy(&(msg->extendedheaderv2.linr), buffer + pntroffset, 4);
    2465            0 :         msg->extendedheaderv2.linr = DLT_BETOH_32(msg->extendedheaderv2.linr);
    2466            0 :         pntroffset = pntroffset + 4;
    2467              :     }
    2468              : 
    2469            0 :     if (DLT_IS_HTYP2_WTGS(msg->baseheaderv2->htyp2)) {
    2470            0 :         memcpy(&(msg->extendedheaderv2.notg), buffer + pntroffset, 1);
    2471            0 :         pntroffset = pntroffset + 1;
    2472              : 
    2473              :         /* Free previously allocated tags before re-allocating */
    2474            0 :         if (msg->extendedheaderv2.tag != NULL) {
    2475            0 :             free(msg->extendedheaderv2.tag);
    2476              :             msg->extendedheaderv2.tag = NULL;
    2477              :         }
    2478            0 :         msg->extendedheaderv2.tag = (DltTag*)malloc((msg->extendedheaderv2.notg) * sizeof(DltTag));
    2479            0 :         if (msg->extendedheaderv2.tag == NULL) {
    2480              :             return DLT_RETURN_ERROR;
    2481              :         }
    2482            0 :         for (int j = 0; j < msg->extendedheaderv2.notg; j++) {
    2483            0 :             memcpy(&(msg->extendedheaderv2.tag[j].taglen), buffer + pntroffset, 1);
    2484              : 
    2485              :             /* Copy tag name into fixed-size buffer inside DltTag and NUL-terminate. */
    2486            0 :             size_t tlen = msg->extendedheaderv2.tag[j].taglen;
    2487            0 :             if (tlen >= DLT_V2_ID_SIZE) {
    2488              :                 /* truncate if too long */
    2489            0 :                 memcpy(msg->extendedheaderv2.tag[j].tagname, buffer + pntroffset + 1, DLT_V2_ID_SIZE - 1);
    2490            0 :                 msg->extendedheaderv2.tag[j].tagname[DLT_V2_ID_SIZE - 1] = '\0';
    2491              :             } else {
    2492            0 :                 memcpy(msg->extendedheaderv2.tag[j].tagname, buffer + pntroffset + 1, tlen);
    2493            0 :                 msg->extendedheaderv2.tag[j].tagname[tlen] = '\0';
    2494              :             }
    2495              : 
    2496            0 :             pntroffset = pntroffset + (msg->extendedheaderv2.tag[j].taglen) + 1;
    2497              :         }
    2498              :     }
    2499              : 
    2500            0 :     if (DLT_IS_HTYP2_WPVL(msg->baseheaderv2->htyp2)) {
    2501            0 :         memcpy(&(msg->extendedheaderv2.prlv), buffer + pntroffset, 1);
    2502              : 
    2503            0 :         pntroffset = pntroffset + 1;
    2504              :     }
    2505              : 
    2506            0 :     if (DLT_IS_HTYP2_WSGM(msg->baseheaderv2->htyp2)) {
    2507              :         uint8_t sgmtLength = 0;
    2508            0 :         memcpy(&(msg->extendedheaderv2.sgmtinfo), buffer + pntroffset, 1);
    2509              : 
    2510            0 :         memcpy(&(msg->extendedheaderv2.frametype), buffer + pntroffset + 1, 1);
    2511              : 
    2512            0 :         if (msg->extendedheaderv2.frametype == DLT_FIRST_FRAME) {
    2513              :             sgmtLength = 8;
    2514            0 :         } else if (msg->extendedheaderv2.frametype == DLT_CONSECUTIVE_FRAME) {
    2515              :             sgmtLength = 4;
    2516            0 :         } else if (msg->extendedheaderv2.frametype == DLT_LAST_FRAME) {
    2517              :             sgmtLength = 0;
    2518            0 :         } else if (msg->extendedheaderv2.frametype == DLT_ABORT_FRAME) {
    2519              :             sgmtLength = 1;
    2520              :         }
    2521              : 
    2522            0 :         memcpy(&(msg->extendedheaderv2.sgmtdetails), buffer + pntroffset + 2, sgmtLength);
    2523              : 
    2524            0 :         pntroffset = pntroffset + sgmtLength + 2;
    2525              :     }
    2526            0 :     msg->extendedheadersizev2 = (uint32_t)(pntroffset - BASE_HEADER_V2_FIXED_SIZE - headerExtraSize);
    2527            0 :     return DLT_RETURN_OK;
    2528              : }
    2529              : 
    2530           34 : DltReturnValue dlt_file_init(DltFile* file, int verbose)
    2531              : {
    2532           34 :     PRINT_FUNCTION_VERBOSE(verbose);
    2533              : 
    2534           34 :     if (file == NULL)
    2535              :         return DLT_RETURN_WRONG_PARAMETER;
    2536              : 
    2537              :     /* initalise structure parameters */
    2538           34 :     file->handle = NULL;
    2539           34 :     file->counter = 0;
    2540           34 :     file->counter_total = 0;
    2541           34 :     file->index = NULL;
    2542              : 
    2543           34 :     file->filter = NULL;
    2544           34 :     file->filter_counter = 0;
    2545           34 :     file->file_position = 0;
    2546              : 
    2547           34 :     file->position = 0;
    2548              : 
    2549           34 :     file->error_messages = 0;
    2550              : 
    2551           34 :     return dlt_message_init(&(file->msg), verbose);
    2552              : }
    2553              : 
    2554           19 : DltReturnValue dlt_file_init_v2(DltFile* file, int verbose)
    2555              : {
    2556           19 :     PRINT_FUNCTION_VERBOSE(verbose);
    2557              : 
    2558           19 :     if (file == NULL)
    2559              :         return DLT_RETURN_WRONG_PARAMETER;
    2560              : 
    2561              :     /* initalise structure parameters */
    2562           19 :     file->handle = NULL;
    2563           19 :     file->counter = 0;
    2564           19 :     file->counter_total = 0;
    2565           19 :     file->index = NULL;
    2566              : 
    2567           19 :     file->filter = NULL;
    2568           19 :     file->filter_counter = 0;
    2569           19 :     file->file_position = 0;
    2570              : 
    2571           19 :     file->position = 0;
    2572              : 
    2573           19 :     file->error_messages = 0;
    2574              : 
    2575           19 :     return dlt_message_init_v2(&(file->msgv2), verbose);
    2576              : }
    2577              : 
    2578              : 
    2579           11 : DltReturnValue dlt_file_set_filter(DltFile* file, DltFilter* filter, int verbose)
    2580              : {
    2581           11 :     PRINT_FUNCTION_VERBOSE(verbose);
    2582              : 
    2583           11 :     if (file == NULL)
    2584              :         return DLT_RETURN_WRONG_PARAMETER;
    2585              : 
    2586              :     /* set filter */
    2587           11 :     file->filter = filter;
    2588              : 
    2589           11 :     return DLT_RETURN_OK;
    2590              : }
    2591              : 
    2592         6866 : DltReturnValue dlt_file_read_header(DltFile* file, int verbose)
    2593              : {
    2594         6866 :     PRINT_FUNCTION_VERBOSE(verbose);
    2595              : 
    2596         6866 :     if (file == NULL)
    2597              :         return DLT_RETURN_WRONG_PARAMETER;
    2598              : 
    2599              :     /* Loop until storage header is found */
    2600              :     while (1) {
    2601              :         /* load header from file */
    2602        17874 :         if (fread(file->msg.headerbuffer, sizeof(DltStorageHeader) + sizeof(DltStandardHeader), 1, file->handle) != 1) {
    2603           71 :             if (!feof(file->handle))
    2604            0 :                 dlt_log(LOG_WARNING, "Cannot read header from file!\n");
    2605              :             else
    2606           71 :                 dlt_log(LOG_DEBUG, "Reached end of file\n");
    2607              : 
    2608           71 :             return DLT_RETURN_ERROR;
    2609              :         }
    2610              : 
    2611              :         /* set ptrs to structures */
    2612         8866 :         file->msg.storageheader = (DltStorageHeader*)file->msg.headerbuffer;
    2613         8866 :         file->msg.standardheader = (DltStandardHeader*)(file->msg.headerbuffer + sizeof(DltStorageHeader));
    2614              : 
    2615              :         /* check id of storage header */
    2616         8866 :         if (dlt_check_storageheader(file->msg.storageheader) != DLT_RETURN_TRUE) {
    2617              :             /* Shift the position back to the place where it stared to read + 1 */
    2618         2071 :             if (fseek(file->handle, (long)(1 - (sizeof(DltStorageHeader) + sizeof(DltStandardHeader))), SEEK_CUR) < 0) {
    2619            0 :                 dlt_log(LOG_WARNING, "DLT storage header pattern not found!\n");
    2620            0 :                 return DLT_RETURN_ERROR;
    2621              :             }
    2622              :         } else {
    2623              :             /* storage header is found */
    2624              :             break;
    2625              :         }
    2626              :     }
    2627              : 
    2628              :     /* calculate complete size of headers */
    2629         6795 :     file->msg.headersize =
    2630         6795 :         (int32_t)(sizeof(DltStorageHeader) + sizeof(DltStandardHeader)
    2631         6795 :                   + DLT_STANDARD_HEADER_EXTRA_SIZE(file->msg.standardheader->htyp)
    2632         6795 :                   + (DLT_IS_HTYP_UEH(file->msg.standardheader->htyp) ? (uint32_t)sizeof(DltExtendedHeader) : 0U));
    2633              : 
    2634              :     /* calculate complete size of payload */
    2635              :     int32_t temp_datasize;
    2636         6795 :     temp_datasize =
    2637         6795 :         DLT_BETOH_16(file->msg.standardheader->len) + (int32_t)sizeof(DltStorageHeader) - (int32_t)file->msg.headersize;
    2638              : 
    2639              :     /* check data size */
    2640         6795 :     if (temp_datasize < 0) {
    2641            0 :         dlt_vlog(LOG_WARNING, "Plausibility check failed. Complete message size too short! (%d)\n", temp_datasize);
    2642            0 :         return DLT_RETURN_ERROR;
    2643              :     } else {
    2644         6795 :         file->msg.datasize = temp_datasize;
    2645              :     }
    2646              : 
    2647              :     /* check if verbose mode is on */
    2648         6795 :     if (verbose) {
    2649            0 :         dlt_vlog(LOG_DEBUG, "HeaderSize=%u, DataSize=%u\n", file->msg.headersize, file->msg.datasize);
    2650              :     }
    2651              : 
    2652              :     return DLT_RETURN_OK;
    2653              : }
    2654              : 
    2655            0 : DltReturnValue dlt_file_read_header_raw(DltFile* file, int resync, int verbose)
    2656              : {
    2657              :     char dltSerialHeaderBuffer[DLT_ID_SIZE];
    2658              : 
    2659            0 :     PRINT_FUNCTION_VERBOSE(verbose);
    2660              : 
    2661            0 :     if (file == NULL)
    2662              :         return DLT_RETURN_WRONG_PARAMETER;
    2663              : 
    2664              :     /* check if serial header exists, ignore if found */
    2665            0 :     if (fread(dltSerialHeaderBuffer, sizeof(dltSerialHeaderBuffer), 1, file->handle) != 1) {
    2666              :         /* cannot read serial header, not enough data available in file */
    2667            0 :         if (!feof(file->handle))
    2668            0 :             dlt_log(LOG_WARNING, "Cannot read header from file!\n");
    2669              : 
    2670            0 :         return DLT_RETURN_ERROR;
    2671              :     }
    2672              : 
    2673            0 :     if (memcmp(dltSerialHeaderBuffer, dltSerialHeader, sizeof(dltSerialHeader)) == 0) {
    2674              :         /* serial header found */
    2675              :         /* nothing to do continue reading */
    2676              : 
    2677              :     } else {
    2678              :         /* serial header not found */
    2679            0 :         if (resync) {
    2680              :             /* increase error counter */
    2681            0 :             file->error_messages++;
    2682              : 
    2683              :             /* resync to serial header */
    2684              :             do {
    2685              :                 memmove(dltSerialHeaderBuffer, dltSerialHeaderBuffer + 1, sizeof(dltSerialHeader) - 1);
    2686              : 
    2687            0 :                 if (fread(dltSerialHeaderBuffer + 3, 1, 1, file->handle) != 1)
    2688              :                     /* cannot read any data, perhaps end of file reached */
    2689              :                     return DLT_RETURN_ERROR;
    2690              : 
    2691            0 :                 if (memcmp(dltSerialHeaderBuffer, dltSerialHeader, sizeof(dltSerialHeader)) == 0)
    2692              :                     /* serial header synchronised */
    2693              :                     break;
    2694              :             } while (1);
    2695              :         } else
    2696              :             /* go back to last file position */
    2697            0 :             if (0 != fseek(file->handle, (long)file->file_position, SEEK_SET)) {
    2698              :                 return DLT_RETURN_ERROR;
    2699              :             }
    2700              :     }
    2701              : 
    2702              :     /* load header from file */
    2703            0 :     if (fread(file->msg.headerbuffer + sizeof(DltStorageHeader), sizeof(DltStandardHeader), 1, file->handle) != 1) {
    2704            0 :         if (!feof(file->handle))
    2705            0 :             dlt_log(LOG_WARNING, "Cannot read header from file!\n");
    2706              : 
    2707            0 :         return DLT_RETURN_ERROR;
    2708              :     }
    2709              : 
    2710              :     /* set ptrs to structures */
    2711            0 :     file->msg.storageheader =
    2712            0 :         (DltStorageHeader*)file->msg.headerbuffer; /* this points now to a empty storage header (filled with '0') */
    2713            0 :     file->msg.standardheader = (DltStandardHeader*)(file->msg.headerbuffer + sizeof(DltStorageHeader));
    2714              : 
    2715              :     /* Skip storage header field, fill this field with '0' */
    2716              :     memset(file->msg.storageheader, 0, sizeof(DltStorageHeader));
    2717              : 
    2718              :     /* Set storage header */
    2719            0 :     dlt_set_storageheader(file->msg.storageheader, DLT_COMMON_DUMMY_ECUID);
    2720              : 
    2721              :     /* no check for storage header id*/
    2722              : 
    2723              :     /* calculate complete size of headers */
    2724            0 :     file->msg.headersize =
    2725            0 :         (int32_t)(sizeof(DltStorageHeader) + sizeof(DltStandardHeader)
    2726            0 :                   + DLT_STANDARD_HEADER_EXTRA_SIZE(file->msg.standardheader->htyp)
    2727            0 :                   + (DLT_IS_HTYP_UEH(file->msg.standardheader->htyp) ? (uint32_t)sizeof(DltExtendedHeader) : 0U));
    2728              : 
    2729              :     /* calculate complete size of payload */
    2730              :     int32_t temp_datasize;
    2731            0 :     temp_datasize =
    2732            0 :         DLT_BETOH_16(file->msg.standardheader->len) + (int32_t)sizeof(DltStorageHeader) - (int32_t)file->msg.headersize;
    2733              : 
    2734              :     /* check data size */
    2735            0 :     if (temp_datasize < 0) {
    2736            0 :         dlt_vlog(LOG_WARNING, "Plausibility check failed. Complete message size too short! (%d)\n", temp_datasize);
    2737            0 :         return DLT_RETURN_ERROR;
    2738              :     } else {
    2739            0 :         file->msg.datasize = temp_datasize;
    2740              :     }
    2741              : 
    2742              :     /* check if verbose mode is on */
    2743            0 :     if (verbose) {
    2744            0 :         dlt_vlog(LOG_DEBUG, "HeaderSize=%u, DataSize=%u\n", file->msg.headersize, file->msg.datasize);
    2745              :     }
    2746              : 
    2747              :     return DLT_RETURN_OK;
    2748              : }
    2749              : 
    2750         4608 : DltReturnValue dlt_file_read_header_extended(DltFile* file, int verbose)
    2751              : {
    2752         4608 :     PRINT_FUNCTION_VERBOSE(verbose);
    2753              : 
    2754         4608 :     if (file == NULL)
    2755              :         return DLT_RETURN_WRONG_PARAMETER;
    2756              : 
    2757              :     /* load standard header extra parameters if used */
    2758         4608 :     if (DLT_STANDARD_HEADER_EXTRA_SIZE(file->msg.standardheader->htyp)) {
    2759         1736 :         if (fread(
    2760              :                 file->msg.headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader),
    2761              :                 DLT_STANDARD_HEADER_EXTRA_SIZE(file->msg.standardheader->htyp), 1, file->handle)
    2762              :             != 1) {
    2763            0 :             dlt_log(LOG_WARNING, "Cannot read standard header extra parameters from file!\n");
    2764            0 :             return DLT_RETURN_ERROR;
    2765              :         }
    2766              : 
    2767          868 :         dlt_message_get_extraparameters(&(file->msg), verbose);
    2768              :     }
    2769              : 
    2770              :     /* load Extended header if used */
    2771         4608 :     if (DLT_IS_HTYP_UEH(file->msg.standardheader->htyp) == 0)
    2772              :         /* there is nothing to be loaded */
    2773              :         return DLT_RETURN_OK;
    2774              : 
    2775         2276 :     if (fread(
    2776         2276 :             file->msg.headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader)
    2777         2276 :                 + DLT_STANDARD_HEADER_EXTRA_SIZE(file->msg.standardheader->htyp),
    2778              :             (DLT_IS_HTYP_UEH(file->msg.standardheader->htyp) ? sizeof(DltExtendedHeader) : 0), 1, file->handle)
    2779              :         != 1) {
    2780            0 :         dlt_log(LOG_WARNING, "Cannot read extended header from file!\n");
    2781            0 :         return DLT_RETURN_ERROR;
    2782              :     }
    2783              : 
    2784              :     /* set extended header ptr */
    2785         2276 :     if (DLT_IS_HTYP_UEH(file->msg.standardheader->htyp))
    2786         2276 :         file->msg.extendedheader =
    2787         2276 :             (DltExtendedHeader*)(file->msg.headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader)
    2788         2276 :                                  + DLT_STANDARD_HEADER_EXTRA_SIZE(file->msg.standardheader->htyp));
    2789              :     else
    2790            0 :         file->msg.extendedheader = NULL;
    2791              : 
    2792              :     return DLT_RETURN_OK;
    2793              : }
    2794              : 
    2795         3978 : DltReturnValue dlt_file_read_data(DltFile* file, int verbose)
    2796              : {
    2797         3978 :     PRINT_FUNCTION_VERBOSE(verbose);
    2798              : 
    2799         3978 :     if (file == NULL)
    2800              :         return DLT_RETURN_WRONG_PARAMETER;
    2801              : 
    2802              :     /* free last used memory for buffer */
    2803         3978 :     if (file->msg.databuffer && (file->msg.databuffersize < file->msg.datasize)) {
    2804          129 :         free(file->msg.databuffer);
    2805          129 :         file->msg.databuffer = NULL;
    2806              :     }
    2807              : 
    2808         3978 :     if (file->msg.databuffer == NULL) {
    2809              :         /* get new memory for buffer */
    2810          157 :         file->msg.databuffer = (uint8_t*)malloc((size_t)file->msg.datasize);
    2811          157 :         file->msg.databuffersize = file->msg.datasize;
    2812              :     }
    2813              : 
    2814         3978 :     if (file->msg.databuffer == NULL) {
    2815            0 :         dlt_vlog(LOG_WARNING, "Cannot allocate memory for payload buffer of size %u!\n", file->msg.datasize);
    2816            0 :         return DLT_RETURN_ERROR;
    2817              :     }
    2818              : 
    2819              :     /* load payload data from file */
    2820         7956 :     if (fread(file->msg.databuffer, (size_t)file->msg.datasize, 1, file->handle) != 1) {
    2821           52 :         if (file->msg.datasize != 0) {
    2822            0 :             dlt_vlog(LOG_WARNING, "Cannot read payload data from file of size %u!\n", file->msg.datasize);
    2823            0 :             return DLT_RETURN_ERROR;
    2824              :         }
    2825              :     }
    2826              : 
    2827              :     return DLT_RETURN_OK;
    2828              : }
    2829              : 
    2830           82 : DltReturnValue dlt_file_open(DltFile* file, const char* filename, int verbose)
    2831              : {
    2832           82 :     PRINT_FUNCTION_VERBOSE(verbose);
    2833              : 
    2834           82 :     if ((file == NULL) || (filename == NULL))
    2835              :         return DLT_RETURN_WRONG_PARAMETER;
    2836              : 
    2837              :     /* reset counters */
    2838           76 :     file->counter = 0;
    2839           76 :     file->counter_total = 0;
    2840           76 :     file->position = 0;
    2841           76 :     file->file_position = 0;
    2842           76 :     file->file_length = 0;
    2843           76 :     file->error_messages = 0;
    2844              : 
    2845           76 :     if (file->handle)
    2846           25 :         fclose(file->handle);
    2847              : 
    2848              :     /* open dlt file */
    2849           76 :     file->handle = fopen(filename, "rb");
    2850              : 
    2851           76 :     if (file->handle == NULL) {
    2852            0 :         dlt_vlog(LOG_WARNING, "File %s cannot be opened!\n", filename);
    2853            0 :         return DLT_RETURN_ERROR;
    2854              :     }
    2855              : 
    2856           76 :     if (0 != fseek(file->handle, 0, SEEK_END)) {
    2857            0 :         dlt_vlog(LOG_WARNING, "dlt_file_open: Seek failed to 0,SEEK_END");
    2858            0 :         return DLT_RETURN_ERROR;
    2859              :     }
    2860              : 
    2861           76 :     file->file_length = (uint64_t)ftell(file->handle);
    2862              : 
    2863           76 :     if (0 != fseek(file->handle, 0, SEEK_SET)) {
    2864            0 :         dlt_vlog(LOG_WARNING, "dlt_file_open: Seek failed to 0,SEEK_SET");
    2865            0 :         return DLT_RETURN_ERROR;
    2866              :     }
    2867              : 
    2868           76 :     if (verbose)
    2869              :         /* print file length */
    2870            1 :         dlt_vlog(LOG_DEBUG, "File is %" PRIu64 "bytes long\n", file->file_length);
    2871              : 
    2872              :     return DLT_RETURN_OK;
    2873              : }
    2874              : 
    2875         2888 : DltReturnValue dlt_file_read(DltFile* file, int verbose)
    2876              : {
    2877              :     long* ptr;
    2878              :     int found = DLT_RETURN_OK;
    2879              : 
    2880         2888 :     if (file == NULL)
    2881              :         return DLT_RETURN_WRONG_PARAMETER;
    2882              : 
    2883         2888 :     if (verbose)
    2884            0 :         dlt_vlog(LOG_DEBUG, "%s: Message %d:\n", __func__, file->counter_total);
    2885              : 
    2886              :     /* allocate new memory for index if number of messages exceeds a multiple of DLT_COMMON_INDEX_ALLOC (e.g.: 1000) */
    2887         2888 :     if (file->counter % DLT_COMMON_INDEX_ALLOC == 0) {
    2888          383 :         ptr = (long*)malloc(
    2889          383 :             (size_t)((file->counter / DLT_COMMON_INDEX_ALLOC) + 1) * (size_t)DLT_COMMON_INDEX_ALLOC * sizeof(long));
    2890              : 
    2891          383 :         if (ptr == NULL)
    2892              :             return DLT_RETURN_ERROR;
    2893              : 
    2894          383 :         if (file->index) {
    2895          337 :             memcpy(ptr, file->index, (size_t)(file->counter) * sizeof(long));
    2896          337 :             free(file->index);
    2897              :         }
    2898              : 
    2899          383 :         file->index = ptr;
    2900              :     }
    2901              : 
    2902              :     /* set to end of last succesful read message, because of conflicting calls to dlt_file_read and dlt_file_message */
    2903         2888 :     if (0 != fseek(file->handle, (long)file->file_position, SEEK_SET)) {
    2904            0 :         dlt_vlog(LOG_WARNING, "Seek failed to file_position %" PRIu64 "\n", file->file_position);
    2905            0 :         return DLT_RETURN_ERROR;
    2906              :     }
    2907              : 
    2908              :     /* get file position at start of DLT message */
    2909         2888 :     if (verbose)
    2910            0 :         dlt_vlog(LOG_INFO, "Position in file: %" PRIu64 "\n", file->file_position);
    2911              : 
    2912              :     /* read header */
    2913         2888 :     if (dlt_file_read_header(file, verbose) < DLT_RETURN_OK) {
    2914              :         /* go back to last position in file */
    2915           71 :         if (0 != fseek(file->handle, (long)file->file_position, SEEK_SET)) {
    2916            0 :             dlt_vlog(LOG_WARNING, "Seek failed to file_position %" PRIu64 " \n", file->file_position);
    2917              :         }
    2918           71 :         return DLT_RETURN_ERROR;
    2919              :     }
    2920              : 
    2921         2817 :     if (file->filter) {
    2922              :         /* read the extended header if filter is enabled and extended header exists */
    2923          630 :         if (dlt_file_read_header_extended(file, verbose) < DLT_RETURN_OK) {
    2924              :             /* go back to last position in file */
    2925            0 :             if (0 != fseek(file->handle, (long)file->file_position, SEEK_SET))
    2926            0 :                 dlt_vlog(LOG_WARNING, "Seek to last file pos failed!\n");
    2927              : 
    2928            0 :             return DLT_RETURN_ERROR;
    2929              :         }
    2930              : 
    2931              :         /* check the filters if message is used */
    2932          630 :         if (dlt_message_filter_check(&(file->msg), file->filter, verbose) == DLT_RETURN_TRUE) {
    2933              :             /* filter matched, consequently store current message */
    2934              :             /* store index pointer to message position in DLT file */
    2935          318 :             file->index[file->counter] = (long)file->file_position;
    2936          318 :             file->counter++;
    2937          318 :             file->position = file->counter - 1;
    2938              : 
    2939              :             found = DLT_RETURN_TRUE;
    2940              :         }
    2941              : 
    2942              :         /* skip payload data */
    2943          630 :         if (fseek(file->handle, (long)file->msg.datasize, SEEK_CUR) != 0) {
    2944              :             /* go back to last position in file */
    2945            0 :             dlt_vlog(LOG_WARNING, "Seek failed to skip payload data of size %u!\n", file->msg.datasize);
    2946              : 
    2947            0 :             if (0 != fseek(file->handle, (long)file->file_position, SEEK_SET))
    2948            0 :                 dlt_log(LOG_WARNING, "Seek back also failed!\n");
    2949              : 
    2950            0 :             return DLT_RETURN_ERROR;
    2951              :         }
    2952              :     } else {
    2953              :         /* filter is disabled */
    2954              :         /* skip additional header parameters and payload data */
    2955         2187 :         if (fseek(
    2956              :                 file->handle,
    2957         2187 :                 (long)((int32_t)file->msg.headersize - (int32_t)sizeof(DltStorageHeader)
    2958         2187 :                        - (int32_t)sizeof(DltStandardHeader) + (long)file->msg.datasize),
    2959              :                 SEEK_CUR)) {
    2960            0 :             dlt_vlog(
    2961              :                 LOG_WARNING, "Seek failed to skip extra header and payload data from file of size %u!\n",
    2962            0 :                 file->msg.headersize - (int32_t)sizeof(DltStorageHeader) - (int32_t)sizeof(DltStandardHeader)
    2963            0 :                     + file->msg.datasize);
    2964              : 
    2965              :             /* go back to last position in file */
    2966            0 :             if (fseek(file->handle, (long)file->file_position, SEEK_SET))
    2967            0 :                 dlt_log(LOG_WARNING, "Seek back also failed!\n");
    2968              : 
    2969            0 :             return DLT_RETURN_ERROR;
    2970              :         }
    2971              : 
    2972              :         /* store index pointer to message position in DLT file */
    2973         2187 :         file->index[file->counter] = (long)file->file_position;
    2974         2187 :         file->counter++;
    2975         2187 :         file->position = file->counter - 1;
    2976              : 
    2977              :         found = DLT_RETURN_TRUE;
    2978              :     }
    2979              : 
    2980              :     /* increase total message counter */
    2981         2817 :     file->counter_total++;
    2982              : 
    2983              :     /* store position to next message */
    2984         2817 :     file->file_position = (uint64_t)ftell(file->handle);
    2985              : 
    2986         2817 :     return found;
    2987              : }
    2988              : 
    2989            0 : DltReturnValue dlt_file_read_raw(DltFile* file, int resync, int verbose)
    2990              : {
    2991              :     int found = DLT_RETURN_OK;
    2992              :     long* ptr;
    2993              : 
    2994            0 :     if (verbose)
    2995            0 :         dlt_vlog(LOG_DEBUG, "%s: Message %d:\n", __func__, file->counter_total);
    2996              : 
    2997            0 :     if (file == NULL)
    2998              :         return DLT_RETURN_WRONG_PARAMETER;
    2999              : 
    3000              :     /* allocate new memory for index if number of messages exceeds a multiple of DLT_COMMON_INDEX_ALLOC (e.g.: 1000) */
    3001            0 :     if (file->counter % DLT_COMMON_INDEX_ALLOC == 0) {
    3002            0 :         ptr = (long*)malloc(
    3003            0 :             (size_t)((file->counter / DLT_COMMON_INDEX_ALLOC) + 1) * (size_t)DLT_COMMON_INDEX_ALLOC * sizeof(long));
    3004              : 
    3005            0 :         if (ptr == NULL)
    3006              :             return DLT_RETURN_ERROR;
    3007              : 
    3008            0 :         if (file->index) {
    3009            0 :             memcpy(ptr, file->index, (size_t)(file->counter) * sizeof(long));
    3010            0 :             free(file->index);
    3011              :         }
    3012              : 
    3013            0 :         file->index = ptr;
    3014              :     }
    3015              : 
    3016              :     /* set to end of last successful read message, because of conflicting calls to dlt_file_read and dlt_file_message */
    3017            0 :     if (0 != fseek(file->handle, (long)file->file_position, SEEK_SET))
    3018              :         return DLT_RETURN_ERROR;
    3019              : 
    3020              :     /* get file position at start of DLT message */
    3021            0 :     if (verbose)
    3022            0 :         dlt_vlog(LOG_DEBUG, "Position in file: %" PRIu64 "\n", file->file_position);
    3023              : 
    3024              :     /* read header */
    3025            0 :     if (dlt_file_read_header_raw(file, resync, verbose) < DLT_RETURN_OK) {
    3026              :         /* go back to last position in file */
    3027            0 :         if (0 != fseek(file->handle, (long)file->file_position, SEEK_SET))
    3028            0 :             dlt_log(LOG_WARNING, "dlt_file_read_raw, fseek failed 1\n");
    3029              : 
    3030            0 :         return DLT_RETURN_ERROR;
    3031              :     }
    3032              : 
    3033              :     /* read the extended header if filter is enabled and extended header exists */
    3034            0 :     if (dlt_file_read_header_extended(file, verbose) < DLT_RETURN_OK) {
    3035              :         /* go back to last position in file */
    3036            0 :         if (0 != fseek(file->handle, (long)file->file_position, SEEK_SET))
    3037            0 :             dlt_log(LOG_WARNING, "dlt_file_read_raw, fseek failed 2\n");
    3038              : 
    3039            0 :         return DLT_RETURN_ERROR;
    3040              :     }
    3041              : 
    3042            0 :     if (dlt_file_read_data(file, verbose) < DLT_RETURN_OK) {
    3043              :         /* go back to last position in file */
    3044            0 :         if (0 != fseek(file->handle, (long)file->file_position, SEEK_SET))
    3045            0 :             dlt_log(LOG_WARNING, "dlt_file_read_raw, fseek failed 3\n");
    3046              : 
    3047            0 :         return DLT_RETURN_ERROR;
    3048              :     }
    3049              : 
    3050              :     /* store index pointer to message position in DLT file */
    3051            0 :     file->index[file->counter] = (long)file->file_position;
    3052            0 :     file->counter++;
    3053            0 :     file->position = file->counter - 1;
    3054              : 
    3055              :     found = DLT_RETURN_TRUE;
    3056              : 
    3057              :     /* increase total message counter */
    3058            0 :     file->counter_total++;
    3059              : 
    3060              :     /* store position to next message */
    3061            0 :     file->file_position = (uint64_t)ftell(file->handle);
    3062              : 
    3063            0 :     return found;
    3064              : }
    3065              : 
    3066            0 : DltReturnValue dlt_file_close(DltFile* file, int verbose)
    3067              : {
    3068            0 :     PRINT_FUNCTION_VERBOSE(verbose);
    3069              : 
    3070            0 :     if (file == NULL)
    3071              :         return DLT_RETURN_WRONG_PARAMETER;
    3072              : 
    3073            0 :     if (file->handle)
    3074            0 :         fclose(file->handle);
    3075              : 
    3076            0 :     file->handle = NULL;
    3077              : 
    3078            0 :     return DLT_RETURN_OK;
    3079              : }
    3080              : 
    3081         3873 : DltReturnValue dlt_file_message(DltFile* file, int index, int verbose)
    3082              : {
    3083         3873 :     PRINT_FUNCTION_VERBOSE(verbose);
    3084              : 
    3085         3873 :     if (file == NULL)
    3086              :         return DLT_RETURN_WRONG_PARAMETER;
    3087              : 
    3088              :     /* check if message is in range */
    3089         3873 :     if (index < 0 || index >= file->counter) {
    3090            0 :         dlt_vlog(LOG_WARNING, "Message %d out of range!\r\n", index);
    3091            0 :         return DLT_RETURN_WRONG_PARAMETER;
    3092              :     }
    3093              : 
    3094              :     /* seek to position in file */
    3095         3873 :     if (fseek(file->handle, file->index[index], SEEK_SET) != 0) {
    3096            0 :         dlt_vlog(LOG_WARNING, "Seek to message %d to position %ld failed!\r\n", index, file->index[index]);
    3097            0 :         return DLT_RETURN_ERROR;
    3098              :     }
    3099              : 
    3100              :     /* read all header and payload */
    3101         3873 :     if (dlt_file_read_header(file, verbose) < DLT_RETURN_OK)
    3102              :         return DLT_RETURN_ERROR;
    3103              : 
    3104         3873 :     if (dlt_file_read_header_extended(file, verbose) < DLT_RETURN_OK)
    3105              :         return DLT_RETURN_ERROR;
    3106              : 
    3107         3873 :     if (dlt_file_read_data(file, verbose) < DLT_RETURN_OK)
    3108              :         return DLT_RETURN_ERROR;
    3109              : 
    3110              :     /* set current position in file */
    3111         3873 :     file->position = index;
    3112              : 
    3113         3873 :     return DLT_RETURN_OK;
    3114              : }
    3115              : 
    3116           32 : DltReturnValue dlt_file_free(DltFile* file, int verbose)
    3117              : {
    3118           32 :     PRINT_FUNCTION_VERBOSE(verbose);
    3119              : 
    3120           32 :     if (file == NULL)
    3121              :         return DLT_RETURN_WRONG_PARAMETER;
    3122              : 
    3123              :     /* delete index lost if exists */
    3124           32 :     if (file->index)
    3125           25 :         free(file->index);
    3126              : 
    3127           32 :     file->index = NULL;
    3128              : 
    3129              :     /* close file */
    3130           32 :     if (file->handle)
    3131           30 :         fclose(file->handle);
    3132              : 
    3133           32 :     file->handle = NULL;
    3134              : 
    3135           32 :     return dlt_message_free(&(file->msg), verbose);
    3136              : }
    3137              : 
    3138           17 : DltReturnValue dlt_file_free_v2(DltFile* file, int verbose)
    3139              : {
    3140           17 :     PRINT_FUNCTION_VERBOSE(verbose);
    3141              : 
    3142           17 :     if (file == NULL)
    3143              :         return DLT_RETURN_WRONG_PARAMETER;
    3144              : 
    3145              :     /* delete index lost if exists */
    3146           17 :     if (file->index)
    3147           17 :         free(file->index);
    3148              : 
    3149           17 :     file->index = NULL;
    3150              : 
    3151              :     /* close file */
    3152           17 :     if (file->handle)
    3153           17 :         fclose(file->handle);
    3154              : 
    3155           17 :     file->handle = NULL;
    3156              : 
    3157           17 :     return dlt_message_free_v2(&(file->msgv2), verbose);
    3158              : }
    3159              : 
    3160              : #if defined DLT_DAEMON_USE_FIFO_IPC || defined DLT_LIB_USE_FIFO_IPC
    3161        21003 : void dlt_log_set_fifo_basedir(const char* pipe_dir)
    3162              : {
    3163              :     strncpy(dltFifoBaseDir, pipe_dir, DLT_PATH_MAX);
    3164        21003 :     dltFifoBaseDir[DLT_PATH_MAX - 1] = 0;
    3165        21002 : }
    3166              : #endif
    3167              : 
    3168              : #ifdef DLT_SHM_ENABLE
    3169              : void dlt_log_set_shm_name(const char* env_shm_name)
    3170              : {
    3171              :     strncpy(dltShmName, env_shm_name, NAME_MAX);
    3172              :     dltShmName[NAME_MAX] = 0;
    3173              : }
    3174              : #endif
    3175              : 
    3176            0 : void dlt_print_with_attributes(bool state)
    3177              : {
    3178            0 :     print_with_attributes = state;
    3179            0 : }
    3180              : 
    3181        21012 : DltReturnValue dlt_receiver_init(DltReceiver* receiver, int fd, DltReceiverType type, int buffersize)
    3182              : {
    3183        21012 :     if (NULL == receiver)
    3184              :         return DLT_RETURN_WRONG_PARAMETER;
    3185              : 
    3186        21012 :     receiver->fd = fd;
    3187        21012 :     receiver->type = type;
    3188              : 
    3189              :     /** Reuse the receiver buffer if it exists and the buffer size
    3190              :      * is not changed. If not, free the old one and allocate a new buffer.
    3191              :      */
    3192        21012 :     if ((NULL != receiver->buffer) && (buffersize != receiver->buffersize)) {
    3193            0 :         free(receiver->buffer);
    3194            0 :         receiver->buffer = NULL;
    3195              :     }
    3196              : 
    3197        21012 :     if (NULL == receiver->buffer) {
    3198        21012 :         receiver->lastBytesRcvd = 0;
    3199        21012 :         receiver->bytesRcvd = 0;
    3200        21012 :         receiver->totalBytesRcvd = 0;
    3201        21012 :         receiver->buf = NULL;
    3202        21012 :         receiver->backup_buf = NULL;
    3203        21012 :         receiver->buffer = (char*)calloc(1, (size_t)buffersize);
    3204        21012 :         receiver->buffersize = (int32_t)buffersize;
    3205              :     }
    3206              : 
    3207        21012 :     if (NULL == receiver->buffer) {
    3208            0 :         dlt_log(LOG_ERR, "allocate memory for receiver buffer failed.\n");
    3209            0 :         return DLT_RETURN_ERROR;
    3210              :     } else {
    3211        21012 :         receiver->buf = receiver->buffer;
    3212              :     }
    3213              : 
    3214        21012 :     return DLT_RETURN_OK;
    3215              : }
    3216              : 
    3217            1 : DltReturnValue dlt_receiver_init_global_buffer(DltReceiver* receiver, int fd, DltReceiverType type, char** buffer)
    3218              : {
    3219            1 :     if (receiver == NULL)
    3220              :         return DLT_RETURN_WRONG_PARAMETER;
    3221              : 
    3222            1 :     if (*buffer == NULL) {
    3223              :         /* allocating the buffer once and using it for all application receivers
    3224              :          * by keeping allocated buffer in app_recv_buffer global handle
    3225              :          */
    3226            1 :         *buffer = (char*)malloc(DLT_RECEIVE_BUFSIZE);
    3227              : 
    3228            1 :         if (*buffer == NULL)
    3229              :             return DLT_RETURN_ERROR;
    3230              :     }
    3231              : 
    3232            1 :     receiver->lastBytesRcvd = 0;
    3233            1 :     receiver->bytesRcvd = 0;
    3234            1 :     receiver->totalBytesRcvd = 0;
    3235            1 :     receiver->buffersize = DLT_RECEIVE_BUFSIZE;
    3236            1 :     receiver->fd = fd;
    3237            1 :     receiver->type = type;
    3238            1 :     receiver->buffer = *buffer;
    3239            1 :     receiver->backup_buf = NULL;
    3240            1 :     receiver->buf = receiver->buffer;
    3241              : 
    3242            1 :     return DLT_RETURN_OK;
    3243              : }
    3244              : 
    3245        21011 : DltReturnValue dlt_receiver_free(DltReceiver* receiver)
    3246              : {
    3247        21011 :     if (receiver == NULL)
    3248              :         return DLT_RETURN_WRONG_PARAMETER;
    3249              : 
    3250        21011 :     if (receiver->buffer)
    3251        21009 :         free(receiver->buffer);
    3252              : 
    3253        21011 :     if (receiver->backup_buf)
    3254            0 :         free(receiver->backup_buf);
    3255              : 
    3256        21011 :     receiver->buffer = NULL;
    3257        21011 :     receiver->buf = NULL;
    3258        21011 :     receiver->backup_buf = NULL;
    3259              : 
    3260        21011 :     return DLT_RETURN_OK;
    3261              : }
    3262              : 
    3263            1 : DltReturnValue dlt_receiver_free_global_buffer(DltReceiver* receiver)
    3264              : {
    3265            1 :     if (receiver == NULL)
    3266              :         return DLT_RETURN_WRONG_PARAMETER;
    3267              : 
    3268            1 :     if (receiver->backup_buf)
    3269            0 :         free(receiver->backup_buf);
    3270              : 
    3271            1 :     receiver->buffer = NULL;
    3272            1 :     receiver->buf = NULL;
    3273            1 :     receiver->backup_buf = NULL;
    3274              : 
    3275            1 :     return DLT_RETURN_OK;
    3276              : }
    3277              : 
    3278          654 : int dlt_receiver_receive(DltReceiver* receiver)
    3279              : {
    3280              :     socklen_t addrlen;
    3281              : 
    3282          654 :     if (receiver == NULL)
    3283              :         return -1;
    3284              : 
    3285          654 :     if (receiver->buffer == NULL)
    3286              :         return -1;
    3287              : 
    3288          653 :     receiver->buf = (char*)receiver->buffer;
    3289          653 :     receiver->lastBytesRcvd = receiver->bytesRcvd;
    3290              : 
    3291          653 :     if ((receiver->lastBytesRcvd) && (receiver->backup_buf != NULL)) {
    3292            0 :         memcpy(receiver->buf, receiver->backup_buf, (size_t)receiver->lastBytesRcvd);
    3293            0 :         free(receiver->backup_buf);
    3294            0 :         receiver->backup_buf = NULL;
    3295              :     }
    3296              : 
    3297          653 :     if (receiver->type == DLT_RECEIVE_SOCKET) {
    3298              :         /* wait for data from socket */
    3299          367 :         ssize_t bytes = recv(
    3300          367 :             receiver->fd, receiver->buf + receiver->lastBytesRcvd,
    3301          367 :             (size_t)(receiver->buffersize - receiver->lastBytesRcvd), 0);
    3302          734 :         receiver->bytesRcvd = (bytes >= 0 && bytes <= INT32_MAX) ? (int32_t)bytes : 0;
    3303          286 :     } else if (receiver->type == DLT_RECEIVE_FD) {
    3304              :         /* wait for data from fd */
    3305          286 :         ssize_t bytes = read(
    3306          286 :             receiver->fd, receiver->buf + receiver->lastBytesRcvd,
    3307          286 :             (size_t)(receiver->buffersize - receiver->lastBytesRcvd));
    3308          572 :         receiver->bytesRcvd = (bytes >= 0 && bytes <= INT32_MAX) ? (int32_t)bytes : 0;
    3309              :     } else { /* receiver->type == DLT_RECEIVE_UDP_SOCKET */
    3310              :         /* wait for data from UDP socket */
    3311            0 :         addrlen = sizeof(receiver->addr);
    3312            0 :         ssize_t bytes = recvfrom(
    3313            0 :             receiver->fd, receiver->buf + receiver->lastBytesRcvd,
    3314            0 :             (size_t)(receiver->buffersize - receiver->lastBytesRcvd), 0, (struct sockaddr*)&(receiver->addr), &addrlen);
    3315            0 :         receiver->bytesRcvd = (bytes >= 0 && bytes <= INT32_MAX) ? (int32_t)bytes : 0;
    3316              :     }
    3317              : 
    3318          653 :     if (receiver->bytesRcvd <= 0) {
    3319            3 :         receiver->bytesRcvd = 0;
    3320            3 :         return receiver->bytesRcvd;
    3321              :     } /* if */
    3322              : 
    3323          650 :     receiver->totalBytesRcvd += receiver->bytesRcvd;
    3324          650 :     receiver->bytesRcvd += receiver->lastBytesRcvd;
    3325              : 
    3326          650 :     return receiver->bytesRcvd;
    3327              : }
    3328              : 
    3329          781 : DltReturnValue dlt_receiver_remove(DltReceiver* receiver, int size)
    3330              : {
    3331          781 :     if (receiver == NULL)
    3332              :         return DLT_RETURN_WRONG_PARAMETER;
    3333              : 
    3334          781 :     if (receiver->buf == NULL)
    3335              :         return DLT_RETURN_ERROR;
    3336              : 
    3337          781 :     if ((size > receiver->bytesRcvd) || (size <= 0)) {
    3338            0 :         receiver->buf = receiver->buf + receiver->bytesRcvd;
    3339            0 :         receiver->bytesRcvd = 0;
    3340            0 :         return DLT_RETURN_WRONG_PARAMETER;
    3341              :     }
    3342              : 
    3343          781 :     receiver->bytesRcvd = receiver->bytesRcvd - size;
    3344          336 :     receiver->buf = receiver->buf + size;
    3345              : 
    3346          781 :     return DLT_RETURN_OK;
    3347              : }
    3348              : 
    3349          650 : DltReturnValue dlt_receiver_move_to_begin(DltReceiver* receiver)
    3350              : {
    3351          650 :     if (receiver == NULL)
    3352              :         return DLT_RETURN_WRONG_PARAMETER;
    3353              : 
    3354          650 :     if ((receiver->buffer == NULL) || (receiver->buf == NULL))
    3355              :         return DLT_RETURN_ERROR;
    3356              : 
    3357          650 :     if ((receiver->buffer != receiver->buf) && (receiver->bytesRcvd != 0)) {
    3358            0 :         receiver->backup_buf = calloc((size_t)(receiver->bytesRcvd + 1), sizeof(char));
    3359              : 
    3360            0 :         if (receiver->backup_buf == NULL)
    3361            0 :             dlt_vlog(
    3362              :                 LOG_WARNING,
    3363              :                 "Can't allocate memory for backup buf, there will be atleast"
    3364              :                 "one corrupted message for fd[%d] \n",
    3365              :                 receiver->fd);
    3366              :         else
    3367            0 :             memcpy(receiver->backup_buf, receiver->buf, (size_t)receiver->bytesRcvd);
    3368              :     }
    3369              : 
    3370              :     return DLT_RETURN_OK;
    3371              : }
    3372              : 
    3373            6 : int dlt_receiver_check_and_get(DltReceiver* receiver, void* dest, unsigned int to_get, unsigned int flags)
    3374              : {
    3375            6 :     size_t min_size = (size_t)to_get;
    3376              :     uint8_t* src = NULL;
    3377              : 
    3378            6 :     if (flags & DLT_RCV_SKIP_HEADER)
    3379            3 :         min_size += sizeof(DltUserHeader);
    3380              : 
    3381            6 :     if (!receiver || (receiver->bytesRcvd < (int32_t)min_size) || !receiver->buf || !dest)
    3382              :         return DLT_RETURN_WRONG_PARAMETER;
    3383              : 
    3384              :     src = (uint8_t*)receiver->buf;
    3385              : 
    3386            6 :     if (flags & DLT_RCV_SKIP_HEADER)
    3387            3 :         src += sizeof(DltUserHeader);
    3388              : 
    3389              :     memcpy(dest, src, to_get);
    3390              : 
    3391            6 :     if (flags & DLT_RCV_REMOVE) {
    3392            0 :         if (dlt_receiver_remove(receiver, (int)min_size) != DLT_RETURN_OK) {
    3393            0 :             dlt_log(LOG_WARNING, "Can't remove bytes from receiver\n");
    3394            0 :             return DLT_RETURN_ERROR;
    3395              :         }
    3396              :     }
    3397              : 
    3398            6 :     return (int)to_get;
    3399              : }
    3400              : 
    3401         6644 : DltReturnValue dlt_set_storageheader(DltStorageHeader* storageheader, const char* ecu)
    3402              : {
    3403              : #if !defined(_MSC_VER)
    3404              :     struct timeval tv;
    3405              : #endif
    3406              : 
    3407         6644 :     if ((storageheader == NULL) || (ecu == NULL))
    3408              :         return DLT_RETURN_WRONG_PARAMETER;
    3409              : 
    3410              :         /* get time of day */
    3411              : #if defined(_MSC_VER)
    3412              :     time(&(storageheader->seconds));
    3413              : #else
    3414         6644 :     gettimeofday(&tv, NULL);
    3415              : #endif
    3416              : 
    3417              :     /* prepare storage header */
    3418         6644 :     storageheader->pattern[0] = 'D';
    3419         6644 :     storageheader->pattern[1] = 'L';
    3420         6644 :     storageheader->pattern[2] = 'T';
    3421         6644 :     storageheader->pattern[3] = 0x01;
    3422              : 
    3423         6644 :     dlt_set_id(storageheader->ecu, ecu);
    3424              : 
    3425              :     /* Set current time */
    3426              : #if defined(_MSC_VER)
    3427              :     storageheader->microseconds = 0;
    3428              : #else
    3429         6644 :     storageheader->seconds = (uint32_t)tv.tv_sec;      /* value is long */
    3430         6644 :     storageheader->microseconds = (int32_t)tv.tv_usec; /* value is long */
    3431              : #endif
    3432              : 
    3433         6644 :     return DLT_RETURN_OK;
    3434              : }
    3435              : 
    3436           21 : DltReturnValue dlt_set_storageheader_v2(DltStorageHeaderV2* storageheader, uint8_t ecuIDlen, const char* ecu)
    3437              : {
    3438              : #if !defined(_MSC_VER)
    3439              :     struct timespec ts;
    3440              : #endif
    3441              : 
    3442           21 :     if (ecu == NULL)
    3443              :         return DLT_RETURN_WRONG_PARAMETER;
    3444              : 
    3445              :         /* get time of day */
    3446              : #if defined(_MSC_VER)
    3447              :     time_t t = time(NULL);
    3448              :     storageheader->seconds[0] = (t >> 32) & 0xFF;
    3449              :     storageheader->seconds[1] = (t >> 24) & 0xFF;
    3450              :     storageheader->seconds[2] = (t >> 16) & 0xFF;
    3451              :     storageheader->seconds[3] = (t >> 8) & 0xFF;
    3452              :     storageheader->seconds[4] = t & 0xFF;
    3453              : #else
    3454              :     /* initialize in case clock_gettime fails to avoid uninitialized reads */
    3455              :     memset(&ts, 0, sizeof(ts));
    3456           21 :     if (clock_gettime(CLOCK_REALTIME, &ts) != 0) {
    3457              :         /* try fallback monotonic clock, if that also fails leave zeros */
    3458            0 :         (void)clock_gettime(CLOCK_MONOTONIC, &ts);
    3459              :     }
    3460              : #endif
    3461              : 
    3462              :     /* prepare storage header */
    3463           21 :     storageheader->pattern[0] = 'D';
    3464           21 :     storageheader->pattern[1] = 'L';
    3465           21 :     storageheader->pattern[2] = 'T';
    3466           21 :     storageheader->pattern[3] = 0x02;
    3467              : 
    3468              :     /* Set current time */
    3469              : #if defined(_MSC_VER)
    3470              :     storageheader->nanoseconds = 0;
    3471              : #else
    3472           21 :     storageheader->seconds[0] = (uint8_t)(((uint64_t)ts.tv_sec >> 32) & 0xFF);
    3473           21 :     storageheader->seconds[1] = (uint8_t)((ts.tv_sec >> 24) & 0xFF);
    3474           21 :     storageheader->seconds[2] = (uint8_t)((ts.tv_sec >> 16) & 0xFF);
    3475           21 :     storageheader->seconds[3] = (uint8_t)((ts.tv_sec >> 8) & 0xFF);
    3476           21 :     storageheader->seconds[4] = (uint8_t)(ts.tv_sec & 0xFF);
    3477           21 :     storageheader->nanoseconds = (int32_t)ts.tv_nsec; /* value is long */
    3478              : #endif
    3479              : 
    3480              : 
    3481           21 :     if (ecuIDlen == 0) {
    3482              :         return DLT_RETURN_ERROR;
    3483              :     }
    3484           21 :     storageheader->ecidlen = ecuIDlen;
    3485           21 :     dlt_set_id_v2(storageheader->ecid, ecu, ecuIDlen);
    3486              : 
    3487           21 :     return DLT_RETURN_OK;
    3488              : }
    3489              : 
    3490            2 : DltReturnValue dlt_check_rcv_data_size(int received, int required)
    3491              : {
    3492              :     int _ret = DLT_RETURN_OK;
    3493            2 :     if (received < required) {
    3494            0 :         dlt_vlog(LOG_WARNING, "%s: Received data not complete\n", __func__);
    3495              :         _ret = DLT_RETURN_ERROR;
    3496              :     }
    3497              : 
    3498            2 :     return _ret;
    3499              : }
    3500              : 
    3501         8866 : DltReturnValue dlt_check_storageheader(DltStorageHeader* storageheader)
    3502              : {
    3503         8866 :     if (storageheader == NULL)
    3504              :         return DLT_RETURN_WRONG_PARAMETER;
    3505              : 
    3506         6814 :     return ((storageheader->pattern[0] == 'D') && (storageheader->pattern[1] == 'L')
    3507         6814 :             && (storageheader->pattern[2] == 'T') && (storageheader->pattern[3] == 1)) ?
    3508        15680 :                DLT_RETURN_TRUE :
    3509              :                DLT_RETURN_OK;
    3510              : }
    3511              : 
    3512            0 : DltReturnValue dlt_check_storageheader_v2(DltStorageHeaderV2* storageheader)
    3513              : {
    3514            0 :     if (storageheader == NULL)
    3515              :         return DLT_RETURN_WRONG_PARAMETER;
    3516              : 
    3517            0 :     return ((storageheader->pattern[0] == 'D') && (storageheader->pattern[1] == 'L')
    3518            0 :             && (storageheader->pattern[2] == 'T') && (storageheader->pattern[3] == 2)) ?
    3519            0 :                DLT_RETURN_TRUE :
    3520              :                DLT_RETURN_OK;
    3521              : }
    3522              : 
    3523            0 : DltReturnValue dlt_buffer_init_static_server(DltBuffer* buf, const unsigned char* ptr, uint32_t size)
    3524              : {
    3525            0 :     if ((buf == NULL) || (ptr == NULL))
    3526              :         return DLT_RETURN_WRONG_PARAMETER;
    3527              : 
    3528              :     DltBufferHead* head;
    3529              : 
    3530              :     /* Init parameters */
    3531              :     union {
    3532              :         const unsigned char* cp;
    3533              :         unsigned char* p;
    3534              :     } shm_cast;
    3535              :     shm_cast.cp = ptr;
    3536            0 :     buf->shm = shm_cast.p;
    3537            0 :     buf->min_size = size;
    3538            0 :     buf->max_size = size;
    3539            0 :     buf->step_size = 0;
    3540              : 
    3541              :     /* Init pointers */
    3542              :     head = (DltBufferHead*)buf->shm;
    3543            0 :     head->read = 0;
    3544            0 :     head->write = 0;
    3545            0 :     head->count = 0;
    3546            0 :     buf->mem = (unsigned char*)(buf->shm + sizeof(DltBufferHead));
    3547            0 :     buf->size = (unsigned int)buf->min_size - (unsigned int)sizeof(DltBufferHead);
    3548              : 
    3549              :     /* clear memory */
    3550            0 :     memset(buf->mem, 0, buf->size);
    3551              : 
    3552            0 :     dlt_vlog(LOG_DEBUG, "%s: Buffer: Size %u, Start address %lX\n", __func__, buf->size, (unsigned long)buf->mem);
    3553              : 
    3554            0 :     return DLT_RETURN_OK; /* OK */
    3555              : }
    3556              : 
    3557            0 : DltReturnValue dlt_buffer_init_static_client(DltBuffer* buf, const unsigned char* ptr, uint32_t size)
    3558              : {
    3559            0 :     if ((buf == NULL) || (ptr == NULL))
    3560              :         return DLT_RETURN_WRONG_PARAMETER;
    3561              : 
    3562              :     /* Init parameters */
    3563              :     union {
    3564              :         const unsigned char* cp;
    3565              :         unsigned char* p;
    3566              :     } shm_cast;
    3567              :     shm_cast.cp = ptr;
    3568            0 :     buf->shm = shm_cast.p;
    3569            0 :     buf->min_size = size;
    3570            0 :     buf->max_size = size;
    3571            0 :     buf->step_size = 0;
    3572              : 
    3573              :     /* Init pointers */
    3574            0 :     buf->mem = (unsigned char*)(buf->shm + sizeof(DltBufferHead));
    3575            0 :     buf->size = (uint32_t)(buf->min_size - sizeof(DltBufferHead));
    3576              : 
    3577            0 :     dlt_vlog(LOG_DEBUG, "%s: Buffer: Size %u, Start address %lX\n", __func__, buf->size, (unsigned long)buf->mem);
    3578              : 
    3579            0 :     return DLT_RETURN_OK; /* OK */
    3580              : }
    3581              : 
    3582        21136 : DltReturnValue dlt_buffer_init_dynamic(DltBuffer* buf, uint32_t min_size, uint32_t max_size, uint32_t step_size)
    3583              : {
    3584              :     /*Do not dlt_mutex_lock inside here! */
    3585              :     DltBufferHead* head;
    3586              : 
    3587              :     /* catch null pointer */
    3588        21136 :     if (buf == NULL)
    3589              :         return DLT_RETURN_WRONG_PARAMETER;
    3590              : 
    3591              :     /* catch 0 logical errors */
    3592        21128 :     if ((min_size == 0) || (max_size == 0) || (step_size == 0))
    3593              :         return DLT_RETURN_WRONG_PARAMETER;
    3594              : 
    3595        21119 :     if (min_size > max_size)
    3596              :         return DLT_RETURN_WRONG_PARAMETER;
    3597              : 
    3598        21117 :     if (step_size > max_size)
    3599              :         return DLT_RETURN_WRONG_PARAMETER;
    3600              : 
    3601              :     /* Init parameters */
    3602        21117 :     buf->min_size = min_size;
    3603        21117 :     buf->max_size = max_size;
    3604        21117 :     buf->step_size = step_size;
    3605              : 
    3606              :     /* allocat memory */
    3607        21117 :     buf->shm = malloc(buf->min_size);
    3608              : 
    3609        21117 :     if (buf->shm == NULL) {
    3610            0 :         dlt_vlog(LOG_EMERG, "%s: Buffer: Cannot allocate %u bytes\n", __func__, buf->min_size);
    3611            0 :         return DLT_RETURN_ERROR;
    3612              :     }
    3613              : 
    3614              :     /* Init pointers */
    3615              :     head = (DltBufferHead*)buf->shm;
    3616        21117 :     head->read = 0;
    3617        21117 :     head->write = 0;
    3618        21117 :     head->count = 0;
    3619        21117 :     buf->mem = (unsigned char*)(buf->shm + sizeof(DltBufferHead));
    3620              : 
    3621        21117 :     if (buf->min_size < (uint32_t)sizeof(DltBufferHead)) {
    3622            0 :         dlt_vlog(LOG_ERR, "%s: min_size is too small [%u]\n", __func__, buf->min_size);
    3623            0 :         return DLT_RETURN_WRONG_PARAMETER;
    3624              :     }
    3625              : 
    3626        21117 :     buf->size = (uint32_t)(buf->min_size - sizeof(DltBufferHead));
    3627              : 
    3628        21117 :     dlt_vlog(LOG_DEBUG, "%s: Buffer: Size %u, Start address %lX\n", __func__, buf->size, (unsigned long)buf->mem);
    3629              : 
    3630              :     /* clear memory */
    3631        21117 :     memset(buf->mem, 0, (size_t)buf->size);
    3632              : 
    3633        21117 :     return DLT_RETURN_OK; /* OK */
    3634              : }
    3635              : 
    3636            0 : DltReturnValue dlt_buffer_free_static(DltBuffer* buf)
    3637              : {
    3638              :     /* catch null pointer */
    3639            0 :     if (buf == NULL)
    3640              :         return DLT_RETURN_WRONG_PARAMETER;
    3641              : 
    3642            0 :     if (buf->mem == NULL) {
    3643              :         /* buffer not initialized */
    3644            0 :         dlt_vlog(LOG_WARNING, "%s: Buffer: Buffer not initialized\n", __func__);
    3645            0 :         return DLT_RETURN_ERROR; /* ERROR */
    3646              :     }
    3647              : 
    3648              :     return DLT_RETURN_OK;
    3649              : }
    3650              : 
    3651        21106 : DltReturnValue dlt_buffer_free_dynamic(DltBuffer* buf)
    3652              : {
    3653              :     /* catch null pointer */
    3654        21106 :     if (buf == NULL)
    3655              :         return DLT_RETURN_WRONG_PARAMETER;
    3656              : 
    3657        21105 :     if (buf->shm == NULL) {
    3658              :         /* buffer not initialized */
    3659            0 :         dlt_vlog(LOG_WARNING, "%s: Buffer: Buffer not initialized\n", __func__);
    3660            0 :         return DLT_RETURN_ERROR; /* ERROR */
    3661              :     }
    3662              : 
    3663        21105 :     free(buf->shm);
    3664        21105 :     buf->shm = NULL;
    3665        21105 :     buf->mem = NULL;
    3666              : 
    3667        21105 :     return DLT_RETURN_OK;
    3668              : }
    3669              : 
    3670        41217 : void dlt_buffer_write_block(DltBuffer* buf, int* write, const unsigned char* data, unsigned int size)
    3671              : {
    3672              :     /* catch null pointer */
    3673        41217 :     if ((buf != NULL) && (write != NULL) && (data != NULL)) {
    3674        40198 :         if (size <= buf->size) {
    3675        40198 :             if (((unsigned int)(*write) + size) <= buf->size) {
    3676              :                 /* write one block */
    3677        40197 :                 memcpy(buf->mem + *write, data, size);
    3678        40197 :                 *write += (int)size;
    3679              :             } else {
    3680              :                 /* when (*write) = buf->size, write only the second block
    3681              :                  * and update write position correspondingly.
    3682              :                  */
    3683            1 :                 if ((unsigned int)(*write) <= buf->size) {
    3684              :                     /* write two blocks */
    3685            1 :                     memcpy(buf->mem + *write, data, buf->size - (unsigned int)(*write));
    3686            1 :                     memcpy(buf->mem, data + buf->size - *write, size - buf->size + (unsigned int)(*write));
    3687            1 :                     *write += (int)(size - buf->size);
    3688              :                 }
    3689              :             }
    3690              :         } else {
    3691            0 :             dlt_vlog(LOG_WARNING, "%s: Write error: ring buffer to small\n", __func__);
    3692              :         }
    3693              :     } else {
    3694         1019 :         dlt_vlog(LOG_WARNING, "%s: Wrong parameter: Null pointer\n", __func__);
    3695              :     }
    3696        41217 : }
    3697              : 
    3698           39 : void dlt_buffer_read_block(DltBuffer* buf, int* read, unsigned char* data, unsigned int size)
    3699              : {
    3700              :     /* catch nullpointer */
    3701           39 :     if ((buf != NULL) && (read != NULL) && (data != NULL)) {
    3702           23 :         if (((unsigned int)(*read) + size) <= buf->size) {
    3703              :             /* read one block */
    3704           21 :             memcpy(data, buf->mem + *read, size);
    3705           21 :             *read += (int)size;
    3706              :         } else {
    3707              :             /* when (*read) = buf->size, read only the second block
    3708              :              * and update read position correspondingly.
    3709              :              */
    3710            2 :             if ((unsigned int)(*read) <= buf->size) {
    3711              :                 /* read two blocks */
    3712            1 :                 memcpy(data, buf->mem + *read, buf->size - (unsigned int)(*read));
    3713            1 :                 memcpy(data + buf->size - *read, buf->mem, size - buf->size + (unsigned int)(*read));
    3714            1 :                 *read += (int)(size - buf->size);
    3715              :             }
    3716              :         }
    3717              :     } else {
    3718           16 :         dlt_vlog(LOG_WARNING, "%s: Wrong parameter: Null pointer\n", __func__);
    3719              :     }
    3720           39 : }
    3721              : 
    3722         1462 : DltReturnValue dlt_buffer_check_size(DltBuffer* buf, int needed)
    3723              : {
    3724         1462 :     if (buf == NULL)
    3725              :         return DLT_RETURN_WRONG_PARAMETER;
    3726              : 
    3727         1462 :     if ((buf->size + sizeof(DltBufferHead) + (size_t)needed) > buf->max_size)
    3728            0 :         return DLT_RETURN_ERROR;
    3729              : 
    3730              :     return DLT_RETURN_OK;
    3731              : }
    3732              : 
    3733           13 : int dlt_buffer_increase_size(DltBuffer* buf)
    3734              : {
    3735              :     DltBufferHead *head, *new_head;
    3736              :     unsigned char* new_ptr;
    3737              : 
    3738              :     /* catch null pointer */
    3739           13 :     if (buf == NULL) {
    3740            1 :         dlt_vlog(LOG_WARNING, "%s: Wrong parameter: Null pointer\n", __func__);
    3741            1 :         return DLT_RETURN_WRONG_PARAMETER;
    3742              :     }
    3743              : 
    3744              :     /* check size */
    3745           12 :     if (buf->step_size == 0)
    3746              :         /* cannot increase size */
    3747              :         return DLT_RETURN_ERROR;
    3748              : 
    3749              :     /* check size */
    3750           11 :     if ((buf->size + sizeof(DltBufferHead) + buf->step_size) > buf->max_size)
    3751              :         /* max size reached, do not increase */
    3752              :         return DLT_RETURN_ERROR;
    3753              : 
    3754              :     /* allocate new buffer */
    3755           10 :     new_ptr = malloc(buf->size + sizeof(DltBufferHead) + buf->step_size);
    3756              : 
    3757           10 :     if (new_ptr == NULL) {
    3758            0 :         dlt_vlog(
    3759              :             LOG_WARNING, "%s: Buffer: Cannot increase size because allocate %u bytes failed\n", __func__,
    3760              :             buf->min_size);
    3761            0 :         return DLT_RETURN_ERROR;
    3762              :     }
    3763              : 
    3764              :     /* copy data */
    3765           10 :     head = (DltBufferHead*)buf->shm;
    3766              :     new_head = (DltBufferHead*)new_ptr;
    3767              : 
    3768           10 :     if (head->read < head->write) {
    3769            8 :         memcpy(new_ptr + sizeof(DltBufferHead), buf->mem + head->read, (size_t)(head->write - head->read));
    3770            8 :         new_head->read = 0;
    3771            8 :         new_head->write = head->write - head->read;
    3772            8 :         new_head->count = head->count;
    3773              :     } else {
    3774            2 :         memcpy(new_ptr + sizeof(DltBufferHead), buf->mem + head->read, buf->size - (uint32_t)(head->read));
    3775            2 :         memcpy(new_ptr + sizeof(DltBufferHead) + buf->size - head->read, buf->mem, (size_t)head->write);
    3776            2 :         new_head->read = 0;
    3777            2 :         new_head->write = (int)(buf->size) + head->write - head->read;
    3778            2 :         new_head->count = head->count;
    3779              :     }
    3780              : 
    3781              :     /* free old data */
    3782           10 :     free(buf->shm);
    3783              : 
    3784              :     /* update data */
    3785           10 :     buf->shm = new_ptr;
    3786           10 :     buf->mem = new_ptr + sizeof(DltBufferHead);
    3787           10 :     buf->size += buf->step_size;
    3788              : 
    3789           10 :     dlt_vlog(
    3790              :         LOG_DEBUG, "%s: Buffer: Size increased to %u bytes with start address %lX\n", __func__,
    3791              :         buf->size + (int32_t)sizeof(DltBufferHead), (unsigned long)buf->mem);
    3792              : 
    3793           10 :     return DLT_RETURN_OK; /* OK */
    3794              : }
    3795              : 
    3796            7 : int dlt_buffer_minimize_size(DltBuffer* buf)
    3797              : {
    3798              :     unsigned char* new_ptr;
    3799              : 
    3800              :     /* catch null pointer */
    3801            7 :     if (buf == NULL) {
    3802            1 :         dlt_vlog(LOG_WARNING, "%s: Wrong parameter: Null pointer\n", __func__);
    3803            1 :         return DLT_RETURN_WRONG_PARAMETER;
    3804              :     }
    3805              : 
    3806            6 :     if ((buf->size + sizeof(DltBufferHead)) == buf->min_size)
    3807              :         /* already minimized */
    3808              :         return DLT_RETURN_OK;
    3809              : 
    3810              :     /* allocate new buffer */
    3811            0 :     new_ptr = malloc(buf->min_size);
    3812              : 
    3813            0 :     if (new_ptr == NULL) {
    3814            0 :         dlt_vlog(LOG_WARNING, "%s: Buffer: Cannot set to min size of %u bytes\n", __func__, buf->min_size);
    3815            0 :         return DLT_RETURN_ERROR;
    3816              :     }
    3817              : 
    3818              :     /* free old data */
    3819            0 :     free(buf->shm);
    3820              : 
    3821              :     /* update data */
    3822            0 :     buf->shm = new_ptr;
    3823            0 :     buf->mem = new_ptr + sizeof(DltBufferHead);
    3824            0 :     buf->size = (uint32_t)(buf->min_size - sizeof(DltBufferHead));
    3825              : 
    3826              :     /* reset pointers and counters */
    3827            0 :     ((int*)(buf->shm))[0] = 0; /* pointer to write memory */
    3828            0 :     ((int*)(buf->shm))[1] = 0; /* pointer to read memory */
    3829            0 :     ((int*)(buf->shm))[2] = 0; /* number of packets */
    3830              : 
    3831            0 :     dlt_vlog(
    3832              :         LOG_DEBUG, "%s: Buffer: Buffer minimized to Size %u bytes with start address %lX\n", __func__, buf->size,
    3833              :         (unsigned long)buf->mem);
    3834              : 
    3835              :     /* clear memory */
    3836            0 :     memset(buf->mem, 0, buf->size);
    3837              : 
    3838            0 :     return DLT_RETURN_OK; /* OK */
    3839              : }
    3840              : 
    3841            9 : int dlt_buffer_reset(DltBuffer* buf)
    3842              : {
    3843              :     /* catch null pointer */
    3844            9 :     if (buf == NULL) {
    3845            1 :         dlt_vlog(LOG_WARNING, "%s: Wrong parameter: Null pointer\n", __func__);
    3846            1 :         return DLT_RETURN_WRONG_PARAMETER;
    3847              :     }
    3848              : 
    3849            8 :     dlt_vlog(
    3850              :         LOG_WARNING, "%s: Buffer: Buffer reset triggered. Size: %u, Start address: %lX\n", __func__, buf->size,
    3851            8 :         (unsigned long)buf->mem);
    3852              : 
    3853              :     /* reset pointers and counters */
    3854            8 :     ((int*)(buf->shm))[0] = 0; /* pointer to write memory */
    3855            8 :     ((int*)(buf->shm))[1] = 0; /* pointer to read memory */
    3856            8 :     ((int*)(buf->shm))[2] = 0; /* number of packets */
    3857              : 
    3858              :     /* clear memory */
    3859            8 :     memset(buf->mem, 0, buf->size);
    3860              : 
    3861            8 :     return DLT_RETURN_OK; /* OK */
    3862              : }
    3863              : 
    3864        13775 : DltReturnValue dlt_buffer_push(DltBuffer* buf, const unsigned char* data, unsigned int size)
    3865              : {
    3866        13775 :     return dlt_buffer_push3(buf, data, size, 0, 0, 0, 0);
    3867              : }
    3868              : 
    3869        17138 : DltReturnValue dlt_buffer_push3(
    3870              :     DltBuffer* buf, const unsigned char* data1, unsigned int size1, const unsigned char* data2, unsigned int size2,
    3871              :     const unsigned char* data3, unsigned int size3)
    3872              : {
    3873              :     int free_size;
    3874              :     int write, read, count;
    3875              :     DltBufferBlockHead head;
    3876              : 
    3877              :     /* catch null pointer */
    3878        17138 :     if (buf == NULL)
    3879              :         return DLT_RETURN_WRONG_PARAMETER;
    3880              : 
    3881        17070 :     if (buf->shm == NULL) {
    3882              :         /* buffer not initialised */
    3883            0 :         dlt_vlog(LOG_ERR, "%s: Buffer: Buffer not initialized\n", __func__);
    3884            0 :         return DLT_RETURN_ERROR; /* ERROR */
    3885              :     }
    3886              : 
    3887              :     /* get current write pointer */
    3888        17070 :     write = ((int*)(buf->shm))[0];
    3889        17070 :     read = ((int*)(buf->shm))[1];
    3890        17070 :     count = ((int*)(buf->shm))[2];
    3891              : 
    3892              :     /* check pointers */
    3893        17070 :     if (((unsigned int)read > buf->size) || ((unsigned int)write > buf->size)) {
    3894            0 :         dlt_vlog(
    3895              :             LOG_ERR, "%s: Buffer: Pointer out of range. Read: %d, Write: %d, Size: %u\n", __func__, read, write,
    3896              :             buf->size);
    3897            0 :         dlt_buffer_reset(buf);
    3898            0 :         return DLT_RETURN_ERROR; /* ERROR */
    3899              :     }
    3900              : 
    3901              :     /* calculate free size */
    3902        17070 :     if (read > write)
    3903            0 :         free_size = read - write;
    3904        17070 :     else if (count && (write == read))
    3905              :         free_size = 0;
    3906              :     else
    3907        17070 :         free_size = (int)buf->size - write + read;
    3908              : 
    3909              :     /* check size */
    3910        17078 :     while (free_size < (int)(sizeof(DltBufferBlockHead) + size1 + size2 + size3)) {
    3911              :         /* try to increase size if possible */
    3912            8 :         if (dlt_buffer_increase_size(buf))
    3913              :             /* increase size is not possible */
    3914              :             /*dlt_log(LOG_ERR, "Buffer: Buffer is full\n"); */
    3915              :             return DLT_RETURN_ERROR; /* ERROR */
    3916              : 
    3917              :         /* update pointers */
    3918            8 :         write = ((int*)(buf->shm))[0];
    3919            8 :         read = ((int*)(buf->shm))[1];
    3920              : 
    3921              :         /* update free size */
    3922            8 :         if (read > write)
    3923            0 :             free_size = read - write;
    3924            8 :         else if (count && (write == read))
    3925              :             free_size = 0;
    3926              :         else
    3927            8 :             free_size = (int)((unsigned int)buf->size - (unsigned int)write + (unsigned int)read);
    3928              :     }
    3929              : 
    3930              :     /* set header */
    3931              :     strncpy(head.head, DLT_BUFFER_HEAD, 4);
    3932              :     head.head[3] = 0;
    3933        17070 :     head.status = 2;
    3934        17070 :     head.size = (int)(size1 + size2 + size3);
    3935              : 
    3936              :     /* write data */
    3937        17070 :     dlt_buffer_write_block(buf, &write, (unsigned char*)&head, sizeof(DltBufferBlockHead));
    3938              : 
    3939        17070 :     if (size1)
    3940        17070 :         dlt_buffer_write_block(buf, &write, data1, size1);
    3941              : 
    3942        17070 :     if (size2)
    3943         3298 :         dlt_buffer_write_block(buf, &write, data2, size2);
    3944              : 
    3945        17070 :     if (size3)
    3946         2759 :         dlt_buffer_write_block(buf, &write, data3, size3);
    3947              : 
    3948              :     /* update global shm pointers */
    3949        17070 :     ((int*)(buf->shm))[0] = write; /* set new write pointer */
    3950        17070 :     ((int*)(buf->shm))[2] += 1;    /* increase counter */
    3951              : 
    3952        17070 :     return DLT_RETURN_OK; /* OK */
    3953              : }
    3954              : 
    3955           55 : int dlt_buffer_get(DltBuffer* buf, unsigned char* data, int max_size, int delete)
    3956              : {
    3957              :     int used_size;
    3958              :     int write, read, count;
    3959           55 :     char head_compare[] = DLT_BUFFER_HEAD;
    3960              :     DltBufferBlockHead head;
    3961              : 
    3962              :     /* catch null pointer */
    3963           55 :     if (buf == NULL)
    3964              :         return DLT_RETURN_WRONG_PARAMETER;
    3965              : 
    3966           38 :     if (buf->shm == NULL) {
    3967              :         /* shm not initialised */
    3968            0 :         dlt_vlog(LOG_ERR, "%s: Buffer: SHM not initialized\n", __func__);
    3969            0 :         return DLT_RETURN_ERROR; /* ERROR */
    3970              :     }
    3971              : 
    3972              :     /* get current write pointer */
    3973           38 :     write = ((int*)(buf->shm))[0];
    3974           38 :     read = ((int*)(buf->shm))[1];
    3975           38 :     count = ((int*)(buf->shm))[2];
    3976              : 
    3977              :     /* check pointers */
    3978           38 :     if (((unsigned int)read > buf->size) || ((unsigned int)write > buf->size) || (count < 0)) {
    3979            3 :         dlt_vlog(
    3980              :             LOG_ERR, "%s: Buffer: Pointer out of range. Read: %d, Write: %d, Count: %d, Size: %u\n", __func__, read,
    3981              :             write, count, buf->size);
    3982            3 :         dlt_buffer_reset(buf);
    3983            3 :         return DLT_RETURN_ERROR; /* ERROR */
    3984              :     }
    3985              : 
    3986              :     /* check if data is in there */
    3987           35 :     if (count == 0) {
    3988           22 :         if (write != read) {
    3989            1 :             dlt_vlog(
    3990              :                 LOG_ERR, "%s: Buffer: SHM should be empty, but is not. Read: %d, Write: %d\n", __func__, read, write);
    3991            1 :             dlt_buffer_reset(buf);
    3992              :         }
    3993              : 
    3994           22 :         return DLT_RETURN_ERROR; /* ERROR */
    3995              :     }
    3996              : 
    3997              :     /* calculate used size */
    3998           13 :     if (write > read)
    3999           12 :         used_size = write - read;
    4000              :     else
    4001            1 :         used_size = (int)buf->size - read + write;
    4002              : 
    4003              :     /* first check size */
    4004           13 :     if (used_size < (int)(sizeof(DltBufferBlockHead))) {
    4005            1 :         dlt_vlog(
    4006              :             LOG_ERR, "%s: Buffer: Used size is smaller than buffer block header size. Used size: %d\n", __func__,
    4007              :             used_size);
    4008            1 :         dlt_buffer_reset(buf);
    4009            1 :         return DLT_RETURN_ERROR; /* ERROR */
    4010              :     }
    4011              : 
    4012              :     /* read header */
    4013           12 :     dlt_buffer_read_block(buf, &read, (unsigned char*)&head, sizeof(DltBufferBlockHead));
    4014              : 
    4015              :     /* check header */
    4016           12 :     if (memcmp((unsigned char*)(head.head), head_compare, sizeof(head_compare)) != 0) {
    4017            1 :         dlt_vlog(LOG_ERR, "%s: Buffer: Header head check failed\n", __func__);
    4018            1 :         dlt_buffer_reset(buf);
    4019            1 :         return DLT_RETURN_ERROR; /* ERROR */
    4020              :     }
    4021              : 
    4022           11 :     if (head.status != 2) {
    4023            0 :         dlt_vlog(LOG_ERR, "%s: Buffer: Header status check failed\n", __func__);
    4024            0 :         dlt_buffer_reset(buf);
    4025            0 :         return DLT_RETURN_ERROR; /* ERROR */
    4026              :     }
    4027              : 
    4028              :     /* second check size */
    4029           11 :     if (used_size < ((int)sizeof(DltBufferBlockHead) + head.size)) {
    4030            1 :         dlt_vlog(
    4031              :             LOG_ERR,
    4032              :             "%s: Buffer: Used size is smaller than buffer block header size And read header size. Used size: %d\n",
    4033              :             __func__, used_size);
    4034            1 :         dlt_buffer_reset(buf);
    4035            1 :         return DLT_RETURN_ERROR; /* ERROR */
    4036              :     }
    4037              : 
    4038              :     /* third check size */
    4039           10 :     if (max_size && (head.size > max_size))
    4040            1 :         dlt_vlog(
    4041              :             LOG_WARNING, "%s: Buffer: Max size is smaller than read header size. Max size: %d\n", __func__, max_size);
    4042              : 
    4043              :     /* nothing to do but data does not fit provided buffer */
    4044              : 
    4045           10 :     if ((data != NULL) && max_size) {
    4046              :         /* read data */
    4047            9 :         dlt_buffer_read_block(buf, &read, data, (unsigned int)head.size);
    4048              : 
    4049            9 :         if (delete)
    4050              :             /* update buffer pointers */
    4051            3 :             ((int*)(buf->shm))[1] = read; /* set new read pointer */
    4052              : 
    4053            1 :     } else if (delete) {
    4054            1 :         if ((unsigned int)(read + head.size) <= buf->size)
    4055            1 :             ((int*)(buf->shm))[1] = read + head.size; /* set new read pointer */
    4056              :         else
    4057            0 :             ((int*)(buf->shm))[1] = read + head.size - (int)buf->size; /* set new read pointer */
    4058              :     }
    4059              : 
    4060            4 :     if (delete) {
    4061            4 :         ((int*)(buf->shm))[2] -= 1; /* decrease counter */
    4062              : 
    4063            4 :         if (((int*)(buf->shm))[2] == 0)
    4064              :             /* try to minimize size */
    4065            3 :             dlt_buffer_minimize_size(buf);
    4066              :     }
    4067              : 
    4068           10 :     return head.size; /* OK */
    4069              : }
    4070              : 
    4071            8 : int dlt_buffer_pull(DltBuffer* buf, unsigned char* data, int max_size)
    4072              : {
    4073            8 :     return dlt_buffer_get(buf, data, max_size, 1);
    4074              : }
    4075              : 
    4076            8 : int dlt_buffer_copy(DltBuffer* buf, unsigned char* data, int max_size)
    4077              : {
    4078            8 :     return dlt_buffer_get(buf, data, max_size, 0);
    4079              : }
    4080              : 
    4081            3 : int dlt_buffer_remove(DltBuffer* buf)
    4082              : {
    4083            3 :     return dlt_buffer_get(buf, 0, 0, 1);
    4084              : }
    4085              : 
    4086            2 : void dlt_buffer_info(DltBuffer* buf)
    4087              : {
    4088              :     /* check nullpointer */
    4089            2 :     if (buf == NULL) {
    4090            1 :         dlt_vlog(LOG_WARNING, "%s: Wrong parameter: Null pointer\n", __func__);
    4091            1 :         return;
    4092              :     }
    4093              : 
    4094            1 :     dlt_vlog(
    4095              :         LOG_DEBUG,
    4096              :         "Buffer: Available size: %u, Buffer: Buffer full start address: %lX, Buffer: Buffer start address: %lX\n",
    4097            1 :         buf->size, (unsigned long)buf->shm, (unsigned long)buf->mem);
    4098              : }
    4099              : 
    4100            2 : void dlt_buffer_status(DltBuffer* buf)
    4101              : {
    4102              :     int write, read, count;
    4103              : 
    4104              :     /* check nullpointer */
    4105            2 :     if (buf == NULL) {
    4106            1 :         dlt_vlog(LOG_WARNING, "%s: Wrong parameter: Null pointer\n", __func__);
    4107            1 :         return;
    4108              :     }
    4109              : 
    4110              :     /* check if buffer available */
    4111            1 :     if (buf->shm == NULL)
    4112              :         return;
    4113              : 
    4114            1 :     write = ((int*)(buf->shm))[0];
    4115            1 :     read = ((int*)(buf->shm))[1];
    4116            1 :     count = ((int*)(buf->shm))[2];
    4117              : 
    4118            1 :     dlt_vlog(LOG_DEBUG, "Buffer: Write: %d, Read: %d, Count: %d\n", write, read, count);
    4119              : }
    4120              : 
    4121            3 : uint32_t dlt_buffer_get_total_size(DltBuffer* buf)
    4122              : {
    4123              :     /* catch null pointer */
    4124            3 :     if (buf == NULL)
    4125              :         return (uint32_t)DLT_RETURN_WRONG_PARAMETER;
    4126              : 
    4127            2 :     return buf->max_size;
    4128              : }
    4129              : 
    4130         2503 : int dlt_buffer_get_used_size(DltBuffer* buf)
    4131              : {
    4132              :     int write, read, count;
    4133              : 
    4134              :     /* catch null pointer */
    4135         2503 :     if (buf == NULL)
    4136              :         return DLT_RETURN_WRONG_PARAMETER;
    4137              : 
    4138              :     /* check if buffer available */
    4139         2502 :     if (buf->shm == NULL)
    4140              :         return DLT_RETURN_OK;
    4141              : 
    4142         2502 :     write = ((int*)(buf->shm))[0];
    4143         2502 :     read = ((int*)(buf->shm))[1];
    4144         2502 :     count = ((int*)(buf->shm))[2];
    4145              : 
    4146         2502 :     if (count == 0)
    4147              :         return DLT_RETURN_OK;
    4148              : 
    4149         2501 :     if (write > read)
    4150         2501 :         return write - read;
    4151              : 
    4152            0 :     return (int)buf->size - read + write;
    4153              : }
    4154              : 
    4155         8910 : int dlt_buffer_get_message_count(DltBuffer* buf)
    4156              : {
    4157              :     /* catch null pointer */
    4158         8910 :     if (buf == NULL)
    4159              :         return DLT_RETURN_WRONG_PARAMETER;
    4160              : 
    4161              :     /* check if buffer available */
    4162         8910 :     if (buf->shm == NULL)
    4163              :         return DLT_RETURN_OK;
    4164              : 
    4165         8910 :     return ((int*)(buf->shm))[2];
    4166              : }
    4167              : 
    4168              : #if !defined(__WIN32__)
    4169              : 
    4170            0 : DltReturnValue dlt_setup_serial(int fd, speed_t speed)
    4171              : {
    4172              : #if !defined(__WIN32__) && !defined(_MSC_VER)
    4173              :     struct termios config;
    4174              : 
    4175            0 :     if (isatty(fd) == 0)
    4176              :         return DLT_RETURN_ERROR;
    4177              : 
    4178            0 :     if (tcgetattr(fd, &config) < 0)
    4179              :         return DLT_RETURN_ERROR;
    4180              : 
    4181              :     /* Input flags - Turn off input processing
    4182              :      * convert break to null byte, no CR to NL translation,
    4183              :      * no NL to CR translation, don't mark parity errors or breaks
    4184              :      * no input parity check, don't strip high bit off,
    4185              :      * no XON/XOFF software flow control
    4186              :      */
    4187            0 :     config.c_iflag &= (tcflag_t) ~(IGNBRK | BRKINT | ICRNL | INLCR | PARMRK | INPCK | ISTRIP | IXON);
    4188              : 
    4189              :     /* Output flags - Turn off output processing
    4190              :      * no CR to NL translation, no NL to CR-NL translation,
    4191              :      * no NL to CR translation, no column 0 CR suppression,
    4192              :      * no Ctrl-D suppression, no fill characters, no case mapping,
    4193              :      * no local output processing
    4194              :      *
    4195              :      * config.c_oflag &= ~(OCRNL | ONLCR | ONLRET |
    4196              :      *                     ONOCR | ONOEOT| OFILL | OLCUC | OPOST);
    4197              :      */
    4198            0 :     config.c_oflag = 0;
    4199              : 
    4200              :     /* No line processing:
    4201              :      * echo off, echo newline off, canonical mode off,
    4202              :      * extended input processing off, signal chars off
    4203              :      */
    4204            0 :     config.c_lflag &= (tcflag_t) ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG);
    4205              : 
    4206              :     /* Turn off character processing
    4207              :      * clear current char size mask, no parity checking,
    4208              :      * no output processing, force 8 bit input
    4209              :      */
    4210            0 :     config.c_cflag &= (tcflag_t) ~(CSIZE | PARENB);
    4211            0 :     config.c_cflag |= CS8;
    4212              : 
    4213              :     /* One input byte is enough to return from read()
    4214              :      * Inter-character timer off
    4215              :      */
    4216            0 :     config.c_cc[VMIN] = 1;
    4217            0 :     config.c_cc[VTIME] = 0;
    4218              : 
    4219              :     /* Communication speed (simple version, using the predefined
    4220              :      * constants)
    4221              :      */
    4222            0 :     if ((cfsetispeed(&config, speed) < 0) || (cfsetospeed(&config, speed) < 0))
    4223            0 :         return DLT_RETURN_ERROR;
    4224              : 
    4225              :     /* Finally, apply the configuration
    4226              :      */
    4227            0 :     if (tcsetattr(fd, TCSAFLUSH, &config) < 0)
    4228              :         return DLT_RETURN_ERROR;
    4229              : 
    4230              :     return DLT_RETURN_OK;
    4231              : #else
    4232              :     return DLT_RETURN_ERROR;
    4233              : #endif
    4234              : }
    4235              : 
    4236            0 : speed_t dlt_convert_serial_speed(int baudrate)
    4237              : {
    4238              : #if !defined(__WIN32__) && !defined(_MSC_VER) && !defined(__CYGWIN__)
    4239              :     speed_t ret;
    4240              : 
    4241            0 :     switch (baudrate) {
    4242              :     case 50: {
    4243              :         ret = B50;
    4244              :         break;
    4245              :     }
    4246            0 :     case 75: {
    4247              :         ret = B75;
    4248            0 :         break;
    4249              :     }
    4250            0 :     case 110: {
    4251              :         ret = B110;
    4252            0 :         break;
    4253              :     }
    4254            0 :     case 134: {
    4255              :         ret = B134;
    4256            0 :         break;
    4257              :     }
    4258            0 :     case 150: {
    4259              :         ret = B150;
    4260            0 :         break;
    4261              :     }
    4262            0 :     case 200: {
    4263              :         ret = B200;
    4264            0 :         break;
    4265              :     }
    4266            0 :     case 300: {
    4267              :         ret = B300;
    4268            0 :         break;
    4269              :     }
    4270            0 :     case 600: {
    4271              :         ret = B600;
    4272            0 :         break;
    4273              :     }
    4274            0 :     case 1200: {
    4275              :         ret = B1200;
    4276            0 :         break;
    4277              :     }
    4278            0 :     case 1800: {
    4279              :         ret = B1800;
    4280            0 :         break;
    4281              :     }
    4282            0 :     case 2400: {
    4283              :         ret = B2400;
    4284            0 :         break;
    4285              :     }
    4286            0 :     case 4800: {
    4287              :         ret = B4800;
    4288            0 :         break;
    4289              :     }
    4290            0 :     case 9600: {
    4291              :         ret = B9600;
    4292            0 :         break;
    4293              :     }
    4294            0 :     case 19200: {
    4295              :         ret = B19200;
    4296            0 :         break;
    4297              :     }
    4298            0 :     case 38400: {
    4299              :         ret = B38400;
    4300            0 :         break;
    4301              :     }
    4302            0 :     case 57600: {
    4303              :         ret = B57600;
    4304            0 :         break;
    4305              :     }
    4306              :     case 115200: {
    4307              :         ret = B115200;
    4308              :         break;
    4309              :     }
    4310              : #ifdef __linux__
    4311            0 :     case 230400: {
    4312              :         ret = B230400;
    4313            0 :         break;
    4314              :     }
    4315            0 :     case 460800: {
    4316              :         ret = B460800;
    4317            0 :         break;
    4318              :     }
    4319            0 :     case 500000: {
    4320              :         ret = B500000;
    4321            0 :         break;
    4322              :     }
    4323            0 :     case 576000: {
    4324              :         ret = B576000;
    4325            0 :         break;
    4326              :     }
    4327            0 :     case 921600: {
    4328              :         ret = B921600;
    4329            0 :         break;
    4330              :     }
    4331            0 :     case 1000000: {
    4332              :         ret = B1000000;
    4333            0 :         break;
    4334              :     }
    4335            0 :     case 1152000: {
    4336              :         ret = B1152000;
    4337            0 :         break;
    4338              :     }
    4339            0 :     case 1500000: {
    4340              :         ret = B1500000;
    4341            0 :         break;
    4342              :     }
    4343            0 :     case 2000000: {
    4344              :         ret = B2000000;
    4345            0 :         break;
    4346              :     }
    4347              : #ifdef B2500000
    4348            0 :     case 2500000: {
    4349              :         ret = B2500000;
    4350            0 :         break;
    4351              :     }
    4352              : #endif
    4353              : #ifdef B3000000
    4354            0 :     case 3000000: {
    4355              :         ret = B3000000;
    4356            0 :         break;
    4357              :     }
    4358              : #endif
    4359              : #ifdef B3500000
    4360            0 :     case 3500000: {
    4361              :         ret = B3500000;
    4362            0 :         break;
    4363              :     }
    4364              : #endif
    4365              : #ifdef B4000000
    4366            0 :     case 4000000: {
    4367              :         ret = B4000000;
    4368            0 :         break;
    4369              :     }
    4370              : #endif
    4371              : #endif /* __linux__ */
    4372              :     default: {
    4373              :         ret = B115200;
    4374              :         break;
    4375              :     }
    4376              :     }
    4377              : 
    4378            0 :     return ret;
    4379              : #else
    4380              :     return 0;
    4381              : #endif
    4382              : }
    4383              : 
    4384              : #endif
    4385              : 
    4386            6 : void dlt_get_version(char* buf, size_t size)
    4387              : {
    4388            6 :     if ((buf == NULL) && (size > 0)) {
    4389            0 :         dlt_log(LOG_WARNING, "Wrong parameter: Null pointer\n");
    4390            0 :         return;
    4391              :     }
    4392              : 
    4393              : /* Clang does not like these macros, because they are not reproducable */
    4394              : #pragma GCC diagnostic push
    4395              : #pragma GCC diagnostic ignored "-Wdate-time"
    4396              :     snprintf(
    4397              :         buf, size, "DLT Package Version: %s %s, Package Revision: %s, build on %s %s\n%s %s %s %s\n",
    4398              :         _DLT_PACKAGE_VERSION, _DLT_PACKAGE_VERSION_STATE, _DLT_PACKAGE_REVISION, __DATE__, __TIME__,
    4399              :         _DLT_SYSTEMD_ENABLE, _DLT_SYSTEMD_WATCHDOG_ENABLE, _DLT_TEST_ENABLE, _DLT_SHM_ENABLE);
    4400              : #pragma GCC diagnostic pop
    4401              : }
    4402              : 
    4403            9 : void dlt_get_major_version(char* buf, size_t size)
    4404              : {
    4405            9 :     if ((buf == NULL) && (size > 0)) {
    4406            0 :         dlt_log(LOG_WARNING, "Wrong parameter: Null pointer\n");
    4407            0 :         return;
    4408              :     }
    4409              : 
    4410              :     snprintf(buf, size, "%s", _DLT_PACKAGE_MAJOR_VERSION);
    4411              : }
    4412              : 
    4413            9 : void dlt_get_minor_version(char* buf, size_t size)
    4414              : {
    4415            9 :     if ((buf == NULL) && (size > 0)) {
    4416            0 :         dlt_log(LOG_WARNING, "Wrong parameter: Null pointer\n");
    4417            0 :         return;
    4418              :     }
    4419              : 
    4420              :     snprintf(buf, size, "%s", _DLT_PACKAGE_MINOR_VERSION);
    4421              : }
    4422              : 
    4423              : 
    4424         6037 : uint32_t dlt_uptime(void)
    4425              : {
    4426              : #if defined(__WIN32__) || defined(_MSC_VER)
    4427              : 
    4428              :     return (uint32_t)(GetTickCount() * 10); /* GetTickCount() return DWORD */
    4429              : 
    4430              : #else
    4431              :     struct timespec ts;
    4432              : 
    4433         6037 :     if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0)
    4434         6037 :         return (uint32_t)ts.tv_sec * 10000 + (uint32_t)ts.tv_nsec / 100000; /* in 0.1 ms = 100 us */
    4435              :     else
    4436              :         return 0;
    4437              : 
    4438              : #endif
    4439              : }
    4440              : 
    4441          328 : DltReturnValue dlt_message_print_header(DltMessage* message, char* text, uint32_t size, int verbose)
    4442              : {
    4443          328 :     if ((message == NULL) || (text == NULL))
    4444              :         return DLT_RETURN_WRONG_PARAMETER;
    4445              : 
    4446          316 :     if (dlt_message_header(message, text, size, verbose) < DLT_RETURN_OK)
    4447              :         return DLT_RETURN_ERROR;
    4448          316 :     dlt_user_printf("%s\n", text);
    4449              : 
    4450          316 :     return DLT_RETURN_OK;
    4451              : }
    4452              : 
    4453           12 : DltReturnValue dlt_message_print_header_v2(DltMessageV2* message, char* text, uint32_t size, int verbose)
    4454              : {
    4455           12 :     if ((message == NULL) || (text == NULL))
    4456              :         return DLT_RETURN_WRONG_PARAMETER;
    4457              : 
    4458            0 :     if (dlt_message_header_v2(message, text, size, verbose) < DLT_RETURN_OK)
    4459              :         return DLT_RETURN_ERROR;
    4460            0 :     dlt_user_printf("%s\n", text);
    4461              : 
    4462            0 :     return DLT_RETURN_OK;
    4463              : }
    4464              : 
    4465          328 : DltReturnValue dlt_message_print_hex(DltMessage* message, char* text, uint32_t size, int verbose)
    4466              : {
    4467          328 :     if ((message == NULL) || (text == NULL))
    4468              :         return DLT_RETURN_WRONG_PARAMETER;
    4469              : 
    4470          316 :     if (dlt_message_header(message, text, size, verbose) < DLT_RETURN_OK)
    4471              :         return DLT_RETURN_ERROR;
    4472          316 :     dlt_user_printf("%s ", text);
    4473              : 
    4474          316 :     if (dlt_message_payload(message, text, size, DLT_OUTPUT_HEX, verbose) < DLT_RETURN_OK)
    4475              :         return DLT_RETURN_ERROR;
    4476          316 :     dlt_user_printf("[%s]\n", text);
    4477              : 
    4478          316 :     return DLT_RETURN_OK;
    4479              : }
    4480              : 
    4481           12 : DltReturnValue dlt_message_print_hex_v2(DltMessageV2* message, char* text, uint32_t size, int verbose)
    4482              : {
    4483           12 :     if ((message == NULL) || (text == NULL))
    4484              :         return DLT_RETURN_WRONG_PARAMETER;
    4485              : 
    4486            0 :     if (dlt_message_header_v2(message, text, size, verbose) < DLT_RETURN_OK)
    4487              :         return DLT_RETURN_ERROR;
    4488            0 :     dlt_user_printf("%s ", text);
    4489              : 
    4490            0 :     if (dlt_message_payload_v2(message, text, size, DLT_OUTPUT_HEX, verbose) < DLT_RETURN_OK)
    4491              :         return DLT_RETURN_ERROR;
    4492            0 :     dlt_user_printf("[%s]\n", text);
    4493              : 
    4494            0 :     return DLT_RETURN_OK;
    4495              : }
    4496              : 
    4497          328 : DltReturnValue dlt_message_print_ascii(DltMessage* message, char* text, uint32_t size, int verbose)
    4498              : {
    4499          328 :     if ((message == NULL) || (text == NULL))
    4500              :         return DLT_RETURN_WRONG_PARAMETER;
    4501              : 
    4502          316 :     if (dlt_message_header(message, text, size, verbose) < DLT_RETURN_OK)
    4503              :         return DLT_RETURN_ERROR;
    4504          316 :     dlt_user_printf("%s ", text);
    4505              : 
    4506          316 :     if (dlt_message_payload(message, text, size, DLT_OUTPUT_ASCII, verbose) < DLT_RETURN_OK)
    4507              :         return DLT_RETURN_ERROR;
    4508          316 :     dlt_user_printf("[%s]\n", text);
    4509              : 
    4510          316 :     return DLT_RETURN_OK;
    4511              : }
    4512              : 
    4513           12 : DltReturnValue dlt_message_print_ascii_v2(DltMessageV2* message, char* text, uint32_t size, int verbose)
    4514              : {
    4515           12 :     if ((message == NULL) || (text == NULL))
    4516              :         return DLT_RETURN_WRONG_PARAMETER;
    4517              : 
    4518            0 :     if (dlt_message_header_v2(message, text, size, verbose) < DLT_RETURN_OK)
    4519              :         return DLT_RETURN_ERROR;
    4520            0 :     dlt_user_printf("%s ", text);
    4521              : 
    4522            0 :     if (dlt_message_payload_v2(message, text, size, DLT_OUTPUT_ASCII, verbose) < DLT_RETURN_OK)
    4523              :         return DLT_RETURN_ERROR;
    4524            0 :     dlt_user_printf("[%s]\n", text);
    4525              : 
    4526            0 :     return DLT_RETURN_OK;
    4527              : }
    4528              : 
    4529          328 : DltReturnValue dlt_message_print_mixed_plain(DltMessage* message, char* text, uint32_t size, int verbose)
    4530              : {
    4531          328 :     if ((message == NULL) || (text == NULL))
    4532              :         return DLT_RETURN_WRONG_PARAMETER;
    4533              : 
    4534          316 :     if (dlt_message_header(message, text, size, verbose) < DLT_RETURN_OK)
    4535              :         return DLT_RETURN_ERROR;
    4536          316 :     dlt_user_printf("%s \n", text);
    4537              : 
    4538          316 :     if (dlt_message_payload(message, text, size, DLT_OUTPUT_MIXED_FOR_PLAIN, verbose) < DLT_RETURN_OK)
    4539              :         return DLT_RETURN_ERROR;
    4540          316 :     dlt_user_printf("[%s]\n", text);
    4541              : 
    4542          316 :     return DLT_RETURN_OK;
    4543              : }
    4544              : 
    4545           12 : DltReturnValue dlt_message_print_mixed_plain_v2(DltMessageV2* message, char* text, uint32_t size, int verbose)
    4546              : {
    4547           12 :     if ((message == NULL) || (text == NULL))
    4548              :         return DLT_RETURN_WRONG_PARAMETER;
    4549              : 
    4550            0 :     if (dlt_message_header_v2(message, text, size, verbose) < DLT_RETURN_OK)
    4551              :         return DLT_RETURN_ERROR;
    4552            0 :     dlt_user_printf("%s \n", text);
    4553              : 
    4554            0 :     if (dlt_message_payload_v2(message, text, size, DLT_OUTPUT_MIXED_FOR_PLAIN, verbose) < DLT_RETURN_OK)
    4555              :         return DLT_RETURN_ERROR;
    4556            0 :     dlt_user_printf("[%s]\n", text);
    4557              : 
    4558            0 :     return DLT_RETURN_OK;
    4559              : }
    4560              : 
    4561          328 : DltReturnValue dlt_message_print_mixed_html(DltMessage* message, char* text, uint32_t size, int verbose)
    4562              : {
    4563          328 :     if ((message == NULL) || (text == NULL))
    4564              :         return DLT_RETURN_WRONG_PARAMETER;
    4565              : 
    4566          316 :     if (dlt_message_header(message, text, size, verbose) < DLT_RETURN_OK)
    4567              :         return DLT_RETURN_ERROR;
    4568          316 :     dlt_user_printf("%s \n", text);
    4569              : 
    4570          316 :     if (dlt_message_payload(message, text, size, DLT_OUTPUT_MIXED_FOR_HTML, verbose) < DLT_RETURN_OK)
    4571              :         return DLT_RETURN_ERROR;
    4572              : 
    4573          316 :     dlt_user_printf("[%s]\n", text);
    4574              : 
    4575          316 :     return DLT_RETURN_OK;
    4576              : }
    4577              : 
    4578         3183 : DltReturnValue dlt_message_argument_print(
    4579              :     DltMessage* msg, uint32_t type_info, uint8_t** ptr, int32_t* datalength, char* text, size_t textlength,
    4580              :     int byteLength, int __attribute__((unused)) verbose)
    4581              : {
    4582              :     /* check null pointers */
    4583         3183 :     if ((msg == NULL) || (ptr == NULL) || (datalength == NULL) || (text == NULL))
    4584              :         return DLT_RETURN_WRONG_PARAMETER;
    4585              : 
    4586              :     uint16_t length = 0, length2 = 0, length3 = 0;
    4587              : 
    4588              :     uint8_t value8u = 0;
    4589              :     uint16_t value16u = 0, value16u_tmp = 0;
    4590              :     uint32_t value32u = 0, value32u_tmp = 0;
    4591              :     uint64_t value64u = 0, value64u_tmp = 0;
    4592              : 
    4593              :     int8_t value8i = 0;
    4594              :     int16_t value16i = 0, value16i_tmp = 0;
    4595              :     int32_t value32i = 0, value32i_tmp = 0;
    4596              :     int64_t value64i = 0, value64i_tmp = 0;
    4597              : 
    4598         3168 :     float32_t value32f = 0, value32f_tmp = 0;
    4599         3168 :     int32_t value32f_tmp_int32i = 0, value32f_tmp_int32i_swaped = 0;
    4600         3168 :     float64_t value64f = 0, value64f_tmp = 0;
    4601         3168 :     int64_t value64f_tmp_int64i = 0, value64f_tmp_int64i_swaped = 0;
    4602              : 
    4603              :     uint32_t quantisation_tmp = 0;
    4604              : 
    4605              :     // pointer to the value string
    4606              :     char* value_text = text;
    4607              :     // pointer to the "unit" attribute string, if there is one (only for *INT and FLOAT*)
    4608              :     const uint8_t* unit_text_src = NULL;
    4609              :     // length of the "unit" attribute string, if there is one (only for *INT and FLOAT*)
    4610              :     size_t unit_text_len = 0;
    4611              : 
    4612              :     /* apparently this makes no sense but needs to be done to prevent compiler warning.
    4613              :      * This variable is only written by DLT_MSG_READ_VALUE macro in if (type_info & DLT_TYPE_INFO_FIXP)
    4614              :      * case but never read anywhere */
    4615              :     quantisation_tmp += quantisation_tmp;
    4616              : 
    4617         3168 :     if ((type_info & DLT_TYPE_INFO_STRG)
    4618         1365 :         && (((type_info & DLT_TYPE_INFO_SCOD) == DLT_SCOD_ASCII)
    4619         1365 :             || ((type_info & DLT_TYPE_INFO_SCOD) == DLT_SCOD_UTF8))) {
    4620              :         /* string type or utf8-encoded string type */
    4621         1365 :         if (byteLength < 0) {
    4622         1365 :             DLT_MSG_READ_VALUE(value16u_tmp, *ptr, *datalength, uint16_t);
    4623              : 
    4624         1365 :             if ((*datalength) < 0)
    4625              :                 return DLT_RETURN_ERROR;
    4626              : 
    4627         1365 :             length = (uint16_t)DLT_ENDIAN_GET_16(msg->standardheader->htyp, value16u_tmp);
    4628              :         } else {
    4629            0 :             length = (uint16_t)byteLength;
    4630              :         }
    4631              : 
    4632         1365 :         if (type_info & DLT_TYPE_INFO_VARI) {
    4633            0 :             DLT_MSG_READ_VALUE(value16u_tmp, *ptr, *datalength, uint16_t);
    4634              : 
    4635            0 :             if ((*datalength) < 0)
    4636              :                 return DLT_RETURN_ERROR;
    4637              : 
    4638            0 :             length2 = (uint16_t)DLT_ENDIAN_GET_16(msg->standardheader->htyp, value16u_tmp);
    4639              : 
    4640            0 :             if ((*datalength) < length2)
    4641              :                 return DLT_RETURN_ERROR;
    4642              : 
    4643            0 :             if (print_with_attributes) {
    4644              :                 // Print "name" attribute, if we have one with non-zero size.
    4645            0 :                 if (length2 > 1) {
    4646            0 :                     snprintf(text, (size_t)textlength, "%s:", *ptr);
    4647            0 :                     value_text += length2 + 1 - 1;  // +1 for ":" and -1 for NUL
    4648            0 :                     textlength -= (size_t)(length2 + 1 - 1);
    4649              :                 }
    4650              :             }
    4651              : 
    4652            0 :             *ptr += length2;
    4653            0 :             *datalength -= length2;
    4654              :         }
    4655              : 
    4656         1365 :         DLT_MSG_READ_STRING(value_text, *ptr, *datalength, textlength, length);
    4657              : 
    4658         1365 :         if ((*datalength) < 0)
    4659              :             return DLT_RETURN_ERROR;
    4660         1803 :     } else if (type_info & DLT_TYPE_INFO_BOOL) {
    4661              :         /* Boolean type */
    4662          112 :         if (type_info & DLT_TYPE_INFO_VARI) {
    4663            0 :             DLT_MSG_READ_VALUE(value16u_tmp, *ptr, *datalength, uint16_t);
    4664              : 
    4665            0 :             if ((*datalength) < 0)
    4666              :                 return DLT_RETURN_ERROR;
    4667              : 
    4668            0 :             length2 = (uint16_t)DLT_ENDIAN_GET_16(msg->standardheader->htyp, value16u_tmp);
    4669              : 
    4670            0 :             if ((*datalength) < length2)
    4671              :                 return DLT_RETURN_ERROR;
    4672              : 
    4673            0 :             if (print_with_attributes) {
    4674              :                 // Print "name" attribute, if we have one with non-zero size.
    4675            0 :                 if (length2 > 1) {
    4676            0 :                     snprintf(text, (size_t)textlength, "%s:", *ptr);
    4677            0 :                     value_text += length2 + 1 - 1;  // +1 for ":" and -1 for NUL
    4678            0 :                     textlength -= (size_t)(length2 + 1 - 2);
    4679              :                 }
    4680              :             }
    4681              : 
    4682            0 :             *ptr += length2;
    4683            0 :             *datalength -= length2;
    4684              :         }
    4685              : 
    4686              :         value8u = 0;
    4687          112 :         DLT_MSG_READ_VALUE(value8u, *ptr, *datalength, uint8_t); /* No endian conversion necessary */
    4688              : 
    4689          112 :         if ((*datalength) < 0)
    4690              :             return DLT_RETURN_ERROR;
    4691              : 
    4692          110 :         snprintf(value_text, textlength, "%d", value8u);
    4693         1691 :     } else if ((type_info & DLT_TYPE_INFO_UINT) && (DLT_SCOD_BIN == (type_info & DLT_TYPE_INFO_SCOD))) {
    4694            0 :         if (DLT_TYLE_8BIT == (type_info & DLT_TYPE_INFO_TYLE)) {
    4695            0 :             DLT_MSG_READ_VALUE(value8u, *ptr, *datalength, uint8_t); /* No endian conversion necessary */
    4696              : 
    4697            0 :             if ((*datalength) < 0)
    4698            0 :                 return DLT_RETURN_ERROR;
    4699              : 
    4700            0 :             char binary[10] = {'\0'}; /* e.g.: "0b1100 0010" */
    4701              :             int i;
    4702              : 
    4703            0 :             for (i = (1 << 7); i > 0; i >>= 1) {
    4704            0 :                 if ((1 << 3) == i)
    4705              :                     strcat(binary, " ");
    4706              : 
    4707            0 :                 strcat(binary, (i == (value8u & i)) ? "1" : "0");
    4708              :             }
    4709              : 
    4710              :             snprintf(value_text, textlength, "0b%s", binary);
    4711              :         }
    4712              : 
    4713            0 :         if (DLT_TYLE_16BIT == (type_info & DLT_TYPE_INFO_TYLE)) {
    4714            0 :             DLT_MSG_READ_VALUE(value16u, *ptr, *datalength, uint16_t);
    4715              : 
    4716            0 :             if ((*datalength) < 0)
    4717            0 :                 return DLT_RETURN_ERROR;
    4718              : 
    4719            0 :             char binary[20] = {'\0'}; /* e.g.: "0b1100 0010 0011 0110" */
    4720              :             int i;
    4721              : 
    4722            0 :             for (i = (1 << 15); i > 0; i >>= 1) {
    4723            0 :                 if (((1 << 3) == i) || ((1 << 7) == i) || ((1 << 11) == i))
    4724              :                     strcat(binary, " ");
    4725              : 
    4726            0 :                 strcat(binary, (i == (value16u & i)) ? "1" : "0");
    4727              :             }
    4728              : 
    4729              :             snprintf(value_text, textlength, "0b%s", binary);
    4730              :         }
    4731         1691 :     } else if ((type_info & DLT_TYPE_INFO_UINT) && (DLT_SCOD_HEX == (type_info & DLT_TYPE_INFO_SCOD))) {
    4732            0 :         if (DLT_TYLE_8BIT == (type_info & DLT_TYPE_INFO_TYLE)) {
    4733            0 :             DLT_MSG_READ_VALUE(value8u, *ptr, *datalength, uint8_t); /* No endian conversion necessary */
    4734              : 
    4735            0 :             if ((*datalength) < 0)
    4736              :                 return DLT_RETURN_ERROR;
    4737              : 
    4738            0 :             snprintf(value_text, textlength, "0x%02x", value8u);
    4739              :         }
    4740              : 
    4741            0 :         if (DLT_TYLE_16BIT == (type_info & DLT_TYPE_INFO_TYLE)) {
    4742            0 :             DLT_MSG_READ_VALUE(value16u, *ptr, *datalength, uint16_t);
    4743              : 
    4744            0 :             if ((*datalength) < 0)
    4745              :                 return DLT_RETURN_ERROR;
    4746              : 
    4747            0 :             snprintf(value_text, textlength, "0x%04x", value16u);
    4748              :         }
    4749              : 
    4750            0 :         if (DLT_TYLE_32BIT == (type_info & DLT_TYPE_INFO_TYLE)) {
    4751            0 :             DLT_MSG_READ_VALUE(value32u, *ptr, *datalength, uint32_t);
    4752              : 
    4753            0 :             if ((*datalength) < 0)
    4754              :                 return DLT_RETURN_ERROR;
    4755              : 
    4756              :             snprintf(value_text, textlength, "0x%08x", value32u);
    4757              :         }
    4758              : 
    4759            0 :         if (DLT_TYLE_64BIT == (type_info & DLT_TYPE_INFO_TYLE)) {
    4760            0 :             *ptr += 4;
    4761            0 :             DLT_MSG_READ_VALUE(value32u, *ptr, *datalength, uint32_t);
    4762              : 
    4763            0 :             if ((*datalength) < 0)
    4764              :                 return DLT_RETURN_ERROR;
    4765              : 
    4766              :             snprintf(value_text, textlength, "0x%08x", value32u);
    4767            0 :             *ptr -= 8;
    4768            0 :             DLT_MSG_READ_VALUE(value32u, *ptr, *datalength, uint32_t);
    4769              : 
    4770            0 :             if ((*datalength) < 0)
    4771              :                 return DLT_RETURN_ERROR;
    4772              : 
    4773            0 :             snprintf(value_text + strlen(value_text), textlength - strlen(value_text), "%08x", value32u);
    4774            0 :             *ptr += 4;
    4775              :         }
    4776         1691 :     } else if ((type_info & DLT_TYPE_INFO_SINT) || (type_info & DLT_TYPE_INFO_UINT)) {
    4777              :         /* signed or unsigned argument received */
    4778         1564 :         if (type_info & DLT_TYPE_INFO_VARI) {
    4779            0 :             DLT_MSG_READ_VALUE(value16u_tmp, *ptr, *datalength, uint16_t);
    4780              : 
    4781            0 :             if ((*datalength) < 0)
    4782              :                 return DLT_RETURN_ERROR;
    4783              : 
    4784            0 :             length2 = (uint16_t)DLT_ENDIAN_GET_16(msg->standardheader->htyp, value16u_tmp);
    4785            0 :             DLT_MSG_READ_VALUE(value16u_tmp, *ptr, *datalength, uint16_t);
    4786              : 
    4787            0 :             if ((*datalength) < 0)
    4788              :                 return DLT_RETURN_ERROR;
    4789              : 
    4790            0 :             length3 = (uint16_t)DLT_ENDIAN_GET_16(msg->standardheader->htyp, value16u_tmp);
    4791              : 
    4792            0 :             if ((*datalength) < length2)
    4793              :                 return DLT_RETURN_ERROR;
    4794              : 
    4795            0 :             if (print_with_attributes) {
    4796              :                 // Print "name" attribute, if we have one with non-zero size.
    4797            0 :                 if (length2 > 1) {
    4798            0 :                     snprintf(text, (size_t)textlength, "%s:", *ptr);
    4799            0 :                     value_text += length2 + 1 - 1;  // +1 for ":", and -1 for nul
    4800            0 :                     textlength -= (size_t)(length2 + 1 - 1);
    4801              :                 }
    4802              :             }
    4803              : 
    4804            0 :             *ptr += length2;
    4805            0 :             *datalength -= length2;
    4806              : 
    4807            0 :             if ((*datalength) < length3)
    4808              :                 return DLT_RETURN_ERROR;
    4809              : 
    4810              :             // We want to add the "unit" attribute only after the value, so remember its pointer and length here.
    4811              :             unit_text_src = *ptr;
    4812            0 :             unit_text_len = length3;
    4813              : 
    4814            0 :             *ptr += length3;
    4815            0 :             *datalength -= length3;
    4816              :         }
    4817              : 
    4818         1564 :         if (type_info & DLT_TYPE_INFO_FIXP) {
    4819            0 :             DLT_MSG_READ_VALUE(quantisation_tmp, *ptr, *datalength, uint32_t);
    4820              : 
    4821            0 :             if ((*datalength) < 0)
    4822              :                 return DLT_RETURN_ERROR;
    4823              : 
    4824            0 :             switch (type_info & DLT_TYPE_INFO_TYLE) {
    4825            0 :             case DLT_TYLE_8BIT:
    4826              :             case DLT_TYLE_16BIT:
    4827              :             case DLT_TYLE_32BIT: {
    4828            0 :                 if ((*datalength) < 4)
    4829              :                     return DLT_RETURN_ERROR;
    4830              : 
    4831            0 :                 *ptr += 4;
    4832            0 :                 *datalength -= 4;
    4833            0 :                 break;
    4834              :             }
    4835            0 :             case DLT_TYLE_64BIT: {
    4836            0 :                 if ((*datalength) < 8)
    4837              :                     return DLT_RETURN_ERROR;
    4838              : 
    4839            0 :                 *ptr += 8;
    4840            0 :                 *datalength -= 8;
    4841            0 :                 break;
    4842              :             }
    4843            0 :             case DLT_TYLE_128BIT: {
    4844            0 :                 if ((*datalength) < 16)
    4845              :                     return DLT_RETURN_ERROR;
    4846              : 
    4847            0 :                 *ptr += 16;
    4848            0 :                 *datalength -= 16;
    4849            0 :                 break;
    4850              :             }
    4851              :             default: {
    4852              :                 return DLT_RETURN_ERROR;
    4853              :             }
    4854              :             }
    4855              :         }
    4856              : 
    4857         1564 :         switch (type_info & DLT_TYPE_INFO_TYLE) {
    4858           14 :         case DLT_TYLE_8BIT: {
    4859           14 :             if (type_info & DLT_TYPE_INFO_SINT) {
    4860              :                 value8i = 0;
    4861            7 :                 DLT_MSG_READ_VALUE(value8i, *ptr, *datalength, int8_t); /* No endian conversion necessary */
    4862              : 
    4863            7 :                 if ((*datalength) < 0)
    4864              :                     return DLT_RETURN_ERROR;
    4865              : 
    4866            7 :                 snprintf(value_text, (size_t)textlength, "%d", value8i);
    4867              :             } else {
    4868              :                 value8u = 0;
    4869            7 :                 DLT_MSG_READ_VALUE(value8u, *ptr, *datalength, uint8_t); /* No endian conversion necessary */
    4870              : 
    4871            7 :                 if ((*datalength) < 0)
    4872              :                     return DLT_RETURN_ERROR;
    4873              : 
    4874            7 :                 snprintf(value_text, (size_t)textlength, "%d", value8u);
    4875              :             }
    4876              : 
    4877              :             break;
    4878              :         }
    4879           21 :         case DLT_TYLE_16BIT: {
    4880           21 :             if (type_info & DLT_TYPE_INFO_SINT) {
    4881              :                 value16i = 0;
    4882              :                 value16i_tmp = 0;
    4883            7 :                 DLT_MSG_READ_VALUE(value16i_tmp, *ptr, *datalength, int16_t);
    4884              : 
    4885            7 :                 if ((*datalength) < 0)
    4886              :                     return DLT_RETURN_ERROR;
    4887              : 
    4888            7 :                 value16i = (int16_t)DLT_ENDIAN_GET_16(msg->standardheader->htyp, value16i_tmp);
    4889            7 :                 snprintf(value_text, (size_t)textlength, "%hd", value16i);
    4890              :             } else {
    4891              :                 value16u = 0;
    4892              :                 value16u_tmp = 0;
    4893           14 :                 DLT_MSG_READ_VALUE(value16u_tmp, *ptr, *datalength, uint16_t);
    4894              : 
    4895           14 :                 if ((*datalength) < 0)
    4896              :                     return DLT_RETURN_ERROR;
    4897              : 
    4898           14 :                 value16u = (uint16_t)DLT_ENDIAN_GET_16(msg->standardheader->htyp, value16u_tmp);
    4899           14 :                 snprintf(value_text, (size_t)textlength, "%hu", value16u);
    4900              :             }
    4901              : 
    4902              :             break;
    4903              :         }
    4904         1515 :         case DLT_TYLE_32BIT: {
    4905         1515 :             if (type_info & DLT_TYPE_INFO_SINT) {
    4906              :                 value32i = 0;
    4907              :                 value32i_tmp = 0;
    4908          287 :                 DLT_MSG_READ_VALUE(value32i_tmp, *ptr, *datalength, int32_t);
    4909              : 
    4910          287 :                 if ((*datalength) < 0)
    4911              :                     return DLT_RETURN_ERROR;
    4912              : 
    4913          287 :                 value32i = (int32_t)DLT_ENDIAN_GET_32(msg->standardheader->htyp, (uint32_t)value32i_tmp);
    4914              :                 snprintf(value_text, (size_t)textlength, "%d", value32i);
    4915              :             } else {
    4916              :                 value32u = 0;
    4917              :                 value32u_tmp = 0;
    4918         1228 :                 DLT_MSG_READ_VALUE(value32u_tmp, *ptr, *datalength, uint32_t);
    4919              : 
    4920         1228 :                 if ((*datalength) < 0)
    4921              :                     return DLT_RETURN_ERROR;
    4922              : 
    4923         1228 :                 value32u = DLT_ENDIAN_GET_32(msg->standardheader->htyp, value32u_tmp);
    4924              :                 snprintf(value_text, (size_t)textlength, "%u", value32u);
    4925              :             }
    4926              : 
    4927              :             break;
    4928              :         }
    4929           14 :         case DLT_TYLE_64BIT: {
    4930           14 :             if (type_info & DLT_TYPE_INFO_SINT) {
    4931              :                 value64i = 0;
    4932              :                 value64i_tmp = 0;
    4933            7 :                 DLT_MSG_READ_VALUE(value64i_tmp, *ptr, *datalength, int64_t);
    4934              : 
    4935            7 :                 if ((*datalength) < 0)
    4936              :                     return DLT_RETURN_ERROR;
    4937              : 
    4938            7 :                 value64i = (int64_t)DLT_ENDIAN_GET_64(msg->standardheader->htyp, (uint64_t)value64i_tmp);
    4939              : #if defined(__WIN32__) && !defined(_MSC_VER)
    4940              :                 snprintf(value_text, (size_t)textlength, "%I64d", value64i);
    4941              : #else
    4942              :                 snprintf(value_text, (size_t)textlength, "%" PRId64, value64i);
    4943              : #endif
    4944              :             } else {
    4945              :                 value64u = 0;
    4946              :                 value64u_tmp = 0;
    4947            7 :                 DLT_MSG_READ_VALUE(value64u_tmp, *ptr, *datalength, uint64_t);
    4948              : 
    4949            7 :                 if ((*datalength) < 0)
    4950              :                     return DLT_RETURN_ERROR;
    4951              : 
    4952            7 :                 value64u = DLT_ENDIAN_GET_64(msg->standardheader->htyp, value64u_tmp);
    4953              : #if defined(__WIN32__) && !defined(_MSC_VER)
    4954              :                 snprintf(value_text, textlength, "%I64u", value64u);
    4955              : #else
    4956              :                 snprintf(value_text, textlength, "%" PRIu64, value64u);
    4957              : #endif
    4958              :             }
    4959              : 
    4960              :             break;
    4961              :         }
    4962            0 :         case DLT_TYLE_128BIT: {
    4963            0 :             if (*datalength >= 16)
    4964            0 :                 dlt_print_hex_string(value_text, (int)textlength, *ptr, 16);
    4965              : 
    4966            0 :             if ((*datalength) < 16)
    4967              :                 return DLT_RETURN_ERROR;
    4968              : 
    4969            0 :             *ptr += 16;
    4970            0 :             *datalength -= 16;
    4971            0 :             break;
    4972              :         }
    4973              :         default: {
    4974              :             return DLT_RETURN_ERROR;
    4975              :         }
    4976              :         }
    4977          127 :     } else if (type_info & DLT_TYPE_INFO_FLOA) {
    4978              :         /* float data argument */
    4979           14 :         if (type_info & DLT_TYPE_INFO_VARI) {
    4980            0 :             DLT_MSG_READ_VALUE(value16u_tmp, *ptr, *datalength, uint16_t);
    4981              : 
    4982            0 :             if ((*datalength) < 0)
    4983              :                 return DLT_RETURN_ERROR;
    4984              : 
    4985            0 :             length2 = DLT_ENDIAN_GET_16(msg->standardheader->htyp, value16u_tmp);
    4986            0 :             DLT_MSG_READ_VALUE(value16u_tmp, *ptr, *datalength, uint16_t);
    4987              : 
    4988            0 :             if ((*datalength) < 0)
    4989              :                 return DLT_RETURN_ERROR;
    4990              : 
    4991            0 :             length3 = DLT_ENDIAN_GET_16(msg->standardheader->htyp, value16u_tmp);
    4992              : 
    4993            0 :             if ((*datalength) < length2)
    4994              :                 return DLT_RETURN_ERROR;
    4995              : 
    4996            0 :             if (print_with_attributes) {
    4997              :                 // Print "name" attribute, if we have one with non-zero size.
    4998            0 :                 if (length2 > 1) {
    4999            0 :                     snprintf(text, textlength, "%s:", *ptr);
    5000            0 :                     value_text += length2 + 1 - 1;  // +1 for ":" and -1 for NUL
    5001            0 :                     textlength -= (size_t)length2 + 1 - 1;
    5002              :                 }
    5003              :             }
    5004              : 
    5005            0 :             *ptr += length2;
    5006            0 :             *datalength -= length2;
    5007              : 
    5008            0 :             if ((*datalength) < length3)
    5009              :                 return DLT_RETURN_ERROR;
    5010              : 
    5011              :             // We want to add the "unit" attribute only after the value, so remember its pointer and length here.
    5012              :             unit_text_src = *ptr;
    5013            0 :             unit_text_len = length3;
    5014              : 
    5015            0 :             *ptr += length3;
    5016            0 :             *datalength -= length3;
    5017              :         }
    5018              : 
    5019           14 :         switch (type_info & DLT_TYPE_INFO_TYLE) {
    5020            0 :         case DLT_TYLE_8BIT: {
    5021            0 :             if (*datalength >= 1)
    5022            0 :                 dlt_print_hex_string(value_text, (int)textlength, *ptr, 1);
    5023              : 
    5024            0 :             if ((*datalength) < 1)
    5025              :                 return DLT_RETURN_ERROR;
    5026              : 
    5027            0 :             *ptr += 1;
    5028            0 :             *datalength -= 1;
    5029            0 :             break;
    5030              :         }
    5031            0 :         case DLT_TYLE_16BIT: {
    5032            0 :             if (*datalength >= 2)
    5033            0 :                 dlt_print_hex_string(value_text, (int)textlength, *ptr, 2);
    5034              : 
    5035            0 :             if ((*datalength) < 2)
    5036              :                 return DLT_RETURN_ERROR;
    5037              : 
    5038            0 :             *ptr += 2;
    5039            0 :             *datalength -= 2;
    5040            0 :             break;
    5041              :         }
    5042              :         case DLT_TYLE_32BIT: {
    5043              :             if (sizeof(float32_t) == 4) {
    5044              :                 value32f = 0;
    5045              :                 value32f_tmp = 0;
    5046              :                 value32f_tmp_int32i = 0;
    5047              :                 value32f_tmp_int32i_swaped = 0;
    5048            7 :                 DLT_MSG_READ_VALUE(value32f_tmp, *ptr, *datalength, float32_t);
    5049              : 
    5050            7 :                 if ((*datalength) < 0)
    5051              :                     return DLT_RETURN_ERROR;
    5052              : 
    5053              :                 memcpy(&value32f_tmp_int32i, &value32f_tmp, sizeof(float32_t));
    5054              :                 value32f_tmp_int32i_swaped =
    5055            7 :                     (int32_t)DLT_ENDIAN_GET_32(msg->standardheader->htyp, (uint32_t)value32f_tmp_int32i);
    5056              :                 memcpy(&value32f, &value32f_tmp_int32i_swaped, sizeof(float32_t));
    5057            7 :                 snprintf(value_text, textlength, "%g", value32f);
    5058              :             } else {
    5059              :                 dlt_log(LOG_ERR, "Invalid size of float32_t\n");
    5060              :                 return DLT_RETURN_ERROR;
    5061              :             }
    5062              : 
    5063              :             break;
    5064              :         }
    5065              :         case DLT_TYLE_64BIT: {
    5066              :             if (sizeof(float64_t) == 8) {
    5067              :                 value64f = 0;
    5068              :                 value64f_tmp = 0;
    5069              :                 value64f_tmp_int64i = 0;
    5070              :                 value64f_tmp_int64i_swaped = 0;
    5071            7 :                 DLT_MSG_READ_VALUE(value64f_tmp, *ptr, *datalength, float64_t);
    5072              : 
    5073            7 :                 if ((*datalength) < 0)
    5074              :                     return DLT_RETURN_ERROR;
    5075              : 
    5076              :                 memcpy(&value64f_tmp_int64i, &value64f_tmp, sizeof(float64_t));
    5077              :                 value64f_tmp_int64i_swaped =
    5078            7 :                     (int64_t)DLT_ENDIAN_GET_64(msg->standardheader->htyp, (uint64_t)value64f_tmp_int64i);
    5079              :                 memcpy(&value64f, &value64f_tmp_int64i_swaped, sizeof(float64_t));
    5080              : #ifdef __arm__
    5081              :                 snprintf(value_text, textlength, "ILLEGAL");
    5082              : #else
    5083              :                 snprintf(value_text, textlength, "%g", value64f);
    5084              : #endif
    5085              :             } else {
    5086              :                 dlt_log(LOG_ERR, "Invalid size of float64_t\n");
    5087              :                 return DLT_RETURN_ERROR;
    5088              :             }
    5089              : 
    5090              :             break;
    5091              :         }
    5092            0 :         case DLT_TYLE_128BIT: {
    5093            0 :             if (*datalength >= 16)
    5094            0 :                 dlt_print_hex_string(value_text, (int)textlength, *ptr, 16);
    5095              : 
    5096            0 :             if ((*datalength) < 16)
    5097              :                 return DLT_RETURN_ERROR;
    5098              : 
    5099            0 :             *ptr += 16;
    5100            0 :             *datalength -= 16;
    5101            0 :             break;
    5102              :         }
    5103              :         default: {
    5104              :             return DLT_RETURN_ERROR;
    5105              :         }
    5106              :         }
    5107          113 :     } else if (type_info & DLT_TYPE_INFO_RAWD) {
    5108              :         /* raw data argument */
    5109          112 :         DLT_MSG_READ_VALUE(value16u_tmp, *ptr, *datalength, uint16_t);
    5110              : 
    5111          112 :         if ((*datalength) < 0)
    5112              :             return DLT_RETURN_ERROR;
    5113              : 
    5114          110 :         length = DLT_ENDIAN_GET_16(msg->standardheader->htyp, value16u_tmp);
    5115              : 
    5116          110 :         if (type_info & DLT_TYPE_INFO_VARI) {
    5117            0 :             DLT_MSG_READ_VALUE(value16u_tmp, *ptr, *datalength, uint16_t);
    5118              : 
    5119            0 :             if ((*datalength) < 0)
    5120              :                 return DLT_RETURN_ERROR;
    5121              : 
    5122            0 :             length2 = DLT_ENDIAN_GET_16(msg->standardheader->htyp, value16u_tmp);
    5123              : 
    5124            0 :             if ((*datalength) < length2)
    5125              :                 return DLT_RETURN_ERROR;
    5126              : 
    5127            0 :             if (print_with_attributes) {
    5128              :                 // Print "name" attribute, if we have one with non-zero size.
    5129            0 :                 if (length2 > 1) {
    5130            0 :                     snprintf(text, textlength, "%s:", *ptr);
    5131            0 :                     value_text += length2 + 1 - 1;  // +1 for ":" and -1 for NUL
    5132            0 :                     textlength -= (size_t)(length2 + 1 - 1);
    5133              :                 }
    5134              :             }
    5135              : 
    5136            0 :             *ptr += length2;
    5137            0 :             *datalength -= length2;
    5138              :         }
    5139              : 
    5140          110 :         if ((*datalength) < length)
    5141              :             return DLT_RETURN_ERROR;
    5142              : 
    5143            9 :         if (dlt_print_hex_string_delim(value_text, (int)textlength, *ptr, length, '\'') < DLT_RETURN_OK)
    5144              :             return DLT_RETURN_ERROR;
    5145            9 :         *ptr += length;
    5146            9 :         *datalength -= length;
    5147            1 :     } else if (type_info & DLT_TYPE_INFO_TRAI) {
    5148              :         /* trace info argument */
    5149            0 :         DLT_MSG_READ_VALUE(value16u_tmp, *ptr, *datalength, uint16_t);
    5150              : 
    5151            0 :         if ((*datalength) < 0)
    5152              :             return DLT_RETURN_ERROR;
    5153              : 
    5154            0 :         length = DLT_ENDIAN_GET_16(msg->standardheader->htyp, value16u_tmp);
    5155              : 
    5156            0 :         DLT_MSG_READ_STRING(value_text, *ptr, *datalength, textlength, length);
    5157              : 
    5158            0 :         if ((*datalength) < 0)
    5159              :             return DLT_RETURN_ERROR;
    5160              :     } else {
    5161              :         return DLT_RETURN_ERROR;
    5162              :     }
    5163         3062 :     if (*datalength < 0) {
    5164            0 :         dlt_log(LOG_ERR, "Payload of DLT message corrupted\n");
    5165            0 :         return DLT_RETURN_ERROR;
    5166              :     }
    5167              : 
    5168              :     // Now write "unit" attribute, but only if it has more than only a nul-termination char.
    5169         3062 :     if (print_with_attributes) {
    5170            0 :         if (unit_text_len > 1) {
    5171              :             // 'value_text' still points to the +start+ of the value text
    5172            0 :             size_t currLen = strlen(value_text);
    5173              : 
    5174            0 :             char* unitText = value_text + currLen;
    5175            0 :             textlength -= currLen;
    5176              :             snprintf(unitText, textlength, ":%s", unit_text_src);
    5177              :         }
    5178              :     }
    5179              : 
    5180              :     return DLT_RETURN_OK;
    5181              : }
    5182              : 
    5183           16 : DltReturnValue dlt_message_argument_print_v2(
    5184              :     DltMessageV2* msg, uint32_t type_info, uint8_t** ptr, int32_t* datalength, char* text, size_t textlength,
    5185              :     int byteLength, int __attribute__((unused)) verbose)
    5186              : {
    5187              :     /* check null pointers */
    5188           16 :     if ((msg == NULL) || (ptr == NULL) || (datalength == NULL) || (text == NULL))
    5189              :         return DLT_RETURN_WRONG_PARAMETER;
    5190              : 
    5191              :     uint16_t length = 0, length2 = 0, length3 = 0;
    5192              : 
    5193              :     uint8_t value8u = 0;
    5194              :     uint16_t value16u = 0, value16u_tmp = 0;
    5195              :     uint32_t value32u = 0, value32u_tmp = 0;
    5196              :     uint64_t value64u = 0, value64u_tmp = 0;
    5197              : 
    5198              :     int8_t value8i = 0;
    5199              :     int16_t value16i = 0, value16i_tmp = 0;
    5200              :     int32_t value32i = 0, value32i_tmp = 0;
    5201              :     int64_t value64i = 0, value64i_tmp = 0;
    5202              : 
    5203            1 :     float32_t value32f = 0, value32f_tmp = 0;
    5204            1 :     int32_t value32f_tmp_int32i = 0, value32f_tmp_int32i_swaped = 0;
    5205            1 :     float64_t value64f = 0, value64f_tmp = 0;
    5206            1 :     int64_t value64f_tmp_int64i = 0, value64f_tmp_int64i_swaped = 0;
    5207              : 
    5208              :     uint32_t quantisation_tmp = 0;
    5209              : 
    5210              :     // pointer to the value string
    5211              :     char* value_text = text;
    5212              :     // pointer to the "unit" attribute string, if there is one (only for *INT and FLOAT*)
    5213              :     const uint8_t* unit_text_src = NULL;
    5214              :     // length of the "unit" attribute string, if there is one (only for *INT and FLOAT*)
    5215              :     size_t unit_text_len = 0;
    5216              : 
    5217              :     /* apparently this makes no sense but needs to be done to prevent compiler warning.
    5218              :      * This variable is only written by DLT_MSG_READ_VALUE macro in if (type_info & DLT_TYPE_INFO_FIXP)
    5219              :      * case but never read anywhere */
    5220              :     quantisation_tmp += quantisation_tmp;
    5221              : 
    5222            1 :     if ((type_info & DLT_TYPE_INFO_STRG)
    5223            0 :         && (((type_info & DLT_TYPE_INFO_SCOD) == DLT_SCOD_ASCII)
    5224            0 :             || ((type_info & DLT_TYPE_INFO_SCOD) == DLT_SCOD_UTF8))) {
    5225              :         /* string type or utf8-encoded string type */
    5226              : 
    5227            0 :         if (byteLength < 0) {
    5228            0 :             DLT_MSG_READ_VALUE(value16u_tmp, *ptr, *datalength, uint16_t);
    5229              : 
    5230            0 :             if ((*datalength) < 0)
    5231              :                 return DLT_RETURN_ERROR;
    5232              : 
    5233              :             length = (uint16_t)DLT_LETOH_16(value16u_tmp);
    5234              :         } else {
    5235            0 :             length = (uint16_t)byteLength;
    5236              :         }
    5237              : 
    5238            0 :         if (type_info & DLT_TYPE_INFO_VARI) {
    5239            0 :             DLT_MSG_READ_VALUE(value16u_tmp, *ptr, *datalength, uint16_t);
    5240              : 
    5241            0 :             if ((*datalength) < 0)
    5242              :                 return DLT_RETURN_ERROR;
    5243              : 
    5244              :             length2 = (uint16_t)DLT_LETOH_16(value16u_tmp);
    5245              : 
    5246            0 :             if ((*datalength) < length2)
    5247              :                 return DLT_RETURN_ERROR;
    5248              : 
    5249            0 :             if (print_with_attributes) {
    5250              :                 // Print "name" attribute, if we have one with non-zero size.
    5251            0 :                 if (length2 > 1) {
    5252            0 :                     snprintf(text, textlength, "%s:", *ptr);
    5253            0 :                     value_text += (size_t)length2 + 1 - 1;  // +1 for ":" and -1 for NUL
    5254            0 :                     textlength -= (size_t)length2 + 1 - 1;
    5255              :                 }
    5256              :             }
    5257              : 
    5258            0 :             *ptr += length2;
    5259            0 :             *datalength -= length2;
    5260              :         }
    5261              : 
    5262            0 :         DLT_MSG_READ_STRING(value_text, *ptr, *datalength, textlength, length);
    5263              : 
    5264            0 :         if ((*datalength) < 0)
    5265              :             return DLT_RETURN_ERROR;
    5266            1 :     } else if (type_info & DLT_TYPE_INFO_BOOL) {
    5267              :         /* Boolean type */
    5268            0 :         if (type_info & DLT_TYPE_INFO_VARI) {
    5269            0 :             DLT_MSG_READ_VALUE(value16u_tmp, *ptr, *datalength, uint16_t);
    5270              : 
    5271            0 :             if ((*datalength) < 0)
    5272              :                 return DLT_RETURN_ERROR;
    5273              : 
    5274              :             length2 = (uint16_t)DLT_LETOH_16(value16u_tmp);
    5275              : 
    5276            0 :             if ((*datalength) < length2)
    5277              :                 return DLT_RETURN_ERROR;
    5278              : 
    5279            0 :             if (print_with_attributes) {
    5280              :                 // Print "name" attribute, if we have one with non-zero size.
    5281            0 :                 if (length2 > 1) {
    5282            0 :                     snprintf(text, textlength, "%s:", *ptr);
    5283            0 :                     value_text += (size_t)length2 + 1 - 1;  // +1 for ":" and -1 for NUL
    5284            0 :                     textlength -= (size_t)length2 + 1 - 2;
    5285              :                 }
    5286              :             }
    5287              : 
    5288            0 :             *ptr += length2;
    5289            0 :             *datalength -= length2;
    5290              :         }
    5291              : 
    5292              :         value8u = 0;
    5293            0 :         DLT_MSG_READ_VALUE(value8u, *ptr, *datalength, uint8_t); /* No endian conversion necessary */
    5294              : 
    5295            0 :         if ((*datalength) < 0)
    5296              :             return DLT_RETURN_ERROR;
    5297              : 
    5298            0 :         snprintf(value_text, textlength, "%d", value8u);
    5299            1 :     } else if ((type_info & DLT_TYPE_INFO_UINT) && (DLT_SCOD_BIN == (type_info & DLT_TYPE_INFO_SCOD))) {
    5300            0 :         if (DLT_TYLE_8BIT == (type_info & DLT_TYPE_INFO_TYLE)) {
    5301            0 :             DLT_MSG_READ_VALUE(value8u, *ptr, *datalength, uint8_t); /* No endian conversion necessary */
    5302              : 
    5303            0 :             if ((*datalength) < 0)
    5304            0 :                 return DLT_RETURN_ERROR;
    5305              : 
    5306            0 :             char binary[10] = {'\0'}; /* e.g.: "0b1100 0010" */
    5307              :             int i;
    5308              : 
    5309            0 :             for (i = (1 << 7); i > 0; i >>= 1) {
    5310            0 :                 if ((1 << 3) == i)
    5311              :                     strcat(binary, " ");
    5312              : 
    5313            0 :                 strcat(binary, (i == (value8u & i)) ? "1" : "0");
    5314              :             }
    5315              : 
    5316              :             snprintf(value_text, textlength, "0b%s", binary);
    5317              :         }
    5318              : 
    5319            0 :         if (DLT_TYLE_16BIT == (type_info & DLT_TYPE_INFO_TYLE)) {
    5320            0 :             DLT_MSG_READ_VALUE(value16u, *ptr, *datalength, uint16_t);
    5321              : 
    5322            0 :             if ((*datalength) < 0)
    5323            0 :                 return DLT_RETURN_ERROR;
    5324              : 
    5325            0 :             char binary[20] = {'\0'}; /* e.g.: "0b1100 0010 0011 0110" */
    5326              :             int i;
    5327              : 
    5328            0 :             for (i = (1 << 15); i > 0; i >>= 1) {
    5329            0 :                 if (((1 << 3) == i) || ((1 << 7) == i) || ((1 << 11) == i))
    5330              :                     strcat(binary, " ");
    5331              : 
    5332            0 :                 strcat(binary, (i == (value16u & i)) ? "1" : "0");
    5333              :             }
    5334              : 
    5335              :             snprintf(value_text, textlength, "0b%s", binary);
    5336              :         }
    5337            1 :     } else if ((type_info & DLT_TYPE_INFO_UINT) && (DLT_SCOD_HEX == (type_info & DLT_TYPE_INFO_SCOD))) {
    5338            0 :         if (DLT_TYLE_8BIT == (type_info & DLT_TYPE_INFO_TYLE)) {
    5339            0 :             DLT_MSG_READ_VALUE(value8u, *ptr, *datalength, uint8_t); /* No endian conversion necessary */
    5340              : 
    5341            0 :             if ((*datalength) < 0)
    5342              :                 return DLT_RETURN_ERROR;
    5343              : 
    5344            0 :             snprintf(value_text, textlength, "0x%02x", value8u);
    5345              :         }
    5346              : 
    5347            0 :         if (DLT_TYLE_16BIT == (type_info & DLT_TYPE_INFO_TYLE)) {
    5348            0 :             DLT_MSG_READ_VALUE(value16u, *ptr, *datalength, uint16_t);
    5349              : 
    5350            0 :             if ((*datalength) < 0)
    5351              :                 return DLT_RETURN_ERROR;
    5352              : 
    5353            0 :             snprintf(value_text, textlength, "0x%04x", value16u);
    5354              :         }
    5355              : 
    5356            0 :         if (DLT_TYLE_32BIT == (type_info & DLT_TYPE_INFO_TYLE)) {
    5357            0 :             DLT_MSG_READ_VALUE(value32u, *ptr, *datalength, uint32_t);
    5358            0 :             if ((*datalength) < 0)
    5359              :                 return DLT_RETURN_ERROR;
    5360              : 
    5361              :             snprintf(value_text, textlength, "0x%08x", value32u);
    5362              :         }
    5363              : 
    5364            0 :         if (DLT_TYLE_64BIT == (type_info & DLT_TYPE_INFO_TYLE)) {
    5365            0 :             *ptr += 4;
    5366            0 :             DLT_MSG_READ_VALUE(value32u, *ptr, *datalength, uint32_t);
    5367              : 
    5368            0 :             if ((*datalength) < 0)
    5369              :                 return DLT_RETURN_ERROR;
    5370              : 
    5371              :             snprintf(value_text, textlength, "0x%08x", value32u);
    5372            0 :             *ptr -= 8;
    5373            0 :             DLT_MSG_READ_VALUE(value32u, *ptr, *datalength, uint32_t);
    5374              : 
    5375            0 :             if ((*datalength) < 0)
    5376              :                 return DLT_RETURN_ERROR;
    5377              : 
    5378            0 :             snprintf(value_text + strlen(value_text), textlength - strlen(value_text), "%08x", value32u);
    5379            0 :             *ptr += 4;
    5380              :         }
    5381            1 :     } else if ((type_info & DLT_TYPE_INFO_SINT) || (type_info & DLT_TYPE_INFO_UINT)) {
    5382              :         /* signed or unsigned argument received */
    5383            0 :         if (type_info & DLT_TYPE_INFO_VARI) {
    5384            0 :             DLT_MSG_READ_VALUE(value16u_tmp, *ptr, *datalength, uint16_t);
    5385              : 
    5386            0 :             if ((*datalength) < 0)
    5387              :                 return DLT_RETURN_ERROR;
    5388              : 
    5389              :             length2 = (uint16_t)DLT_LETOH_16(value16u_tmp);
    5390            0 :             DLT_MSG_READ_VALUE(value16u_tmp, *ptr, *datalength, uint16_t);
    5391              : 
    5392            0 :             if ((*datalength) < 0)
    5393              :                 return DLT_RETURN_ERROR;
    5394              : 
    5395              :             length3 = (uint16_t)DLT_LETOH_16(value16u_tmp);
    5396              : 
    5397            0 :             if ((*datalength) < length2)
    5398              :                 return DLT_RETURN_ERROR;
    5399              : 
    5400            0 :             if (print_with_attributes) {
    5401              :                 // Print "name" attribute, if we have one with non-zero size.
    5402            0 :                 if (length2 > 1) {
    5403            0 :                     snprintf(text, textlength, "%s:", *ptr);
    5404            0 :                     value_text += (size_t)length2 + 1 - 1;  // +1 for the ":", and -1 for nul
    5405            0 :                     textlength -= (size_t)length2 + 1 - 1;
    5406              :                 }
    5407              :             }
    5408              : 
    5409            0 :             *ptr += length2;
    5410            0 :             *datalength -= length2;
    5411              : 
    5412            0 :             if ((*datalength) < length3)
    5413              :                 return DLT_RETURN_ERROR;
    5414              : 
    5415              :             // We want to add the "unit" attribute only after the value, so remember its pointer and length here.
    5416              :             unit_text_src = *ptr;
    5417            0 :             unit_text_len = length3;
    5418              : 
    5419            0 :             *ptr += length3;
    5420            0 :             *datalength -= length3;
    5421              :         }
    5422              : 
    5423            0 :         if (type_info & DLT_TYPE_INFO_FIXP) {
    5424            0 :             DLT_MSG_READ_VALUE(quantisation_tmp, *ptr, *datalength, uint32_t);
    5425              : 
    5426            0 :             if ((*datalength) < 0)
    5427              :                 return DLT_RETURN_ERROR;
    5428              : 
    5429            0 :             switch (type_info & DLT_TYPE_INFO_TYLE) {
    5430            0 :             case DLT_TYLE_8BIT:
    5431              :             case DLT_TYLE_16BIT:
    5432              :             case DLT_TYLE_32BIT: {
    5433            0 :                 if ((*datalength) < 4)
    5434              :                     return DLT_RETURN_ERROR;
    5435              : 
    5436            0 :                 *ptr += 4;
    5437            0 :                 *datalength -= 4;
    5438            0 :                 break;
    5439              :             }
    5440            0 :             case DLT_TYLE_64BIT: {
    5441            0 :                 if ((*datalength) < 8)
    5442              :                     return DLT_RETURN_ERROR;
    5443              : 
    5444            0 :                 *ptr += 8;
    5445            0 :                 *datalength -= 8;
    5446            0 :                 break;
    5447              :             }
    5448            0 :             case DLT_TYLE_128BIT: {
    5449            0 :                 if ((*datalength) < 16)
    5450              :                     return DLT_RETURN_ERROR;
    5451              : 
    5452            0 :                 *ptr += 16;
    5453            0 :                 *datalength -= 16;
    5454            0 :                 break;
    5455              :             }
    5456              :             default: {
    5457              :                 return DLT_RETURN_ERROR;
    5458              :             }
    5459              :             }
    5460              :         }
    5461              : 
    5462            0 :         switch (type_info & DLT_TYPE_INFO_TYLE) {
    5463            0 :         case DLT_TYLE_8BIT: {
    5464            0 :             if (type_info & DLT_TYPE_INFO_SINT) {
    5465              :                 value8i = 0;
    5466            0 :                 DLT_MSG_READ_VALUE(value8i, *ptr, *datalength, int8_t); /* No endian conversion necessary */
    5467              : 
    5468            0 :                 if ((*datalength) < 0)
    5469              :                     return DLT_RETURN_ERROR;
    5470              : 
    5471            0 :                 snprintf(value_text, textlength, "%d", value8i);
    5472              :             } else {
    5473              :                 value8u = 0;
    5474            0 :                 DLT_MSG_READ_VALUE(value8u, *ptr, *datalength, uint8_t); /* No endian conversion necessary */
    5475              : 
    5476            0 :                 if ((*datalength) < 0)
    5477              :                     return DLT_RETURN_ERROR;
    5478              : 
    5479            0 :                 snprintf(value_text, textlength, "%d", value8u);
    5480              :             }
    5481              : 
    5482              :             break;
    5483              :         }
    5484            0 :         case DLT_TYLE_16BIT: {
    5485            0 :             if (type_info & DLT_TYPE_INFO_SINT) {
    5486              :                 value16i = 0;
    5487              :                 value16i_tmp = 0;
    5488            0 :                 DLT_MSG_READ_VALUE(value16i_tmp, *ptr, *datalength, int16_t);
    5489              : 
    5490            0 :                 if ((*datalength) < 0)
    5491              :                     return DLT_RETURN_ERROR;
    5492              : 
    5493              :                 value16i = (int16_t)DLT_LETOH_16(value16i_tmp);
    5494            0 :                 snprintf(value_text, textlength, "%hd", value16i);
    5495              :             } else {
    5496              :                 value16u = 0;
    5497              :                 value16u_tmp = 0;
    5498            0 :                 DLT_MSG_READ_VALUE(value16u_tmp, *ptr, *datalength, uint16_t);
    5499              : 
    5500            0 :                 if ((*datalength) < 0)
    5501              :                     return DLT_RETURN_ERROR;
    5502              : 
    5503              :                 value16u = (uint16_t)DLT_LETOH_16(value16u_tmp);
    5504            0 :                 snprintf(value_text, textlength, "%hu", value16u);
    5505              :             }
    5506              : 
    5507              :             break;
    5508              :         }
    5509            0 :         case DLT_TYLE_32BIT: {
    5510            0 :             if (type_info & DLT_TYPE_INFO_SINT) {
    5511              :                 value32i = 0;
    5512              :                 value32i_tmp = 0;
    5513            0 :                 DLT_MSG_READ_VALUE(value32i_tmp, *ptr, *datalength, int32_t);
    5514              : 
    5515            0 :                 if ((*datalength) < 0)
    5516              :                     return DLT_RETURN_ERROR;
    5517              : 
    5518              :                 value32i = (int32_t)DLT_LETOH_32((uint32_t)value32i_tmp);
    5519              :                 snprintf(value_text, textlength, "%d", value32i);
    5520              :             } else {
    5521              :                 value32u = 0;
    5522              :                 value32u_tmp = 0;
    5523            0 :                 DLT_MSG_READ_VALUE(value32u_tmp, *ptr, *datalength, uint32_t);
    5524              : 
    5525            0 :                 if ((*datalength) < 0)
    5526              :                     return DLT_RETURN_ERROR;
    5527              : 
    5528              :                 value32u = DLT_LETOH_32(value32u_tmp);
    5529              :                 snprintf(value_text, textlength, "%u", value32u);
    5530              :             }
    5531              : 
    5532              :             break;
    5533              :         }
    5534            0 :         case DLT_TYLE_64BIT: {
    5535            0 :             if (type_info & DLT_TYPE_INFO_SINT) {
    5536              :                 value64i = 0;
    5537              :                 value64i_tmp = 0;
    5538            0 :                 DLT_MSG_READ_VALUE(value64i_tmp, *ptr, *datalength, int64_t);
    5539              : 
    5540            0 :                 if ((*datalength) < 0)
    5541              :                     return DLT_RETURN_ERROR;
    5542              : 
    5543              :                 value64i = (int64_t)DLT_LETOH_64((uint64_t)value64i_tmp);
    5544              : #if defined(__WIN32__) && !defined(_MSC_VER)
    5545              :                 snprintf(value_text, textlength, "%I64d", value64i);
    5546              : #else
    5547              :                 snprintf(value_text, textlength, "%" PRId64, value64i);
    5548              : #endif
    5549              :             } else {
    5550              :                 value64u = 0;
    5551              :                 value64u_tmp = 0;
    5552            0 :                 DLT_MSG_READ_VALUE(value64u_tmp, *ptr, *datalength, uint64_t);
    5553              : 
    5554            0 :                 if ((*datalength) < 0)
    5555              :                     return DLT_RETURN_ERROR;
    5556              : 
    5557              :                 value64u = DLT_LETOH_64(value64u_tmp);
    5558              : #if defined(__WIN32__) && !defined(_MSC_VER)
    5559              :                 snprintf(value_text, textlength, "%I64u", value64u);
    5560              : #else
    5561              :                 snprintf(value_text, textlength, "%" PRIu64, value64u);
    5562              : #endif
    5563              :             }
    5564              : 
    5565              :             break;
    5566              :         }
    5567            0 :         case DLT_TYLE_128BIT: {
    5568            0 :             if (*datalength >= 16)
    5569            0 :                 dlt_print_hex_string(value_text, (int)textlength, *ptr, 16);
    5570              : 
    5571            0 :             if ((*datalength) < 16)
    5572              :                 return DLT_RETURN_ERROR;
    5573              : 
    5574            0 :             *ptr += 16;
    5575            0 :             *datalength -= 16;
    5576            0 :             break;
    5577              :         }
    5578              :         default: {
    5579              :             return DLT_RETURN_ERROR;
    5580              :         }
    5581              :         }
    5582            1 :     } else if (type_info & DLT_TYPE_INFO_FLOA) {
    5583              :         /* float data argument */
    5584            0 :         if (type_info & DLT_TYPE_INFO_VARI) {
    5585            0 :             DLT_MSG_READ_VALUE(value16u_tmp, *ptr, *datalength, uint16_t);
    5586              : 
    5587            0 :             if ((*datalength) < 0)
    5588              :                 return DLT_RETURN_ERROR;
    5589              : 
    5590              :             length2 = DLT_LETOH_16(value16u_tmp);
    5591            0 :             DLT_MSG_READ_VALUE(value16u_tmp, *ptr, *datalength, uint16_t);
    5592              : 
    5593            0 :             if ((*datalength) < 0)
    5594              :                 return DLT_RETURN_ERROR;
    5595              : 
    5596              :             length3 = DLT_LETOH_16(value16u_tmp);
    5597              : 
    5598            0 :             if ((*datalength) < length2)
    5599              :                 return DLT_RETURN_ERROR;
    5600              : 
    5601            0 :             if (print_with_attributes) {
    5602              :                 // Print "name" attribute, if we have one with non-zero size.
    5603            0 :                 if (length2 > 1) {
    5604            0 :                     snprintf(text, textlength, "%s:", *ptr);
    5605            0 :                     value_text += (size_t)length2 + 1 - 1;  // +1 for ":" and -1 for NUL
    5606            0 :                     textlength -= (size_t)length2 + 1 - 1;
    5607              :                 }
    5608              :             }
    5609              : 
    5610            0 :             *ptr += length2;
    5611            0 :             *datalength -= length2;
    5612              : 
    5613            0 :             if ((*datalength) < length3)
    5614              :                 return DLT_RETURN_ERROR;
    5615              : 
    5616              :             // We want to add the "unit" attribute only after the value, so remember its pointer and length here.
    5617              :             unit_text_src = *ptr;
    5618            0 :             unit_text_len = length3;
    5619              : 
    5620            0 :             *ptr += length3;
    5621            0 :             *datalength -= length3;
    5622              :         }
    5623              : 
    5624            0 :         switch (type_info & DLT_TYPE_INFO_TYLE) {
    5625            0 :         case DLT_TYLE_8BIT: {
    5626            0 :             if (*datalength >= 1)
    5627            0 :                 dlt_print_hex_string(value_text, (int)textlength, *ptr, 1);
    5628              : 
    5629            0 :             if ((*datalength) < 1)
    5630              :                 return DLT_RETURN_ERROR;
    5631              : 
    5632            0 :             *ptr += 1;
    5633            0 :             *datalength -= 1;
    5634            0 :             break;
    5635              :         }
    5636            0 :         case DLT_TYLE_16BIT: {
    5637            0 :             if (*datalength >= 2)
    5638            0 :                 dlt_print_hex_string(value_text, (int)textlength, *ptr, 2);
    5639              : 
    5640            0 :             if ((*datalength) < 2)
    5641              :                 return DLT_RETURN_ERROR;
    5642              : 
    5643            0 :             *ptr += 2;
    5644            0 :             *datalength -= 2;
    5645            0 :             break;
    5646              :         }
    5647              :         case DLT_TYLE_32BIT: {
    5648              :             if (sizeof(float32_t) == 4) {
    5649              :                 value32f = 0;
    5650              :                 value32f_tmp = 0;
    5651              :                 value32f_tmp_int32i = 0;
    5652              :                 value32f_tmp_int32i_swaped = 0;
    5653            0 :                 DLT_MSG_READ_VALUE(value32f_tmp, *ptr, *datalength, float32_t);
    5654              : 
    5655            0 :                 if ((*datalength) < 0)
    5656              :                     return DLT_RETURN_ERROR;
    5657              : 
    5658              :                 memcpy(&value32f_tmp_int32i, &value32f_tmp, sizeof(float32_t));
    5659              :                 value32f_tmp_int32i_swaped = (int32_t)DLT_LETOH_32((uint32_t)value32f_tmp_int32i);
    5660              :                 memcpy(&value32f, &value32f_tmp_int32i_swaped, sizeof(float32_t));
    5661            0 :                 snprintf(value_text, textlength, "%g", value32f);
    5662              :             } else {
    5663              :                 dlt_log(LOG_ERR, "Invalid size of float32_t\n");
    5664              :                 return DLT_RETURN_ERROR;
    5665              :             }
    5666              : 
    5667              :             break;
    5668              :         }
    5669              :         case DLT_TYLE_64BIT: {
    5670              :             if (sizeof(float64_t) == 8) {
    5671              :                 value64f = 0;
    5672              :                 value64f_tmp = 0;
    5673              :                 value64f_tmp_int64i = 0;
    5674              :                 value64f_tmp_int64i_swaped = 0;
    5675            0 :                 DLT_MSG_READ_VALUE(value64f_tmp, *ptr, *datalength, float64_t);
    5676              : 
    5677            0 :                 if ((*datalength) < 0)
    5678              :                     return DLT_RETURN_ERROR;
    5679              : 
    5680              :                 memcpy(&value64f_tmp_int64i, &value64f_tmp, sizeof(float64_t));
    5681              :                 value64f_tmp_int64i_swaped = (int64_t)DLT_LETOH_64((uint64_t)value64f_tmp_int64i);
    5682              :                 memcpy(&value64f, &value64f_tmp_int64i_swaped, sizeof(float64_t));
    5683              : #ifdef __arm__
    5684              :                 snprintf(value_text, textlength, "ILLEGAL");
    5685              : #else
    5686              :                 snprintf(value_text, textlength, "%g", value64f);
    5687              : #endif
    5688              :             } else {
    5689              :                 dlt_log(LOG_ERR, "Invalid size of float64_t\n");
    5690              :                 return DLT_RETURN_ERROR;
    5691              :             }
    5692              : 
    5693              :             break;
    5694              :         }
    5695            0 :         case DLT_TYLE_128BIT: {
    5696            0 :             if (*datalength >= 16)
    5697            0 :                 dlt_print_hex_string(value_text, (int)textlength, *ptr, 16);
    5698              : 
    5699            0 :             if ((*datalength) < 16)
    5700              :                 return DLT_RETURN_ERROR;
    5701              : 
    5702            0 :             *ptr += 16;
    5703            0 :             *datalength -= 16;
    5704            0 :             break;
    5705              :         }
    5706              :         default: {
    5707              :             return DLT_RETURN_ERROR;
    5708              :         }
    5709              :         }
    5710            1 :     } else if (type_info & DLT_TYPE_INFO_RAWD) {
    5711              :         /* raw data argument */
    5712            0 :         DLT_MSG_READ_VALUE(value16u_tmp, *ptr, *datalength, uint16_t);
    5713              : 
    5714            0 :         if ((*datalength) < 0)
    5715              :             return DLT_RETURN_ERROR;
    5716              : 
    5717              :         length = DLT_LETOH_16(value16u_tmp);
    5718              : 
    5719            0 :         if (type_info & DLT_TYPE_INFO_VARI) {
    5720            0 :             DLT_MSG_READ_VALUE(value16u_tmp, *ptr, *datalength, uint16_t);
    5721              : 
    5722            0 :             if ((*datalength) < 0)
    5723              :                 return DLT_RETURN_ERROR;
    5724              : 
    5725              :             length2 = DLT_LETOH_16(value16u_tmp);
    5726              : 
    5727            0 :             if ((*datalength) < length2)
    5728              :                 return DLT_RETURN_ERROR;
    5729              : 
    5730            0 :             if (print_with_attributes) {
    5731              :                 // Print "name" attribute, if we have one with non-zero size.
    5732            0 :                 if (length2 > 1) {
    5733            0 :                     snprintf(text, textlength, "%s:", *ptr);
    5734            0 :                     value_text += (size_t)length2 + 1 - 1;  // +1 for ":" and -1 for NUL
    5735            0 :                     textlength -= (size_t)length2 + 1 - 1;
    5736              :                 }
    5737              :             }
    5738              : 
    5739            0 :             *ptr += length2;
    5740            0 :             *datalength -= length2;
    5741              :         }
    5742              : 
    5743            0 :         if ((*datalength) < length)
    5744              :             return DLT_RETURN_ERROR;
    5745              : 
    5746            0 :         if (dlt_print_hex_string_delim(value_text, (int)textlength, *ptr, length, '\'') < DLT_RETURN_OK)
    5747              :             return DLT_RETURN_ERROR;
    5748            0 :         *ptr += length;
    5749            0 :         *datalength -= length;
    5750            1 :     } else if (type_info & DLT_TYPE_INFO_TRAI) {
    5751              :         /* trace info argument */
    5752            0 :         DLT_MSG_READ_VALUE(value16u_tmp, *ptr, *datalength, uint16_t);
    5753              : 
    5754            0 :         if ((*datalength) < 0)
    5755              :             return DLT_RETURN_ERROR;
    5756              : 
    5757              :         length = DLT_LETOH_16(value16u_tmp);
    5758              : 
    5759            0 :         DLT_MSG_READ_STRING(value_text, *ptr, *datalength, textlength, length);
    5760              : 
    5761            0 :         if ((*datalength) < 0)
    5762              :             return DLT_RETURN_ERROR;
    5763              :     } else {
    5764              :         return DLT_RETURN_ERROR;
    5765              :     }
    5766              : 
    5767            0 :     if (*datalength < 0) {
    5768            0 :         dlt_log(LOG_ERR, "Payload of DLT message corrupted\n");
    5769            0 :         return DLT_RETURN_ERROR;
    5770              :     }
    5771              : 
    5772              :     // Now write "unit" attribute, but only if it has more than only a nul-termination char.
    5773            0 :     if (print_with_attributes) {
    5774            0 :         if (unit_text_len > 1) {
    5775              :             // 'value_text' still points to the +start+ of the value text
    5776            0 :             size_t currLen = strlen(value_text);
    5777              : 
    5778            0 :             char* unitText = value_text + currLen;
    5779            0 :             textlength -= currLen;
    5780              :             snprintf(unitText, textlength, ":%s", unit_text_src);
    5781              :         }
    5782              :     }
    5783              : 
    5784              :     return DLT_RETURN_OK;
    5785              : }
    5786              : 
    5787        21002 : void dlt_check_envvar()
    5788              : {
    5789        21002 :     char* env_log_filename = getenv("DLT_LOG_FILENAME");
    5790              : 
    5791        21002 :     if (env_log_filename != NULL)
    5792            0 :         dlt_log_set_filename(env_log_filename);
    5793              : 
    5794        21002 :     char* env_log_level_str = getenv("DLT_LOG_LEVEL");
    5795              : 
    5796        21002 :     if (env_log_level_str != NULL) {
    5797            0 :         int level = 0;
    5798              : 
    5799            0 :         if (sscanf(env_log_level_str, "%d", &level) == 1)
    5800            0 :             dlt_log_set_level(level);
    5801              :     }
    5802              : 
    5803        21002 :     char* env_log_mode = getenv("DLT_LOG_MODE");
    5804              : 
    5805        21002 :     if (env_log_mode != NULL) {
    5806            0 :         int mode = 0;
    5807              : 
    5808            0 :         if (sscanf(env_log_mode, "%d", &mode) == 1)
    5809            0 :             dlt_log_init(mode);
    5810              :     }
    5811              : 
    5812              : #if defined DLT_DAEMON_USE_FIFO_IPC || defined DLT_LIB_USE_FIFO_IPC
    5813        21002 :     char* env_pipe_dir = getenv("DLT_PIPE_DIR");
    5814              : 
    5815        21002 :     if (env_pipe_dir != NULL)
    5816            0 :         dlt_log_set_fifo_basedir(env_pipe_dir);
    5817              :     else
    5818        21002 :         dlt_log_set_fifo_basedir(DLT_USER_IPC_PATH);
    5819              : 
    5820              : #endif
    5821              : 
    5822              : #ifdef DLT_SHM_ENABLE
    5823              :     char* env_shm_name = getenv("DLT_SHM_NAME");
    5824              : 
    5825              :     if (env_shm_name != NULL)
    5826              :         dlt_log_set_shm_name(env_shm_name);
    5827              : 
    5828              : #endif
    5829        21002 : }
    5830              : 
    5831            2 : int dlt_set_loginfo_parse_service_id(char* resp_text, uint32_t* service_id, uint8_t* service_opt)
    5832              : {
    5833              :     int ret = -1;
    5834              :     char get_log_info_tag[GET_LOG_INFO_LENGTH];
    5835              :     char service_opt_str[SERVICE_OPT_LENGTH];
    5836              : 
    5837            2 :     if ((resp_text == NULL) || (service_id == NULL) || (service_opt == NULL))
    5838              :         return DLT_RETURN_ERROR;
    5839              : 
    5840              :     /* ascii type, syntax is 'get_log_info, ..' */
    5841              :     /* check target id */
    5842              :     strncpy(get_log_info_tag, "get_log_info", strlen("get_log_info") + 1);
    5843            2 :     ret = memcmp((void*)resp_text, (void*)get_log_info_tag, sizeof(get_log_info_tag) - 1);
    5844              : 
    5845            2 :     if (ret == 0) {
    5846            2 :         *service_id = DLT_SERVICE_ID_GET_LOG_INFO;
    5847              :         /* reading the response mode from the resp_text. eg. option 7*/
    5848            2 :         service_opt_str[0] = *(resp_text + GET_LOG_INFO_LENGTH + 1);
    5849            2 :         service_opt_str[1] = *(resp_text + GET_LOG_INFO_LENGTH + 2);
    5850            2 :         service_opt_str[2] = 0;
    5851            2 :         *service_opt = (uint8_t)atoi(service_opt_str);
    5852              :     }
    5853              : 
    5854              :     return ret;
    5855              : }
    5856              : 
    5857           14 : uint16_t dlt_getloginfo_conv_ascii_to_uint16_t(char* rp, int* rp_count)
    5858              : {
    5859           14 :     char num_work[5] = {0};
    5860              :     char* endptr;
    5861              : 
    5862           14 :     if ((rp == NULL) || (rp_count == NULL))
    5863              :         return (uint16_t)0xFFFF;
    5864              : 
    5865              :     /* ------------------------------------------------------
    5866              :      *  from: [89 13 ] -> to: ['+0x'1389\0] -> to num
    5867              :      *  ------------------------------------------------------ */
    5868           14 :     num_work[0] = *(rp + *rp_count + 3);
    5869           14 :     num_work[1] = *(rp + *rp_count + 4);
    5870           14 :     num_work[2] = *(rp + *rp_count + 0);
    5871           14 :     num_work[3] = *(rp + *rp_count + 1);
    5872              :     num_work[4] = 0;
    5873           14 :     *rp_count += 6;
    5874              : 
    5875           14 :     return (uint16_t)strtol(num_work, &endptr, 16);
    5876              : }
    5877              : 
    5878           12 : int16_t dlt_getloginfo_conv_ascii_to_int16_t(char* rp, int* rp_count)
    5879              : {
    5880           12 :     char num_work[3] = {0};
    5881              :     char* endptr;
    5882              : 
    5883           12 :     if ((rp == NULL) || (rp_count == NULL))
    5884              :         return -1;
    5885              : 
    5886              :     /* ------------------------------------------------------
    5887              :      *  from: [89 ] -> to: ['0x'89\0] -> to num
    5888              :      *  ------------------------------------------------------ */
    5889           12 :     num_work[0] = *(rp + *rp_count + 0);
    5890           12 :     num_work[1] = *(rp + *rp_count + 1);
    5891              :     num_work[2] = 0;
    5892           12 :     *rp_count += 3;
    5893              : 
    5894           12 :     return (signed char)strtol(num_work, &endptr, 16);
    5895              : }
    5896              : 
    5897            0 : uint8_t dlt_getloginfo_conv_ascii_to_uint8_t(char* rp, int* rp_count)
    5898              : {
    5899            0 :     char num_work[3] = {0};
    5900              :     char* endptr;
    5901              : 
    5902            0 :     if ((rp == NULL) || (rp_count == NULL))
    5903              :         return (uint8_t)-1;
    5904              : 
    5905              :     /* ------------------------------------------------------
    5906              :      *  from: [89 ] -> to: ['0x'89\0] -> to num
    5907              :      *  ------------------------------------------------------ */
    5908            0 :     num_work[0] = *(rp + *rp_count + 0);
    5909            0 :     num_work[1] = *(rp + *rp_count + 1);
    5910              :     num_work[2] = 0;
    5911            0 :     *rp_count += 3;
    5912              : 
    5913            0 :     return (uint8_t)strtol(num_work, &endptr, 16);
    5914              : }
    5915              : 
    5916           11 : void dlt_getloginfo_conv_ascii_to_string(char* rp, int* rp_count, char* wp, int len)
    5917              : {
    5918           11 :     if ((rp == NULL) || (rp_count == NULL) || (wp == NULL))
    5919              :         return;
    5920              :     /* ------------------------------------------------------
    5921              :      *  from: [72 65 6d 6f ] -> to: [0x72,0x65,0x6d,0x6f,0x00]
    5922              :      *  ------------------------------------------------------ */
    5923              : 
    5924           11 :     int count = dlt_getloginfo_conv_ascii_to_id(rp, rp_count, wp, len);
    5925           11 :     *(wp + count) = '\0';
    5926              : 
    5927           11 :     return;
    5928              : }
    5929              : 
    5930           20 : int dlt_getloginfo_conv_ascii_to_id(char* rp, int* rp_count, char* wp, int len)
    5931              : {
    5932           20 :     char number16[3] = {0};
    5933              :     char* endptr;
    5934              :     int count;
    5935              : 
    5936           20 :     if ((rp == NULL) || (rp_count == NULL) || (wp == NULL))
    5937              :         return 0;
    5938              : 
    5939              :     /* ------------------------------------------------------
    5940              :      *  from: [72 65 6d 6f ] -> to: [0x72,0x65,0x6d,0x6f]
    5941              :      *  ------------------------------------------------------ */
    5942          289 :     for (count = 0; count < len; count++) {
    5943          269 :         number16[0] = *(rp + *rp_count + 0);
    5944          269 :         number16[1] = *(rp + *rp_count + 1);
    5945          269 :         *(wp + count) = (char)strtol(number16, &endptr, 16);
    5946          269 :         *rp_count += 3;
    5947              :     }
    5948              : 
    5949              :     return count;
    5950              : }
    5951              : 
    5952            0 : void dlt_hex_ascii_to_binary(const char* ptr, uint8_t* binary, int* size)
    5953              : {
    5954            0 :     char ch = *ptr;
    5955              :     int pos = 0;
    5956            0 :     binary[pos] = 0;
    5957              :     int first = 1;
    5958              :     int found;
    5959              : 
    5960              :     for (;;) {
    5961            0 :         if (ch == 0) {
    5962            0 :             *size = pos;
    5963            0 :             return;
    5964              :         }
    5965              : 
    5966              :         found = 0;
    5967              : 
    5968            0 :         if ((ch >= '0') && (ch <= '9')) {
    5969            0 :             binary[pos] = (uint8_t)((binary[pos] << 4) + (ch - '0'));
    5970              :             found = 1;
    5971            0 :         } else if ((ch >= 'A') && (ch <= 'F')) {
    5972            0 :             binary[pos] = (uint8_t)((binary[pos] << 4) + (ch - 'A' + 10));
    5973              :             found = 1;
    5974            0 :         } else if ((ch >= 'a') && (ch <= 'f')) {
    5975            0 :             binary[pos] = (uint8_t)((binary[pos] << 4) + (ch - 'a' + 10));
    5976              :             found = 1;
    5977              :         }
    5978              : 
    5979              :         if (found) {
    5980            0 :             if (first) {
    5981              :                 first = 0;
    5982              :             } else {
    5983              :                 first = 1;
    5984            0 :                 pos++;
    5985              : 
    5986            0 :                 if (pos >= *size)
    5987              :                     return;
    5988              : 
    5989            0 :                 binary[pos] = 0;
    5990              :             }
    5991              :         }
    5992              : 
    5993            0 :         ch = *(++ptr);
    5994              :     }
    5995              : }
    5996              : 
    5997            3 : DltReturnValue dlt_file_quick_parsing(DltFile* file, const char* filename, int type, int verbose)
    5998              : {
    5999            3 :     PRINT_FUNCTION_VERBOSE(verbose);
    6000              :     int ret = DLT_RETURN_OK;
    6001            3 :     char text[DLT_CONVERT_TEXTBUFSIZE] = {0};
    6002              : 
    6003            3 :     if ((file == NULL) || (filename == NULL))
    6004              :         return DLT_RETURN_WRONG_PARAMETER;
    6005              : 
    6006            1 :     FILE* output = fopen(filename, "w+");
    6007              : 
    6008            1 :     if (output == NULL) {
    6009            0 :         dlt_vlog(LOG_ERR, "Cannot open output file %s for parsing\n", filename);
    6010            0 :         return DLT_RETURN_ERROR;
    6011              :     }
    6012              : 
    6013          106 :     while (ret >= DLT_RETURN_OK && file->file_position < file->file_length) {
    6014              :         /* get file position at start of DLT message */
    6015          105 :         if (verbose)
    6016            0 :             dlt_vlog(LOG_DEBUG, "Position in file: %" PRIu64 "\n", file->file_position);
    6017              : 
    6018              :         /* read all header and payload */
    6019          105 :         ret = dlt_file_read_header(file, verbose);
    6020              : 
    6021          105 :         if (ret < DLT_RETURN_OK)
    6022              :             break;
    6023              : 
    6024          105 :         ret = dlt_file_read_header_extended(file, verbose);
    6025              : 
    6026          105 :         if (ret < DLT_RETURN_OK)
    6027              :             break;
    6028              : 
    6029          105 :         ret = dlt_file_read_data(file, verbose);
    6030              : 
    6031          105 :         if (ret < DLT_RETURN_OK)
    6032              :             break;
    6033              : 
    6034          105 :         if (file->filter) {
    6035              :             /* check the filters if message is used */
    6036            0 :             ret = dlt_message_filter_check(&(file->msg), file->filter, verbose);
    6037              : 
    6038            0 :             if (ret != DLT_RETURN_TRUE)
    6039            0 :                 continue;
    6040              :         }
    6041              : 
    6042          105 :         ret = dlt_message_header(&(file->msg), text, DLT_CONVERT_TEXTBUFSIZE, verbose);
    6043              : 
    6044          105 :         if (ret < DLT_RETURN_OK)
    6045              :             break;
    6046              : 
    6047              :         fprintf(output, "%s", text);
    6048              : 
    6049          105 :         ret = dlt_message_payload(&(file->msg), text, DLT_CONVERT_TEXTBUFSIZE, type, verbose);
    6050              : 
    6051          105 :         if (ret < DLT_RETURN_OK)
    6052              :             break;
    6053              : 
    6054              :         fprintf(output, "[%s]\n", text);
    6055              : 
    6056              :         /* store index pointer to message position in DLT file */
    6057          105 :         file->counter++;
    6058          105 :         file->position = file->counter_total - 1;
    6059              :         /* increase total message counter */
    6060          105 :         file->counter_total++;
    6061              :         /* store position to next message */
    6062          105 :         file->file_position = (uint64_t)ftell(file->handle);
    6063              :     } /* while() */
    6064              : 
    6065            1 :     fclose(output);
    6066            1 :     return ret;
    6067              : }
    6068              : 
    6069              : 
    6070            0 : int dlt_execute_command(char* filename, char* command, ...)
    6071              : {
    6072              :     va_list val;
    6073              :     int argc;
    6074              :     char** args = NULL;
    6075            0 :     int ret = 0;
    6076              : 
    6077            0 :     if (command == NULL)
    6078              :         return -1;
    6079              : 
    6080              :     /* Determine number of variadic arguments */
    6081            0 :     va_start(val, command);
    6082              : 
    6083            0 :     for (argc = 2; va_arg(val, char*) != NULL; argc++)
    6084              :         ;
    6085              : 
    6086            0 :     va_end(val);
    6087              : 
    6088              :     /* Allocate args, put references to command */
    6089            0 :     args = (char**)malloc((uint32_t)argc * sizeof(char*));
    6090            0 :     args[0] = command;
    6091              : 
    6092            0 :     va_start(val, command);
    6093              : 
    6094            0 :     for (int i = 0; args[i] != NULL; i++)
    6095            0 :         args[i + 1] = va_arg(val, char*);
    6096              : 
    6097            0 :     va_end(val);
    6098              : 
    6099              :     /* Run command in child process */
    6100            0 :     pid_t pid = fork();
    6101              : 
    6102            0 :     if (pid == 0) { /* child process */
    6103              : 
    6104              :         /* Redirect output if required */
    6105            0 :         if (filename != NULL) {
    6106              :             int fd = open(filename, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
    6107              : 
    6108            0 :             if (fd < 0)
    6109            0 :                 err(-1, "%s failed on open()", __func__);
    6110              : 
    6111            0 :             if (dup2(fd, STDOUT_FILENO) == -1) {
    6112            0 :                 close(fd);
    6113            0 :                 err(-1, "%s failed on dup2()", __func__);
    6114              :             }
    6115              : 
    6116            0 :             close(fd);
    6117              :         }
    6118              : 
    6119              :         /* Run command */
    6120            0 :         execvp(command, (char**)args);
    6121            0 :     } else if (pid == -1) /* error in fork */
    6122              :     {
    6123            0 :         ret = -1;
    6124              :     } else /* parent */
    6125              :     {
    6126            0 :         if (wait(&ret) == -1) {
    6127            0 :             err(-1, "%s failed on wait()", __func__);
    6128              :         }
    6129              :     }
    6130              : 
    6131            0 :     free(args);
    6132            0 :     return ret;
    6133              : }
    6134              : 
    6135            5 : const char* get_filename_ext(const char* filename)
    6136              : {
    6137            5 :     if (filename == NULL) {
    6138            0 :         fprintf(stderr, "ERROR: %s: invalid arguments\n", __func__);
    6139            0 :         return "";
    6140              :     }
    6141              : 
    6142            5 :     const char* dot = strrchr(filename, '.');
    6143            5 :     return (!dot || dot == filename) ? NULL : dot;
    6144              : }
    6145              : 
    6146            6 : bool dlt_extract_base_name_without_ext(const char* const abs_file_name, char* base_name, long base_name_len)
    6147              : {
    6148            6 :     if (abs_file_name == NULL || base_name == NULL)
    6149              :         return false;
    6150              : 
    6151            6 :     const char* last_separator = strrchr(abs_file_name, '.');
    6152            6 :     if (!last_separator)
    6153              :         return false;
    6154            5 :     long length = last_separator - abs_file_name;
    6155              :     /* Ensure length fits within buffer, leaving room for null terminator */
    6156            5 :     if (length >= base_name_len)
    6157            0 :         length = base_name_len - 1;
    6158              : 
    6159            5 :     strncpy(base_name, abs_file_name, (size_t)length);
    6160            5 :     base_name[length] = '\0';
    6161            5 :     return true;
    6162              : }
    6163              : 
    6164              : #ifdef DLT_TRACE_LOAD_CTRL_ENABLE
    6165              : static int32_t dlt_output_soft_limit_over_warning(
    6166              :     DltTraceLoadSettings* const tl_settings, DltLogInternal log_internal, void* const log_params)
    6167              : {
    6168              :     char local_str[255];
    6169              : 
    6170              :     if (!tl_settings || !tl_settings->tl_stat.is_over_soft_limit || tl_settings->tl_stat.slot_left_soft_limit_warn) {
    6171              :         /* No need to output warning message */
    6172              :         return 0;
    6173              :     }
    6174              : 
    6175              :     /* Calculate extra trace load which was over limit */
    6176              :     const uint64_t dropped_message_load =
    6177              :         (tl_settings->tl_stat.hard_limit_over_bytes * DLT_TIMESTAMP_RESOLUTION) / TIMESTAMP_BASED_WINDOW_SIZE;
    6178              :     const uint64_t curr_trace_load = tl_settings->tl_stat.avg_trace_load + dropped_message_load;
    6179              :     if (curr_trace_load <= tl_settings->soft_limit) {
    6180              :         /* No need to output warning message */
    6181              :         return 0;
    6182              :     }
    6183              : 
    6184              :     /* Warning for exceeded soft limit */
    6185              :     if (tl_settings->ctid[0] == 0) {
    6186              :         snprintf(
    6187              :             local_str, sizeof(local_str),
    6188              :             "Trace load exceeded trace soft limit on apid %.4s "
    6189              :             "(soft limit: %u bytes/sec, current: %lu bytes/sec)",
    6190              :             tl_settings->apid, tl_settings->soft_limit, curr_trace_load);
    6191              :     } else {
    6192              :         snprintf(
    6193              :             local_str, sizeof(local_str),
    6194              :             "Trace load exceeded trace soft limit on apid %.4s, ctid %.4s "
    6195              :             "(soft limit: %u bytes/sec, current: %lu bytes/sec)",
    6196              :             tl_settings->apid, tl_settings->ctid, tl_settings->soft_limit, curr_trace_load);
    6197              :     }
    6198              : 
    6199              :     // must be signed int for error return value
    6200              :     int32_t sent_size = log_internal(DLT_LOG_WARN, local_str, log_params);
    6201              :     if (sent_size < DLT_RETURN_OK) {
    6202              :         /* Output warning message via other route for safety */
    6203              :         dlt_log(DLT_LOG_WARN, local_str);
    6204              :         sent_size = 0;
    6205              :     }
    6206              : 
    6207              :     /* Turn off the flag after sending warning message */
    6208              :     tl_settings->tl_stat.is_over_soft_limit = false;
    6209              :     tl_settings->tl_stat.slot_left_soft_limit_warn = DLT_SOFT_LIMIT_WARN_FREQUENCY;
    6210              : 
    6211              :     return sent_size;
    6212              : }
    6213              : 
    6214              : static int32_t dlt_output_hard_limit_warning(
    6215              :     DltTraceLoadSettings* const tl_settings, DltLogInternal log_internal, void* const log_params)
    6216              : {
    6217              :     char local_str[255];
    6218              :     if (!tl_settings || !tl_settings->tl_stat.is_over_hard_limit || tl_settings->tl_stat.slot_left_hard_limit_warn) {
    6219              :         /* No need to output warning message */
    6220              :         return 0;
    6221              :     }
    6222              : 
    6223              :     /* Calculate extra trace load which was over limit */
    6224              :     const uint64_t dropped_message_load =
    6225              :         (tl_settings->tl_stat.hard_limit_over_bytes * DLT_TIMESTAMP_RESOLUTION) / TIMESTAMP_BASED_WINDOW_SIZE;
    6226              :     const uint64_t curr_trace_load = tl_settings->tl_stat.avg_trace_load + dropped_message_load;
    6227              :     if (curr_trace_load <= tl_settings->hard_limit) {
    6228              :         /* No need to output warning message */
    6229              :         return 0;
    6230              :     }
    6231              : 
    6232              :     if (tl_settings->ctid[0] == 0) {
    6233              :         snprintf(
    6234              :             local_str, sizeof(local_str),
    6235              :             "Trace load exceeded trace hard limit on apid %.4s "
    6236              :             "(hard limit: %u bytes/sec, current: %lu bytes/sec) %u messages discarded. ",
    6237              :             tl_settings->apid, tl_settings->hard_limit, curr_trace_load, tl_settings->tl_stat.hard_limit_over_counter);
    6238              :     } else {
    6239              :         snprintf(
    6240              :             local_str, sizeof(local_str),
    6241              :             "Trace load exceeded trace hard limit on apid %.4s, ctid %.4s."
    6242              :             "(hard limit: %u bytes/sec, current: %lu bytes/sec) %u messages discarded.",
    6243              :             tl_settings->apid, tl_settings->ctid, tl_settings->hard_limit, curr_trace_load,
    6244              :             tl_settings->tl_stat.hard_limit_over_counter);
    6245              :     }
    6246              : 
    6247              :     // must be signed int for error return
    6248              :     int32_t sent_size = log_internal(DLT_LOG_WARN, local_str, log_params);
    6249              :     if (sent_size < DLT_RETURN_OK) {
    6250              :         /* Output warning message via other route for safety */
    6251              :         dlt_log(DLT_LOG_WARN, local_str);
    6252              :         sent_size = 0;
    6253              :     }
    6254              : 
    6255              :     /* Turn off the flag after sending warning message */
    6256              :     tl_settings->tl_stat.is_over_hard_limit = false;
    6257              :     tl_settings->tl_stat.hard_limit_over_counter = 0;
    6258              :     tl_settings->tl_stat.hard_limit_over_bytes = 0;
    6259              :     tl_settings->tl_stat.slot_left_hard_limit_warn = DLT_HARD_LIMIT_WARN_FREQUENCY;
    6260              : 
    6261              :     return sent_size;
    6262              : }
    6263              : 
    6264              : static bool dlt_user_cleanup_window(DltTraceLoadStat* const tl_stat)
    6265              : {
    6266              :     if (!tl_stat) {
    6267              :         return false;
    6268              :     }
    6269              : 
    6270              :     uint32_t elapsed_slots = 0;
    6271              :     /* check if overflow of timestamp happened, after ~119 hours */
    6272              :     if (tl_stat->curr_abs_slot < tl_stat->last_abs_slot) {
    6273              :         /* calculate where the next slot starts according to the last slot
    6274              :          * This works because the value after the uint32 rollover equals is equal to the remainder that did not fit
    6275              :          * into uint32 before. Therefore, we always have slots that are DLT_TIMESTAMP_RESOLUTION long
    6276              :          * */
    6277              :         const uint32_t next_slot_start = DLT_TIMESTAMP_RESOLUTION + tl_stat->last_abs_slot;
    6278              : 
    6279              :         /* Check if we are already in the next slot */
    6280              :         if (next_slot_start <= tl_stat->curr_abs_slot) {
    6281              :             /* Calculate relative amount of elapsed slots */
    6282              :             elapsed_slots = (tl_stat->curr_abs_slot - next_slot_start) / DLT_TIMESTAMP_RESOLUTION + 1;
    6283              :         }
    6284              :         /* else we are not in the next slot yet */
    6285              :     } else {
    6286              :         /* no rollover, get difference between slots to get amount of elapsed slots  */
    6287              :         elapsed_slots = (tl_stat->curr_abs_slot - tl_stat->last_abs_slot);
    6288              :     }
    6289              : 
    6290              :     if (!elapsed_slots) {
    6291              :         /* Same slot can be still used. No need to cleanup slot */
    6292              :         return false;
    6293              :     }
    6294              : 
    6295              :     /* Slot-Based Count down for next warning messages */
    6296              :     tl_stat->slot_left_soft_limit_warn =
    6297              :         (tl_stat->slot_left_soft_limit_warn > elapsed_slots) ? (tl_stat->slot_left_soft_limit_warn - elapsed_slots) : 0;
    6298              : 
    6299              :     tl_stat->slot_left_hard_limit_warn =
    6300              :         (tl_stat->slot_left_hard_limit_warn > elapsed_slots) ? (tl_stat->slot_left_hard_limit_warn - elapsed_slots) : 0;
    6301              : 
    6302              :     /* Clear whole window when time elapsed longer than window size from last message */
    6303              :     if (elapsed_slots >= DLT_TRACE_LOAD_WINDOW_SIZE) {
    6304              :         tl_stat->total_bytes_of_window = 0;
    6305              :         memset(tl_stat->window, 0, sizeof(tl_stat->window));
    6306              :         return true;
    6307              :     }
    6308              : 
    6309              :     /* Clear skipped no data slots */
    6310              :     uint32_t temp_slot = tl_stat->last_slot;
    6311              :     while (temp_slot != tl_stat->curr_slot) {
    6312              :         temp_slot++;
    6313              :         temp_slot %= DLT_TRACE_LOAD_WINDOW_SIZE;
    6314              :         tl_stat->total_bytes_of_window -= tl_stat->window[temp_slot];
    6315              :         tl_stat->window[temp_slot] = 0;
    6316              :     }
    6317              : 
    6318              :     return true;
    6319              : }
    6320              : 
    6321              : static int32_t dlt_switch_slot_if_needed(
    6322              :     DltTraceLoadSettings* const tl_settings, DltLogInternal log_internal, void* const log_internal_params,
    6323              :     const uint32_t timestamp)
    6324              : {
    6325              :     if (!tl_settings) {
    6326              :         return 0;
    6327              :     }
    6328              : 
    6329              :     /* Get new window slot No. */
    6330              :     tl_settings->tl_stat.curr_abs_slot = timestamp / DLT_TRACE_LOAD_WINDOW_RESOLUTION;
    6331              :     tl_settings->tl_stat.curr_slot = tl_settings->tl_stat.curr_abs_slot % DLT_TRACE_LOAD_WINDOW_SIZE;
    6332              : 
    6333              :     /* Cleanup window */
    6334              :     if (!dlt_user_cleanup_window(&tl_settings->tl_stat)) {
    6335              :         /* No need to switch slot because same slot can be still used */
    6336              :         return 0;
    6337              :     }
    6338              : 
    6339              :     /* If slot is switched and trace load has been over soft/hard limit
    6340              :      * in previous slot, warning messages may be sent.
    6341              :      * The warning messages will be also counted as trace load.
    6342              :      */
    6343              :     const int32_t sent_warn_msg_bytes =
    6344              :         dlt_output_soft_limit_over_warning(tl_settings, log_internal, log_internal_params)
    6345              :         + dlt_output_hard_limit_warning(tl_settings, log_internal, log_internal_params);
    6346              :     return sent_warn_msg_bytes;
    6347              : }
    6348              : 
    6349              : static void dlt_record_trace_load(DltTraceLoadStat* const tl_stat, const int32_t size)
    6350              : {
    6351              :     if (!tl_stat) {
    6352              :         return;
    6353              :     }
    6354              : 
    6355              :     /* Record trace load to current slot by message size of
    6356              :      * original message and warning message if it was sent
    6357              :      */
    6358              :     tl_stat->window[tl_stat->curr_slot] += size;
    6359              :     tl_stat->total_bytes_of_window += size;
    6360              : 
    6361              :     /* Keep the latest time information */
    6362              :     tl_stat->last_abs_slot = tl_stat->curr_abs_slot;
    6363              :     tl_stat->last_slot = tl_stat->curr_slot;
    6364              : 
    6365              :     /* Calculate average trace load [bytes/sec] in window
    6366              :      * The division is necessary to normalize the average to bytes per second even if
    6367              :      * the slot size is not equal to 1s
    6368              :      * */
    6369              :     tl_stat->avg_trace_load = (tl_stat->total_bytes_of_window * DLT_TIMESTAMP_RESOLUTION) / TIMESTAMP_BASED_WINDOW_SIZE;
    6370              : }
    6371              : 
    6372              : static inline bool dlt_is_over_trace_load_soft_limit(DltTraceLoadSettings* const tl_settings)
    6373              : {
    6374              :     if (tl_settings
    6375              :         && (tl_settings->tl_stat.avg_trace_load > tl_settings->soft_limit || tl_settings->soft_limit == 0)) {
    6376              :         /* Mark as soft limit over */
    6377              :         tl_settings->tl_stat.is_over_soft_limit = true;
    6378              :         return true;
    6379              :     }
    6380              : 
    6381              :     return false;
    6382              : }
    6383              : 
    6384              : static inline bool dlt_is_over_trace_load_hard_limit(DltTraceLoadSettings* const tl_settings, const int size)
    6385              : {
    6386              :     if (tl_settings
    6387              :         && (tl_settings->tl_stat.avg_trace_load > tl_settings->hard_limit || tl_settings->hard_limit == 0)) {
    6388              :         /* Mark as limit over */
    6389              :         tl_settings->tl_stat.is_over_hard_limit = true;
    6390              :         tl_settings->tl_stat.hard_limit_over_counter++;
    6391              :         tl_settings->tl_stat.hard_limit_over_bytes += size;
    6392              : 
    6393              :         /* Delete size of limit over message from window */
    6394              :         tl_settings->tl_stat.window[tl_settings->tl_stat.curr_slot] -= size;
    6395              :         tl_settings->tl_stat.total_bytes_of_window -= size;
    6396              :         return true;
    6397              :     }
    6398              : 
    6399              :     return false;
    6400              : }
    6401              : 
    6402              : bool dlt_check_trace_load(
    6403              :     DltTraceLoadSettings* const tl_settings, const int32_t log_level, const uint32_t timestamp, const int32_t size,
    6404              :     DltLogInternal internal_dlt_log, void* const internal_dlt_log_params)
    6405              : {
    6406              :     /* Unconditionally allow message which has log level: Debug/Verbose to be output */
    6407              :     if (log_level == DLT_LOG_DEBUG || log_level == DLT_LOG_VERBOSE) {
    6408              :         return true;
    6409              :     }
    6410              : 
    6411              :     if (tl_settings == NULL) {
    6412              :         internal_dlt_log(DLT_LOG_ERROR, "tl_settings is NULL", internal_dlt_log_params);
    6413              :         return false;
    6414              :     }
    6415              : 
    6416              :     if (size < 0) {
    6417              :         dlt_vlog(LOG_ERR, "Invalid size: %d", size);
    6418              :         return false;
    6419              :     }
    6420              : 
    6421              :     /* Switch window slot according to timestamp
    6422              :      * If warning messages for hard/soft limit over are sent,
    6423              :      * the message size will be returned.
    6424              :      */
    6425              :     const int32_t sent_warn_msg_bytes =
    6426              :         dlt_switch_slot_if_needed(tl_settings, internal_dlt_log, internal_dlt_log_params, timestamp);
    6427              : 
    6428              :     /* Record trace load */
    6429              :     dlt_record_trace_load(&tl_settings->tl_stat, size + sent_warn_msg_bytes);
    6430              : 
    6431              :     /* Check if trace load is over the soft limit.
    6432              :      * Even if trace load is over the soft limit, message will not be discarded.
    6433              :      * Only the warning message will be output
    6434              :      */
    6435              :     dlt_is_over_trace_load_soft_limit(tl_settings);
    6436              : 
    6437              :     /* Check if trace load is over hard limit.
    6438              :      * If trace load is over the limit, message will be discarded.
    6439              :      */
    6440              :     const bool allow_output = !dlt_is_over_trace_load_hard_limit(tl_settings, size);
    6441              : 
    6442              :     return allow_output;
    6443              : }
    6444              : 
    6445              : DltTraceLoadSettings* dlt_find_runtime_trace_load_settings(
    6446              :     DltTraceLoadSettings* settings, uint32_t settings_count, const char* apid, const char* ctid)
    6447              : {
    6448              :     if ((apid == NULL) || (strnlen(apid, DLT_ID_SIZE) == 0))
    6449              :         return NULL;
    6450              : 
    6451              :     DltTraceLoadSettings* app_level = NULL;
    6452              :     size_t ctid_len = (ctid != NULL) ? strnlen(ctid, DLT_ID_SIZE) : 0;
    6453              : 
    6454              :     for (uint32_t i = 0; i < settings_count; ++i) {
    6455              :         if (strncmp(apid, settings->apid, DLT_ID_SIZE) != 0) {
    6456              :             if (app_level == NULL)
    6457              :                 continue;
    6458              :             // settings are sorted.
    6459              :             // If we found a configuration entry which matches the app id already
    6460              :             // we can exit here because no more entries with the app id will follow anymore.
    6461              :             break;
    6462              :         }
    6463              : 
    6464              :         if (settings[i].ctid[0] == '\0') {
    6465              :             app_level = &settings[i];
    6466              :             if (ctid_len == 0)
    6467              :                 return &settings[i];
    6468              :             continue;
    6469              :         }
    6470              : 
    6471              :         if ((ctid_len > 0) && (strncmp(ctid, settings[i].ctid, DLT_ID_SIZE) == 0)) {
    6472              :             return &settings[i];
    6473              :         }
    6474              :     }
    6475              : 
    6476              :     return app_level;
    6477              : }
    6478              : 
    6479              : #endif
        

Generated by: LCOV version 2.0-1