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

Generated by: LCOV version 2.0-1