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