+
+ 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 2730 : static DltReturnValue dlt_print_hex_string_delim(char *text, int textlength, uint8_t *ptr, int size, char delim)
+ 140 : {
+ 141 : int num;
+ 142 :
+ 143 2730 : 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 2727 : 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 36441 : for (num = 0; num < size; num++) {
+ 155 33714 : if (num > 0) {
+ 156 31013 : snprintf(text, 2, "%c", delim);
+ 157 31013 : text++;
+ 158 : }
+ 159 :
+ 160 33714 : snprintf(text, 3, "%.2x", ((uint8_t *)ptr)[num]);
+ 161 33714 : text += 2; /* 2 chars */
+ 162 : }
+ 163 :
+ 164 : return DLT_RETURN_OK;
+ 165 : }
+ 166 :
+ 167 2721 : DltReturnValue dlt_print_hex_string(char *text, int textlength, uint8_t *ptr, int size)
+ 168 : {
+ 169 2721 : 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 4089 : size_t dlt_strnlen_s(const char* str, size_t maxsize)
+ 321 : {
+ 322 4089 : if (str == NULL)
+ 323 : return 0;
+ 324 :
+ 325 17137 : for (size_t i = 0; i < maxsize; ++i) {
+ 326 16385 : if (str[i] == '\0')
+ 327 3336 : return i;
+ 328 : }
+ 329 : return maxsize;
+ 330 : }
+ 331 :
+ 332 4087 : void dlt_print_id(char *text, const char *id)
+ 333 : {
+ 334 : /* check nullpointer */
+ 335 4087 : if ((text == NULL) || (id == NULL))
+ 336 : return;
+ 337 :
+ 338 : /* Initialize text */
+ 339 : memset(text, '-', DLT_ID_SIZE);
+ 340 :
+ 341 4084 : text[DLT_ID_SIZE] = 0;
+ 342 :
+ 343 4084 : size_t len = dlt_strnlen_s(id, DLT_ID_SIZE);
+ 344 :
+ 345 : memcpy(text, id, len);
+ 346 : }
+ 347 :
+ 348 23443 : void dlt_set_id(char *id, const char *text)
+ 349 : {
+ 350 : /* check nullpointer */
+ 351 23443 : if ((id == NULL) || (text == NULL))
+ 352 : return;
+ 353 :
+ 354 23440 : id[0] = 0;
+ 355 23440 : id[1] = 0;
+ 356 23440 : id[2] = 0;
+ 357 23307 : id[3] = 0;
+ 358 :
+ 359 23440 : if (text[0] != 0)
+ 360 9337 : id[0] = text[0];
+ 361 : else
+ 362 : return;
+ 363 :
+ 364 9337 : if (text[1] != 0)
+ 365 9331 : id[1] = text[1];
+ 366 : else
+ 367 : return;
+ 368 :
+ 369 9331 : if (text[2] != 0)
+ 370 9323 : id[2] = text[2];
+ 371 : else
+ 372 : return;
+ 373 :
+ 374 9323 : if (text[3] != 0)
+ 375 9160 : id[3] = text[3];
+ 376 : else
+ 377 : return;
+ 378 : }
+ 379 :
+ 380 147 : void dlt_clean_string(char *text, int length)
+ 381 : {
+ 382 : int num;
+ 383 :
+ 384 147 : if (text == NULL)
+ 385 : return;
+ 386 :
+ 387 2002 : for (num = 0; num < length; num++)
+ 388 1855 : if ((text[num] == '\r') || (text[num] == '\n'))
+ 389 0 : text[num] = ' ';
+ 390 : }
+ 391 :
+ 392 6 : DltReturnValue dlt_filter_init(DltFilter *filter, int verbose)
+ 393 : {
+ 394 6 : PRINT_FUNCTION_VERBOSE(verbose);
+ 395 :
+ 396 6 : if (filter == NULL)
+ 397 : return DLT_RETURN_WRONG_PARAMETER;
+ 398 :
+ 399 6 : filter->counter = 0;
+ 400 :
+ 401 6 : return DLT_RETURN_OK;
+ 402 : }
+ 403 :
+ 404 0 : DltReturnValue dlt_filter_free(DltFilter *filter, int verbose)
+ 405 : {
+ 406 0 : PRINT_FUNCTION_VERBOSE(verbose);
+ 407 :
+ 408 0 : 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 252 : DltReturnValue dlt_message_init(DltMessage *msg, int verbose)
+ 642 : {
+ 643 252 : PRINT_FUNCTION_VERBOSE(verbose);
+ 644 :
+ 645 252 : if (msg == NULL)
+ 646 : return DLT_RETURN_WRONG_PARAMETER;
+ 647 :
+ 648 : /* initalise structure parameters */
+ 649 250 : msg->headersize = 0;
+ 650 250 : msg->datasize = 0;
+ 651 :
+ 652 250 : msg->databuffer = NULL;
+ 653 250 : msg->databuffersize = 0;
+ 654 :
+ 655 250 : msg->storageheader = NULL;
+ 656 250 : msg->standardheader = NULL;
+ 657 250 : msg->extendedheader = NULL;
+ 658 :
+ 659 250 : msg->found_serialheader = 0;
+ 660 :
+ 661 250 : return DLT_RETURN_OK;
+ 662 : }
+ 663 :
+ 664 64 : DltReturnValue dlt_message_free(DltMessage *msg, int verbose)
+ 665 : {
+ 666 64 : PRINT_FUNCTION_VERBOSE(verbose);
+ 667 :
+ 668 64 : if (msg == NULL)
+ 669 : return DLT_RETURN_WRONG_PARAMETER;
+ 670 :
+ 671 : /* delete databuffer if exists */
+ 672 62 : if (msg->databuffer) {
+ 673 48 : free(msg->databuffer);
+ 674 48 : msg->databuffer = NULL;
+ 675 48 : msg->databuffersize = 0;
+ 676 : }
+ 677 :
+ 678 : return DLT_RETURN_OK;
+ 679 : }
+ 680 :
+ 681 1909 : DltReturnValue dlt_message_header(DltMessage *msg, char *text, size_t textlength, int verbose)
+ 682 : {
+ 683 1909 : return dlt_message_header_flags(msg, text, textlength, DLT_HEADER_SHOW_ALL, verbose);
+ 684 : }
+ 685 :
+ 686 4611 : 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 4611 : PRINT_FUNCTION_VERBOSE(verbose);
+ 692 :
+ 693 4611 : if ((msg == NULL) || (text == NULL) || (textlength <= 0))
+ 694 : return DLT_RETURN_WRONG_PARAMETER;
+ 695 :
+ 696 4415 : if ((DLT_IS_HTYP_UEH(msg->standardheader->htyp)) && (msg->extendedheader == NULL))
+ 697 : return DLT_RETURN_WRONG_PARAMETER;
+ 698 :
+ 699 4415 : if ((flags < DLT_HEADER_SHOW_NONE) || (flags > DLT_HEADER_SHOW_ALL))
+ 700 : return DLT_RETURN_WRONG_PARAMETER;
+ 701 :
+ 702 4415 : text[0] = 0;
+ 703 :
+ 704 4415 : if ((flags & DLT_HEADER_SHOW_TIME) == DLT_HEADER_SHOW_TIME) {
+ 705 : /* print received time */
+ 706 2315 : time_t tt = msg->storageheader->seconds;
+ 707 2315 : tzset();
+ 708 2315 : localtime_r(&tt, &timeinfo);
+ 709 2315 : strftime (buffer, sizeof(buffer), "%Y/%m/%d %H:%M:%S", &timeinfo);
+ 710 2315 : snprintf(text, textlength, "%s.%.6d ", buffer, msg->storageheader->microseconds);
+ 711 : }
+ 712 :
+ 713 4415 : if ((flags & DLT_HEADER_SHOW_TMSTP) == DLT_HEADER_SHOW_TMSTP) {
+ 714 : /* print timestamp if available */
+ 715 2315 : if (DLT_IS_HTYP_WTMS(msg->standardheader->htyp))
+ 716 136 : 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 4415 : if ((flags & DLT_HEADER_SHOW_MSGCNT) == DLT_HEADER_SHOW_MSGCNT)
+ 722 : /* print message counter */
+ 723 2315 : snprintf(text + strlen(text), textlength - strlen(text), "%.3d ", msg->standardheader->mcnt);
+ 724 :
+ 725 4415 : if ((flags & DLT_HEADER_SHOW_ECUID) == DLT_HEADER_SHOW_ECUID) {
+ 726 : /* print ecu id, use header extra if available, else storage header value */
+ 727 2315 : if (DLT_IS_HTYP_WEID(msg->standardheader->htyp))
+ 728 136 : 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 4415 : if ((flags & DLT_HEADER_SHOW_APID) == DLT_HEADER_SHOW_APID) {
+ 736 2315 : snprintf(text + strlen(text), textlength - strlen(text), " ");
+ 737 :
+ 738 2315 : if ((DLT_IS_HTYP_UEH(msg->standardheader->htyp)) && (msg->extendedheader->apid[0] != 0))
+ 739 884 : dlt_print_id(text + strlen(text), msg->extendedheader->apid);
+ 740 : else
+ 741 1431 : snprintf(text + strlen(text), textlength - strlen(text), "----");
+ 742 :
+ 743 2315 : snprintf(text + strlen(text), textlength - strlen(text), " ");
+ 744 : }
+ 745 :
+ 746 4415 : if ((flags & DLT_HEADER_SHOW_CTID) == DLT_HEADER_SHOW_CTID) {
+ 747 2315 : if ((DLT_IS_HTYP_UEH(msg->standardheader->htyp)) && (msg->extendedheader->ctid[0] != 0))
+ 748 884 : dlt_print_id(text + strlen(text), msg->extendedheader->ctid);
+ 749 : else
+ 750 1431 : snprintf(text + strlen(text), textlength - strlen(text), "----");
+ 751 :
+ 752 2315 : snprintf(text + strlen(text), textlength - strlen(text), " ");
+ 753 : }
+ 754 :
+ 755 : /* print info about message type and length */
+ 756 4415 : if (DLT_IS_HTYP_UEH(msg->standardheader->htyp)) {
+ 757 1924 : if ((flags & DLT_HEADER_SHOW_MSGTYPE) == DLT_HEADER_SHOW_MSGTYPE) {
+ 758 884 : snprintf(text + strlen(text), textlength - strlen(text), "%s",
+ 759 884 : message_type[DLT_GET_MSIN_MSTP(msg->extendedheader->msin)]);
+ 760 884 : snprintf(text + strlen(text), textlength - strlen(text), " ");
+ 761 : }
+ 762 :
+ 763 1924 : if ((flags & DLT_HEADER_SHOW_MSGSUBTYPE) == DLT_HEADER_SHOW_MSGSUBTYPE) {
+ 764 884 : if ((DLT_GET_MSIN_MSTP(msg->extendedheader->msin)) == DLT_TYPE_LOG)
+ 765 748 : snprintf(text + strlen(text), textlength - strlen(text), "%s",
+ 766 748 : log_info[DLT_GET_MSIN_MTIN(msg->extendedheader->msin)]);
+ 767 :
+ 768 884 : 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 884 : 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 884 : if ((DLT_GET_MSIN_MSTP(msg->extendedheader->msin)) == DLT_TYPE_CONTROL)
+ 777 136 : snprintf(text + strlen(text), textlength - strlen(text), "%s",
+ 778 136 : control_type[DLT_GET_MSIN_MTIN(msg->extendedheader->msin)]);
+ 779 :
+ 780 884 : snprintf(text + strlen(text), textlength - strlen(text), " ");
+ 781 : }
+ 782 :
+ 783 1924 : if ((flags & DLT_HEADER_SHOW_VNVSTATUS) == DLT_HEADER_SHOW_VNVSTATUS) {
+ 784 : /* print verbose status pf message */
+ 785 884 : if (DLT_IS_MSIN_VERB(msg->extendedheader->msin))
+ 786 748 : snprintf(text + strlen(text), textlength - strlen(text), "V");
+ 787 : else
+ 788 136 : snprintf(text + strlen(text), textlength - strlen(text), "N");
+ 789 :
+ 790 884 : snprintf(text + strlen(text), textlength - strlen(text), " ");
+ 791 : }
+ 792 :
+ 793 1924 : if ((flags & DLT_HEADER_SHOW_NOARG) == DLT_HEADER_SHOW_NOARG)
+ 794 : /* print number of arguments */
+ 795 884 : 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 2620 : 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 2620 : PRINT_FUNCTION_VERBOSE(verbose);
+ 833 :
+ 834 2620 : if ((msg == NULL) || (msg->databuffer == NULL) || (text == NULL) ||
+ 835 2561 : (type < DLT_OUTPUT_HEX) || (type > DLT_OUTPUT_ASCII_LIMITED))
+ 836 : return DLT_RETURN_WRONG_PARAMETER;
+ 837 :
+ 838 2430 : 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 2420 : text[0] = 0;
+ 845 :
+ 846 : /* print payload only as hex */
+ 847 2420 : 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 1894 : 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 1368 : 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 842 : ptr = msg->databuffer;
+ 858 842 : 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 842 : if (DLT_MSG_IS_NONVERBOSE(msg)) {
+ 868 :
+ 869 534 : DLT_MSG_READ_VALUE(id_tmp, ptr, datalength, uint32_t);
+ 870 534 : id = DLT_ENDIAN_GET_32(msg->standardheader->htyp, id_tmp);
+ 871 :
+ 872 534 : 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 534 : if (DLT_MSG_IS_CONTROL(msg)) {
+ 881 57 : 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 0 : else if (!(DLT_MSG_IS_CONTROL_TIME(msg)))
+ 885 0 : snprintf(text + strlen(text), textlength - strlen(text), "service(%u)", id); /* service id */
+ 886 :
+ 887 57 : if (datalength > 0)
+ 888 57 : 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 534 : if (DLT_MSG_IS_CONTROL_RESPONSE(msg)) {
+ 896 1 : if (datalength > 0) {
+ 897 1 : DLT_MSG_READ_VALUE(retval, ptr, datalength, uint8_t); /* No endian conversion necessary */
+ 898 :
+ 899 1 : if ((retval < DLT_SERVICE_RESPONSE_LAST) || (retval == 8))
+ 900 0 : 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 1 : if (datalength >= 1)
+ 905 1 : snprintf(text + strlen(text), textlength - strlen(text), ", ");
+ 906 : }
+ 907 : }
+ 908 :
+ 909 534 : 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 412 : ret = dlt_print_hex_string(text + strlen(text), (int)(textlength - strlen(text)), ptr, datalength);
+ 923 : }
+ 924 :
+ 925 534 : 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 833 : for (num = 0; num < (int)(msg->extendedheader->noar); num++) {
+ 935 525 : if (num != 0) {
+ 936 231 : text_offset = (int)strlen(text);
+ 937 231 : snprintf(text + text_offset, textlength - (size_t)text_offset, " ");
+ 938 : }
+ 939 :
+ 940 : /* first read the type info of the argument */
+ 941 525 : DLT_MSG_READ_VALUE(type_info_tmp, ptr, datalength, uint32_t);
+ 942 525 : type_info = DLT_ENDIAN_GET_32(msg->standardheader->htyp, type_info_tmp);
+ 943 :
+ 944 : /* print out argument */
+ 945 525 : text_offset = (int)strlen(text);
+ 946 :
+ 947 525 : if (dlt_message_argument_print(msg, type_info, pptr, pdatalength,
+ 948 525 : (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 246 : 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 246 : PRINT_FUNCTION_VERBOSE(verbose);
+ 992 :
+ 993 246 : if ((msg == NULL) || (buffer == NULL) || (length <= 0))
+ 994 : return DLT_MESSAGE_ERROR_UNKNOWN;
+ 995 :
+ 996 : /* initialize resync_offset */
+ 997 26 : msg->resync_offset = 0;
+ 998 :
+ 999 : /* check if message contains serial header, smaller than standard header */
+ 1000 26 : if (length < sizeof(dltSerialHeader))
+ 1001 : /* dlt_log(LOG_ERR, "Length smaller than serial header!\n"); */
+ 1002 : return DLT_MESSAGE_ERROR_SIZE;
+ 1003 :
+ 1004 26 : 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 26 : msg->found_serialheader = 0;
+ 1013 :
+ 1014 26 : 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 26 : if (length < sizeof(DltStandardHeader))
+ 1041 : /* dlt_log(LOG_ERR, "Length smaller than standard header!\n"); */
+ 1042 : return DLT_MESSAGE_ERROR_SIZE;
+ 1043 :
+ 1044 26 : memcpy(msg->headerbuffer + sizeof(DltStorageHeader), buffer, sizeof(DltStandardHeader));
+ 1045 :
+ 1046 : /* set ptrs to structures */
+ 1047 26 : msg->storageheader = (DltStorageHeader *)msg->headerbuffer;
+ 1048 26 : msg->standardheader = (DltStandardHeader *)(msg->headerbuffer + sizeof(DltStorageHeader));
+ 1049 :
+ 1050 : /* calculate complete size of headers */
+ 1051 26 : extra_size = (uint32_t) (DLT_STANDARD_HEADER_EXTRA_SIZE(msg->standardheader->htyp) +
+ 1052 : (DLT_IS_HTYP_UEH(msg->standardheader->htyp) ? sizeof(DltExtendedHeader) : 0));
+ 1053 26 : msg->headersize = (uint32_t) (sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + extra_size);
+ 1054 26 : 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 26 : temp_datasize = DLT_BETOH_16(msg->standardheader->len) - (int32_t) msg->headersize + (int32_t) sizeof(DltStorageHeader);
+ 1059 :
+ 1060 : /* check data size */
+ 1061 26 : 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 26 : msg->datasize = (uint32_t) temp_datasize;
+ 1069 : }
+ 1070 :
+ 1071 : /* check if verbose mode is on*/
+ 1072 26 : 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 26 : if (extra_size > 0) {
+ 1079 26 : if (length < (msg->headersize - sizeof(DltStorageHeader)))
+ 1080 : return DLT_MESSAGE_ERROR_SIZE;
+ 1081 :
+ 1082 26 : memcpy(msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader),
+ 1083 26 : buffer + sizeof(DltStandardHeader), (size_t)extra_size);
+ 1084 :
+ 1085 : /* set extended header ptr and get standard header extra parameters */
+ 1086 26 : if (DLT_IS_HTYP_UEH(msg->standardheader->htyp))
+ 1087 26 : msg->extendedheader =
+ 1088 26 : (DltExtendedHeader *)(msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) +
+ 1089 26 : DLT_STANDARD_HEADER_EXTRA_SIZE(msg->standardheader->htyp));
+ 1090 : else
+ 1091 0 : msg->extendedheader = NULL;
+ 1092 :
+ 1093 26 : dlt_message_get_extraparameters(msg, verbose);
+ 1094 : }
+ 1095 :
+ 1096 : /* check if payload fits length */
+ 1097 26 : 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 21 : if (msg->databuffer) {
+ 1103 17 : if (msg->datasize > msg->databuffersize) {
+ 1104 2 : free(msg->databuffer);
+ 1105 2 : msg->databuffer = (uint8_t *)malloc(msg->datasize);
+ 1106 2 : msg->databuffersize = msg->datasize;
+ 1107 : }
+ 1108 : }
+ 1109 : else {
+ 1110 : /* get new memory for buffer */
+ 1111 4 : msg->databuffer = (uint8_t *)malloc(msg->datasize);
+ 1112 4 : msg->databuffersize = msg->datasize;
+ 1113 : }
+ 1114 :
+ 1115 21 : 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 21 : memcpy(msg->databuffer, buffer + (msg->headersize - sizeof(DltStorageHeader)), msg->datasize);
+ 1124 :
+ 1125 21 : return DLT_MESSAGE_ERROR_OK;
+ 1126 : }
+ 1127 :
+ 1128 494 : DltReturnValue dlt_message_get_extraparameters(DltMessage *msg, int verbose)
+ 1129 : {
+ 1130 494 : PRINT_FUNCTION_VERBOSE(verbose);
+ 1131 :
+ 1132 494 : if (msg == NULL)
+ 1133 : return DLT_RETURN_WRONG_PARAMETER;
+ 1134 :
+ 1135 492 : if (DLT_IS_HTYP_WEID(msg->standardheader->htyp))
+ 1136 298 : memcpy(msg->headerextra.ecu,
+ 1137 : msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader),
+ 1138 : DLT_ID_SIZE);
+ 1139 :
+ 1140 492 : if (DLT_IS_HTYP_WSID(msg->standardheader->htyp)) {
+ 1141 7 : memcpy(&(msg->headerextra.seid), msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader)
+ 1142 7 : + (DLT_IS_HTYP_WEID(msg->standardheader->htyp) ? DLT_SIZE_WEID : 0), DLT_SIZE_WSID);
+ 1143 7 : msg->headerextra.seid = DLT_BETOH_32(msg->headerextra.seid);
+ 1144 : }
+ 1145 :
+ 1146 492 : if (DLT_IS_HTYP_WTMS(msg->standardheader->htyp)) {
+ 1147 596 : memcpy(&(msg->headerextra.tmsp), msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader)
+ 1148 298 : + (DLT_IS_HTYP_WEID(msg->standardheader->htyp) ? DLT_SIZE_WEID : 0)
+ 1149 298 : + (DLT_IS_HTYP_WSID(msg->standardheader->htyp) ? DLT_SIZE_WSID : 0), DLT_SIZE_WTMS);
+ 1150 298 : msg->headerextra.tmsp = DLT_BETOH_32(msg->headerextra.tmsp);
+ 1151 : }
+ 1152 :
+ 1153 : return DLT_RETURN_OK;
+ 1154 : }
+ 1155 :
+ 1156 425 : DltReturnValue dlt_message_set_extraparameters(DltMessage *msg, int verbose)
+ 1157 : {
+ 1158 425 : PRINT_FUNCTION_VERBOSE(verbose);
+ 1159 :
+ 1160 425 : if (msg == NULL)
+ 1161 : return DLT_RETURN_WRONG_PARAMETER;
+ 1162 :
+ 1163 423 : if (DLT_IS_HTYP_WEID(msg->standardheader->htyp))
+ 1164 227 : memcpy(msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader),
+ 1165 227 : msg->headerextra.ecu,
+ 1166 : DLT_ID_SIZE);
+ 1167 :
+ 1168 423 : if (DLT_IS_HTYP_WSID(msg->standardheader->htyp)) {
+ 1169 186 : msg->headerextra.seid = DLT_HTOBE_32(msg->headerextra.seid);
+ 1170 186 : memcpy(msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader)
+ 1171 186 : + (DLT_IS_HTYP_WEID(msg->standardheader->htyp) ? DLT_SIZE_WEID : 0),
+ 1172 186 : &(msg->headerextra.seid),
+ 1173 : DLT_SIZE_WSID);
+ 1174 : }
+ 1175 :
+ 1176 423 : if (DLT_IS_HTYP_WTMS(msg->standardheader->htyp)) {
+ 1177 227 : msg->headerextra.tmsp = DLT_HTOBE_32(msg->headerextra.tmsp);
+ 1178 454 : memcpy(msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader)
+ 1179 227 : + (DLT_IS_HTYP_WEID(msg->standardheader->htyp) ? DLT_SIZE_WEID : 0)
+ 1180 227 : + (DLT_IS_HTYP_WSID(msg->standardheader->htyp) ? DLT_SIZE_WSID : 0),
+ 1181 227 : &(msg->headerextra.tmsp),
+ 1182 : DLT_SIZE_WTMS);
+ 1183 : }
+ 1184 :
+ 1185 : return DLT_RETURN_OK;
+ 1186 : }
+ 1187 :
+ 1188 28 : DltReturnValue dlt_file_init(DltFile *file, int verbose)
+ 1189 : {
+ 1190 28 : PRINT_FUNCTION_VERBOSE(verbose);
+ 1191 :
+ 1192 28 : if (file == NULL)
+ 1193 : return DLT_RETURN_WRONG_PARAMETER;
+ 1194 :
+ 1195 : /* initalise structure parameters */
+ 1196 28 : file->handle = NULL;
+ 1197 28 : file->counter = 0;
+ 1198 28 : file->counter_total = 0;
+ 1199 28 : file->index = NULL;
+ 1200 :
+ 1201 28 : file->filter = NULL;
+ 1202 28 : file->filter_counter = 0;
+ 1203 28 : file->file_position = 0;
+ 1204 :
+ 1205 28 : file->position = 0;
+ 1206 :
+ 1207 28 : file->error_messages = 0;
+ 1208 :
+ 1209 28 : 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 5592 : DltReturnValue dlt_file_read_header(DltFile *file, int verbose)
+ 1226 : {
+ 1227 5592 : PRINT_FUNCTION_VERBOSE(verbose);
+ 1228 :
+ 1229 5592 : 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 11184 : if (fread(file->msg.headerbuffer,
+ 1236 : sizeof(DltStorageHeader) + sizeof(DltStandardHeader), 1,
+ 1237 : file->handle) != 1) {
+ 1238 21 : if (!feof(file->handle))
+ 1239 0 : dlt_log(LOG_WARNING, "Cannot read header from file!\n");
+ 1240 : else
+ 1241 21 : dlt_log(LOG_DEBUG, "Reached end of file\n");
+ 1242 :
+ 1243 21 : return DLT_RETURN_ERROR;
+ 1244 : }
+ 1245 :
+ 1246 : /* set ptrs to structures */
+ 1247 5571 : file->msg.storageheader = (DltStorageHeader *)file->msg.headerbuffer;
+ 1248 5571 : file->msg.standardheader = (DltStandardHeader *)(file->msg.headerbuffer +
+ 1249 : sizeof(DltStorageHeader));
+ 1250 :
+ 1251 : /* check id of storage header */
+ 1252 5571 : 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 5571 : file->msg.headersize = (uint32_t) (sizeof(DltStorageHeader) + sizeof(DltStandardHeader) +
+ 1269 5571 : 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 5571 : temp_datasize = DLT_BETOH_16(file->msg.standardheader->len) + (int32_t) sizeof(DltStorageHeader) - (int32_t) file->msg.headersize;
+ 1275 :
+ 1276 : /* check data size */
+ 1277 5571 : 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 5571 : file->msg.datasize = (uint32_t) temp_datasize;
+ 1284 : }
+ 1285 :
+ 1286 : /* check if verbose mode is on */
+ 1287 5571 : 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 3996 : DltReturnValue dlt_file_read_header_extended(DltFile *file, int verbose)
+ 1395 : {
+ 1396 3996 : PRINT_FUNCTION_VERBOSE(verbose);
+ 1397 :
+ 1398 3996 : if (file == NULL)
+ 1399 : return DLT_RETURN_WRONG_PARAMETER;
+ 1400 :
+ 1401 : /* load standard header extra parameters if used */
+ 1402 3996 : if (DLT_STANDARD_HEADER_EXTRA_SIZE(file->msg.standardheader->htyp)) {
+ 1403 512 : 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 256 : dlt_message_get_extraparameters(&(file->msg), verbose);
+ 1411 : }
+ 1412 :
+ 1413 : /* load Extended header if used */
+ 1414 3996 : if (DLT_IS_HTYP_UEH(file->msg.standardheader->htyp) == 0)
+ 1415 : /* there is nothing to be loaded */
+ 1416 : return DLT_RETURN_OK;
+ 1417 :
+ 1418 1664 : if (fread(file->msg.headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) +
+ 1419 1664 : 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 1664 : if (DLT_IS_HTYP_UEH(file->msg.standardheader->htyp))
+ 1428 1664 : file->msg.extendedheader =
+ 1429 1664 : (DltExtendedHeader *)(file->msg.headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) +
+ 1430 1664 : 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 3366 : DltReturnValue dlt_file_read_data(DltFile *file, int verbose)
+ 1438 : {
+ 1439 3366 : PRINT_FUNCTION_VERBOSE(verbose);
+ 1440 :
+ 1441 3366 : if (file == NULL)
+ 1442 : return DLT_RETURN_WRONG_PARAMETER;
+ 1443 :
+ 1444 : /* free last used memory for buffer */
+ 1445 3366 : if (file->msg.databuffer && (file->msg.databuffersize < file->msg.datasize)) {
+ 1446 126 : free(file->msg.databuffer);
+ 1447 126 : file->msg.databuffer = NULL;
+ 1448 : }
+ 1449 :
+ 1450 3366 : if (file->msg.databuffer == NULL) {
+ 1451 : /* get new memory for buffer */
+ 1452 148 : file->msg.databuffer = (uint8_t *)malloc(file->msg.datasize);
+ 1453 148 : file->msg.databuffersize = file->msg.datasize;
+ 1454 : }
+ 1455 :
+ 1456 3366 : 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 6732 : 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 32 : DltReturnValue dlt_file_open(DltFile *file, const char *filename, int verbose)
+ 1477 : {
+ 1478 32 : PRINT_FUNCTION_VERBOSE(verbose);
+ 1479 :
+ 1480 32 : if ((file == NULL) || (filename == NULL))
+ 1481 : return DLT_RETURN_WRONG_PARAMETER;
+ 1482 :
+ 1483 : /* reset counters */
+ 1484 26 : file->counter = 0;
+ 1485 26 : file->counter_total = 0;
+ 1486 26 : file->position = 0;
+ 1487 26 : file->file_position = 0;
+ 1488 26 : file->file_length = 0;
+ 1489 26 : file->error_messages = 0;
+ 1490 :
+ 1491 26 : if (file->handle)
+ 1492 0 : fclose(file->handle);
+ 1493 :
+ 1494 : /* open dlt file */
+ 1495 26 : file->handle = fopen(filename, "rb");
+ 1496 :
+ 1497 26 : 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 26 : 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 26 : file->file_length = ftell(file->handle);
+ 1508 :
+ 1509 26 : 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 26 : 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 2226 : DltReturnValue dlt_file_read(DltFile *file, int verbose)
+ 1522 : {
+ 1523 : long *ptr;
+ 1524 : int found = DLT_RETURN_OK;
+ 1525 :
+ 1526 2226 : if (file == NULL)
+ 1527 : return DLT_RETURN_WRONG_PARAMETER;
+ 1528 :
+ 1529 2226 : 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 2226 : if (file->counter % DLT_COMMON_INDEX_ALLOC == 0) {
+ 1534 333 : ptr = (long *)malloc(((file->counter / DLT_COMMON_INDEX_ALLOC) + 1) * DLT_COMMON_INDEX_ALLOC * sizeof(long));
+ 1535 :
+ 1536 333 : if (ptr == NULL)
+ 1537 : return DLT_RETURN_ERROR;
+ 1538 :
+ 1539 333 : if (file->index) {
+ 1540 312 : memcpy(ptr, file->index, (size_t)(file->counter) * sizeof(long));
+ 1541 312 : free(file->index);
+ 1542 : }
+ 1543 :
+ 1544 333 : 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 2226 : 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 2226 : if (verbose)
+ 1556 0 : dlt_vlog(LOG_INFO, "Position in file: %" PRIu64 "\n", file->file_position);
+ 1557 :
+ 1558 : /* read header */
+ 1559 2226 : if (dlt_file_read_header(file, verbose) < DLT_RETURN_OK) {
+ 1560 : /* go back to last position in file */
+ 1561 21 : fseek(file->handle, file->file_position, SEEK_SET);
+ 1562 21 : return DLT_RETURN_ERROR;
+ 1563 : }
+ 1564 :
+ 1565 2205 : if (file->filter) {
+ 1566 : /* read the extended header if filter is enabled and extended header exists */
+ 1567 630 : if (dlt_file_read_header_extended(file, verbose) < DLT_RETURN_OK) {
+ 1568 : /* go back to last position in file */
+ 1569 0 : if (0 != fseek(file->handle, file->file_position, SEEK_SET))
+ 1570 0 : dlt_vlog(LOG_WARNING, "Seek to last file pos failed!\n");
+ 1571 :
+ 1572 0 : return DLT_RETURN_ERROR;
+ 1573 : }
+ 1574 :
+ 1575 : /* check the filters if message is used */
+ 1576 630 : if (dlt_message_filter_check(&(file->msg), file->filter, verbose) == DLT_RETURN_TRUE) {
+ 1577 : /* filter matched, consequently store current message */
+ 1578 : /* store index pointer to message position in DLT file */
+ 1579 318 : file->index[file->counter] = file->file_position;
+ 1580 318 : file->counter++;
+ 1581 318 : file->position = file->counter - 1;
+ 1582 :
+ 1583 : found = DLT_RETURN_TRUE;
+ 1584 : }
+ 1585 :
+ 1586 : /* skip payload data */
+ 1587 630 : if (fseek(file->handle, file->msg.datasize, SEEK_CUR) != 0) {
+ 1588 : /* go back to last position in file */
+ 1589 0 : dlt_vlog(LOG_WARNING,
+ 1590 : "Seek failed to skip payload data of size %u!\n",
+ 1591 : file->msg.datasize);
+ 1592 :
+ 1593 0 : if (0 != fseek(file->handle, file->file_position, SEEK_SET))
+ 1594 0 : dlt_log(LOG_WARNING, "Seek back also failed!\n");
+ 1595 :
+ 1596 0 : return DLT_RETURN_ERROR;
+ 1597 : }
+ 1598 : }
+ 1599 : else {
+ 1600 : /* filter is disabled */
+ 1601 : /* skip additional header parameters and payload data */
+ 1602 1575 : if (fseek(file->handle,
+ 1603 1575 : (long) (file->msg.headersize - sizeof(DltStorageHeader) - sizeof(DltStandardHeader) + file->msg.datasize),
+ 1604 : SEEK_CUR)) {
+ 1605 :
+ 1606 0 : dlt_vlog(LOG_WARNING,
+ 1607 : "Seek failed to skip extra header and payload data from file of size %u!\n",
+ 1608 0 : file->msg.headersize - (int32_t)sizeof(DltStorageHeader) -
+ 1609 0 : (int32_t)sizeof(DltStandardHeader) + file->msg.datasize);
+ 1610 :
+ 1611 : /* go back to last position in file */
+ 1612 0 : if (fseek(file->handle, file->file_position, SEEK_SET))
+ 1613 0 : dlt_log(LOG_WARNING, "Seek back also failed!\n");
+ 1614 :
+ 1615 0 : return DLT_RETURN_ERROR;
+ 1616 : }
+ 1617 :
+ 1618 : /* store index pointer to message position in DLT file */
+ 1619 1575 : file->index[file->counter] = file->file_position;
+ 1620 1575 : file->counter++;
+ 1621 1575 : file->position = file->counter - 1;
+ 1622 :
+ 1623 : found = DLT_RETURN_TRUE;
+ 1624 : }
+ 1625 :
+ 1626 : /* increase total message counter */
+ 1627 2205 : file->counter_total++;
+ 1628 :
+ 1629 : /* store position to next message */
+ 1630 2205 : file->file_position = ftell(file->handle);
+ 1631 :
+ 1632 2205 : return found;
+ 1633 : }
+ 1634 :
+ 1635 0 : DltReturnValue dlt_file_read_raw(DltFile *file, int resync, int verbose)
+ 1636 : {
+ 1637 : int found = DLT_RETURN_OK;
+ 1638 : long *ptr;
+ 1639 :
+ 1640 0 : if (verbose)
+ 1641 0 : dlt_vlog(LOG_DEBUG, "%s: Message %d:\n", __func__, file->counter_total);
+ 1642 :
+ 1643 0 : if (file == NULL)
+ 1644 : return DLT_RETURN_WRONG_PARAMETER;
+ 1645 :
+ 1646 : /* allocate new memory for index if number of messages exceeds a multiple of DLT_COMMON_INDEX_ALLOC (e.g.: 1000) */
+ 1647 0 : if (file->counter % DLT_COMMON_INDEX_ALLOC == 0) {
+ 1648 0 : ptr = (long *)malloc(((file->counter / DLT_COMMON_INDEX_ALLOC) + 1) * DLT_COMMON_INDEX_ALLOC * sizeof(long));
+ 1649 :
+ 1650 0 : if (ptr == NULL)
+ 1651 : return DLT_RETURN_ERROR;
+ 1652 :
+ 1653 0 : if (file->index) {
+ 1654 0 : memcpy(ptr, file->index, (size_t)(file->counter) * sizeof(long));
+ 1655 0 : free(file->index);
+ 1656 : }
+ 1657 :
+ 1658 0 : file->index = ptr;
+ 1659 : }
+ 1660 :
+ 1661 : /* set to end of last successful read message, because of conflicting calls to dlt_file_read and dlt_file_message */
+ 1662 0 : if (0 != fseek(file->handle, file->file_position, SEEK_SET))
+ 1663 : return DLT_RETURN_ERROR;
+ 1664 :
+ 1665 : /* get file position at start of DLT message */
+ 1666 0 : if (verbose)
+ 1667 0 : dlt_vlog(LOG_DEBUG, "Position in file: %" PRIu64 "\n", file->file_position);
+ 1668 :
+ 1669 : /* read header */
+ 1670 0 : if (dlt_file_read_header_raw(file, resync, verbose) < DLT_RETURN_OK) {
+ 1671 : /* go back to last position in file */
+ 1672 0 : if (0 != fseek(file->handle, file->file_position, SEEK_SET))
+ 1673 0 : dlt_log(LOG_WARNING, "dlt_file_read_raw, fseek failed 1\n");
+ 1674 :
+ 1675 0 : return DLT_RETURN_ERROR;
+ 1676 : }
+ 1677 :
+ 1678 : /* read the extended header if filter is enabled and extended header exists */
+ 1679 0 : if (dlt_file_read_header_extended(file, verbose) < DLT_RETURN_OK) {
+ 1680 : /* go back to last position in file */
+ 1681 0 : if (0 != fseek(file->handle, file->file_position, SEEK_SET))
+ 1682 0 : dlt_log(LOG_WARNING, "dlt_file_read_raw, fseek failed 2\n");
+ 1683 :
+ 1684 0 : return DLT_RETURN_ERROR;
+ 1685 : }
+ 1686 :
+ 1687 0 : if (dlt_file_read_data(file, verbose) < DLT_RETURN_OK) {
+ 1688 : /* go back to last position in file */
+ 1689 0 : if (0 != fseek(file->handle, file->file_position, SEEK_SET))
+ 1690 0 : dlt_log(LOG_WARNING, "dlt_file_read_raw, fseek failed 3\n");
+ 1691 :
+ 1692 0 : return DLT_RETURN_ERROR;
+ 1693 : }
+ 1694 :
+ 1695 : /* store index pointer to message position in DLT file */
+ 1696 0 : file->index[file->counter] = file->file_position;
+ 1697 0 : file->counter++;
+ 1698 0 : file->position = file->counter - 1;
+ 1699 :
+ 1700 : found = DLT_RETURN_TRUE;
+ 1701 :
+ 1702 : /* increase total message counter */
+ 1703 0 : file->counter_total++;
+ 1704 :
+ 1705 : /* store position to next message */
+ 1706 0 : file->file_position = ftell(file->handle);
+ 1707 :
+ 1708 0 : return found;
+ 1709 : }
+ 1710 :
+ 1711 0 : DltReturnValue dlt_file_close(DltFile *file, int verbose)
+ 1712 : {
+ 1713 0 : PRINT_FUNCTION_VERBOSE(verbose);
+ 1714 :
+ 1715 0 : if (file == NULL)
+ 1716 : return DLT_RETURN_WRONG_PARAMETER;
+ 1717 :
+ 1718 0 : if (file->handle)
+ 1719 0 : fclose(file->handle);
+ 1720 :
+ 1721 0 : file->handle = NULL;
+ 1722 :
+ 1723 0 : return DLT_RETURN_OK;
+ 1724 : }
+ 1725 :
+ 1726 3261 : DltReturnValue dlt_file_message(DltFile *file, int index, int verbose)
+ 1727 : {
+ 1728 3261 : PRINT_FUNCTION_VERBOSE(verbose);
+ 1729 :
+ 1730 3261 : if (file == NULL)
+ 1731 : return DLT_RETURN_WRONG_PARAMETER;
+ 1732 :
+ 1733 : /* check if message is in range */
+ 1734 3261 : if (index < 0 || index >= file->counter) {
+ 1735 0 : dlt_vlog(LOG_WARNING, "Message %d out of range!\r\n", index);
+ 1736 0 : return DLT_RETURN_WRONG_PARAMETER;
+ 1737 : }
+ 1738 :
+ 1739 : /* seek to position in file */
+ 1740 3261 : if (fseek(file->handle, file->index[index], SEEK_SET) != 0) {
+ 1741 0 : dlt_vlog(LOG_WARNING, "Seek to message %d to position %ld failed!\r\n",
+ 1742 0 : index, file->index[index]);
+ 1743 0 : return DLT_RETURN_ERROR;
+ 1744 : }
+ 1745 :
+ 1746 : /* read all header and payload */
+ 1747 3261 : if (dlt_file_read_header(file, verbose) < DLT_RETURN_OK)
+ 1748 : return DLT_RETURN_ERROR;
+ 1749 :
+ 1750 3261 : if (dlt_file_read_header_extended(file, verbose) < DLT_RETURN_OK)
+ 1751 : return DLT_RETURN_ERROR;
+ 1752 :
+ 1753 3261 : if (dlt_file_read_data(file, verbose) < DLT_RETURN_OK)
+ 1754 : return DLT_RETURN_ERROR;
+ 1755 :
+ 1756 : /* set current position in file */
+ 1757 3261 : file->position = index;
+ 1758 :
+ 1759 3261 : return DLT_RETURN_OK;
+ 1760 : }
+ 1761 :
+ 1762 26 : DltReturnValue dlt_file_free(DltFile *file, int verbose)
+ 1763 : {
+ 1764 26 : PRINT_FUNCTION_VERBOSE(verbose);
+ 1765 :
+ 1766 26 : if (file == NULL)
+ 1767 : return DLT_RETURN_WRONG_PARAMETER;
+ 1768 :
+ 1769 : /* delete index lost if exists */
+ 1770 26 : if (file->index)
+ 1771 19 : free(file->index);
+ 1772 :
+ 1773 26 : file->index = NULL;
+ 1774 :
+ 1775 : /* close file */
+ 1776 26 : if (file->handle)
+ 1777 24 : fclose(file->handle);
+ 1778 :
+ 1779 26 : file->handle = NULL;
+ 1780 :
+ 1781 26 : return dlt_message_free(&(file->msg), verbose);
+ 1782 : }
+ 1783 :
+ 1784 12 : void dlt_log_set_level(int level)
+ 1785 : {
+ 1786 12 : if ((level < 0) || (level > LOG_DEBUG)) {
+ 1787 0 : if (logging_level < LOG_WARNING)
+ 1788 0 : logging_level = LOG_WARNING;
+ 1789 :
+ 1790 0 : dlt_vlog(LOG_WARNING, "Wrong parameter for level: %d\n", level);
+ 1791 : }
+ 1792 : else {
+ 1793 12 : logging_level = level;
+ 1794 : }
+ 1795 12 : }
+ 1796 :
+ 1797 10 : void dlt_log_set_filename(const char *filename)
+ 1798 : {
+ 1799 : /* check nullpointer */
+ 1800 10 : if (filename == NULL) {
+ 1801 1 : dlt_log(LOG_WARNING, "Wrong parameter: filename is NULL\n");
+ 1802 1 : return;
+ 1803 : }
+ 1804 :
+ 1805 : strncpy(logging_filename, filename, NAME_MAX);
+ 1806 9 : logging_filename[NAME_MAX] = 0;
+ 1807 : }
+ 1808 :
+ 1809 : #if defined DLT_DAEMON_USE_FIFO_IPC || defined DLT_LIB_USE_FIFO_IPC
+ 1810 6689 : void dlt_log_set_fifo_basedir(const char *pipe_dir)
+ 1811 : {
+ 1812 : strncpy(dltFifoBaseDir, pipe_dir, DLT_PATH_MAX);
+ 1813 6689 : dltFifoBaseDir[DLT_PATH_MAX - 1] = 0;
+ 1814 6687 : }
+ 1815 : #endif
+ 1816 :
+ 1817 : #ifdef DLT_SHM_ENABLE
+ 1818 : void dlt_log_set_shm_name(const char *env_shm_name)
+ 1819 : {
+ 1820 : strncpy(dltShmName, env_shm_name, NAME_MAX);
+ 1821 : dltShmName[NAME_MAX] = 0;
+ 1822 : }
+ 1823 : #endif
+ 1824 :
+ 1825 0 : void dlt_print_with_attributes(bool state)
+ 1826 : {
+ 1827 0 : print_with_attributes = state;
+ 1828 0 : }
+ 1829 :
+ 1830 12 : DltReturnValue dlt_log_init(int mode)
+ 1831 : {
+ 1832 12 : return dlt_log_init_multiple_logfiles_support((DltLoggingMode)mode, false, 0, 0);
+ 1833 : }
+ 1834 :
+ 1835 19 : DltReturnValue dlt_log_init_multiple_logfiles_support(const DltLoggingMode mode, const bool enable_multiple_logfiles,
+ 1836 : const int logging_file_size, const int logging_files_max_size)
+ 1837 : {
+ 1838 19 : if ((mode < DLT_LOG_TO_CONSOLE) || (mode > DLT_LOG_DROPPED)) {
+ 1839 0 : dlt_vlog(LOG_WARNING, "Wrong parameter for mode: %d\n", mode);
+ 1840 0 : return DLT_RETURN_WRONG_PARAMETER;
+ 1841 : }
+ 1842 :
+ 1843 19 : logging_mode = mode;
+ 1844 :
+ 1845 19 : if (logging_mode != DLT_LOG_TO_FILE) {
+ 1846 : return DLT_RETURN_OK;
+ 1847 : }
+ 1848 :
+ 1849 7 : if (enable_multiple_logfiles) {
+ 1850 4 : dlt_user_printf("configure dlt logging using file limits\n");
+ 1851 4 : int result = dlt_log_init_multiple_logfiles(logging_file_size, logging_files_max_size);
+ 1852 4 : if (result == DLT_RETURN_OK) {
+ 1853 : return DLT_RETURN_OK;
+ 1854 : }
+ 1855 1 : dlt_user_printf("dlt logging for limits fails with error code=%d, use logging without limits as fallback\n", result);
+ 1856 1 : return dlt_log_init_single_logfile();
+ 1857 : } else {
+ 1858 3 : dlt_user_printf("configure dlt logging without file limits\n");
+ 1859 3 : return dlt_log_init_single_logfile();
+ 1860 : }
+ 1861 : }
+ 1862 :
+ 1863 4 : DltReturnValue dlt_log_init_single_logfile()
+ 1864 : {
+ 1865 : /* internal logging to file */
+ 1866 4 : errno = 0;
+ 1867 4 : logging_handle = fopen(logging_filename, "a");
+ 1868 :
+ 1869 4 : if (logging_handle == NULL) {
+ 1870 0 : dlt_user_printf("Internal log file %s cannot be opened, error: %s\n", logging_filename, strerror(errno));
+ 1871 0 : return DLT_RETURN_ERROR;
+ 1872 : }
+ 1873 : return DLT_RETURN_OK;
+ 1874 : }
+ 1875 :
+ 1876 4 : DltReturnValue dlt_log_init_multiple_logfiles(const int logging_file_size, const int logging_files_max_size)
+ 1877 : {
+ 1878 : char path_logging_filename[PATH_MAX + 1];
+ 1879 : strncpy(path_logging_filename, logging_filename, PATH_MAX);
+ 1880 4 : path_logging_filename[PATH_MAX] = 0;
+ 1881 :
+ 1882 4 : const char *directory = dirname(path_logging_filename);
+ 1883 4 : if (directory[0]) {
+ 1884 : char basename_logging_filename[NAME_MAX + 1];
+ 1885 : strncpy(basename_logging_filename, logging_filename, NAME_MAX);
+ 1886 4 : basename_logging_filename[NAME_MAX] = 0;
+ 1887 :
+ 1888 4 : const char *file_name = basename(basename_logging_filename);
+ 1889 : char filename_base[NAME_MAX];
+ 1890 4 : if (!dlt_extract_base_name_without_ext(file_name, filename_base, sizeof(filename_base))) return DLT_RETURN_ERROR;
+ 1891 :
+ 1892 3 : const char *filename_ext = get_filename_ext(file_name);
+ 1893 3 : if (!filename_ext) return DLT_RETURN_ERROR;
+ 1894 :
+ 1895 3 : DltReturnValue result = multiple_files_buffer_init(
+ 1896 : &multiple_files_ring_buffer,
+ 1897 : directory,
+ 1898 : logging_file_size,
+ 1899 : logging_files_max_size,
+ 1900 : false,
+ 1901 : true,
+ 1902 : filename_base,
+ 1903 : filename_ext);
+ 1904 :
+ 1905 3 : return result;
+ 1906 : }
+ 1907 :
+ 1908 : return DLT_RETURN_ERROR;
+ 1909 : }
+ 1910 :
+ 1911 8 : void dlt_log_free(void)
+ 1912 : {
+ 1913 8 : if (logging_mode == DLT_LOG_TO_FILE) {
+ 1914 5 : if (dlt_is_log_in_multiple_files_active()) {
+ 1915 3 : dlt_log_free_multiple_logfiles();
+ 1916 : } else {
+ 1917 2 : dlt_log_free_single_logfile();
+ 1918 : }
+ 1919 : }
+ 1920 8 : }
+ 1921 :
+ 1922 2 : void dlt_log_free_single_logfile()
+ 1923 : {
+ 1924 2 : if (logging_handle)
+ 1925 2 : fclose(logging_handle);
+ 1926 2 : }
+ 1927 :
+ 1928 3 : void dlt_log_free_multiple_logfiles()
+ 1929 : {
+ 1930 3 : if (DLT_RETURN_ERROR == multiple_files_buffer_free(&multiple_files_ring_buffer)) return;
+ 1931 :
+ 1932 : // reset indicator of multiple files usage
+ 1933 3 : multiple_files_ring_buffer.ohandle = -1;
+ 1934 : }
+ 1935 :
+ 1936 2852 : int dlt_user_printf(const char *format, ...)
+ 1937 : {
+ 1938 2852 : if (format == NULL) return -1;
+ 1939 :
+ 1940 : va_list args;
+ 1941 2852 : va_start(args, format);
+ 1942 :
+ 1943 : int ret = 0;
+ 1944 :
+ 1945 2852 : switch (logging_mode) {
+ 1946 8 : case DLT_LOG_TO_CONSOLE:
+ 1947 : case DLT_LOG_TO_SYSLOG:
+ 1948 : case DLT_LOG_TO_FILE:
+ 1949 : case DLT_LOG_DROPPED:
+ 1950 : default:
+ 1951 8 : ret = vfprintf(stdout, format, args);
+ 1952 8 : break;
+ 1953 2844 : case DLT_LOG_TO_STDERR:
+ 1954 2844 : ret = vfprintf(stderr, format, args);
+ 1955 2844 : break;
+ 1956 : }
+ 1957 :
+ 1958 2852 : va_end(args);
+ 1959 :
+ 1960 2852 : return ret;
+ 1961 : }
+ 1962 :
+ 1963 818061 : DltReturnValue dlt_log(int prio, char *s)
+ 1964 : {
+ 1965 : static const char asSeverity[LOG_DEBUG +
+ 1966 : 2][11] =
+ 1967 : { "EMERGENCY", "ALERT ", "CRITICAL ", "ERROR ", "WARNING ", "NOTICE ", "INFO ", "DEBUG ",
+ 1968 : " " };
+ 1969 : static const char sFormatString[] = "[%5u.%06u]~DLT~%5d~%s~%s";
+ 1970 : struct timespec sTimeSpec;
+ 1971 :
+ 1972 818061 : if (s == NULL)
+ 1973 : return DLT_RETURN_WRONG_PARAMETER;
+ 1974 :
+ 1975 818060 : if (logging_level < prio)
+ 1976 : return DLT_RETURN_OK;
+ 1977 :
+ 1978 817992 : if ((prio < 0) || (prio > LOG_DEBUG))
+ 1979 : prio = LOG_DEBUG + 1;
+ 1980 :
+ 1981 817992 : clock_gettime(CLOCK_MONOTONIC, &sTimeSpec);
+ 1982 :
+ 1983 817992 : switch (logging_mode) {
+ 1984 62 : case DLT_LOG_TO_CONSOLE:
+ 1985 : /* log to stdout */
+ 1986 124 : fprintf(stdout, sFormatString,
+ 1987 62 : (unsigned int)sTimeSpec.tv_sec,
+ 1988 62 : (unsigned int)(sTimeSpec.tv_nsec / 1000),
+ 1989 : getpid(),
+ 1990 62 : asSeverity[prio],
+ 1991 : s);
+ 1992 62 : fflush(stdout);
+ 1993 62 : break;
+ 1994 817893 : case DLT_LOG_TO_STDERR:
+ 1995 : /* log to stderr */
+ 1996 1635786 : fprintf(stderr, sFormatString,
+ 1997 817893 : (unsigned int)sTimeSpec.tv_sec,
+ 1998 817893 : (unsigned int)(sTimeSpec.tv_nsec / 1000),
+ 1999 : getpid(),
+ 2000 817893 : asSeverity[prio],
+ 2001 : s);
+ 2002 : break;
+ 2003 0 : case DLT_LOG_TO_SYSLOG:
+ 2004 : /* log to syslog */
+ 2005 : #if !defined (__WIN32__) && !defined(_MSC_VER)
+ 2006 0 : openlog("DLT", LOG_PID, LOG_DAEMON);
+ 2007 0 : syslog(prio,
+ 2008 : sFormatString,
+ 2009 0 : (unsigned int)sTimeSpec.tv_sec,
+ 2010 0 : (unsigned int)(sTimeSpec.tv_nsec / 1000),
+ 2011 : getpid(),
+ 2012 0 : asSeverity[prio],
+ 2013 : s);
+ 2014 0 : closelog();
+ 2015 : #endif
+ 2016 0 : break;
+ 2017 32 : case DLT_LOG_TO_FILE:
+ 2018 : /* log to file */
+ 2019 :
+ 2020 32 : if (dlt_is_log_in_multiple_files_active()) {
+ 2021 24 : dlt_log_multiple_files_write(sFormatString, (unsigned int)sTimeSpec.tv_sec,
+ 2022 12 : (unsigned int)(sTimeSpec.tv_nsec / 1000), getpid(), asSeverity[prio], s);
+ 2023 : }
+ 2024 20 : else if (logging_handle) {
+ 2025 40 : fprintf(logging_handle, sFormatString, (unsigned int)sTimeSpec.tv_sec,
+ 2026 20 : (unsigned int)(sTimeSpec.tv_nsec / 1000), getpid(), asSeverity[prio], s);
+ 2027 20 : fflush(logging_handle);
+ 2028 : }
+ 2029 :
+ 2030 : break;
+ 2031 : case DLT_LOG_DROPPED:
+ 2032 : default:
+ 2033 : break;
+ 2034 : }
+ 2035 :
+ 2036 : return DLT_RETURN_OK;
+ 2037 : }
+ 2038 :
+ 2039 818423 : DltReturnValue dlt_vlog(int prio, const char *format, ...)
+ 2040 : {
+ 2041 818423 : char outputString[2048] = { 0 }; /* TODO: what is a reasonable string length here? */
+ 2042 :
+ 2043 : va_list args;
+ 2044 :
+ 2045 818423 : if (format == NULL)
+ 2046 : return DLT_RETURN_WRONG_PARAMETER;
+ 2047 :
+ 2048 818423 : if (logging_level < prio)
+ 2049 : return DLT_RETURN_OK;
+ 2050 :
+ 2051 811258 : va_start(args, format);
+ 2052 : vsnprintf(outputString, 2047, format, args);
+ 2053 811258 : va_end(args);
+ 2054 :
+ 2055 811258 : dlt_log(prio, outputString);
+ 2056 :
+ 2057 811258 : return DLT_RETURN_OK;
+ 2058 : }
+ 2059 :
+ 2060 6687 : DltReturnValue dlt_vnlog(int prio, size_t size, const char *format, ...)
+ 2061 : {
+ 2062 : char *outputString = NULL;
+ 2063 :
+ 2064 : va_list args;
+ 2065 :
+ 2066 6687 : if (format == NULL)
+ 2067 : return DLT_RETURN_WRONG_PARAMETER;
+ 2068 :
+ 2069 6687 : if ((logging_level < prio) || (size == 0))
+ 2070 : return DLT_RETURN_OK;
+ 2071 :
+ 2072 6687 : if ((outputString = (char *)calloc(size + 1, sizeof(char))) == NULL)
+ 2073 : return DLT_RETURN_ERROR;
+ 2074 :
+ 2075 6687 : va_start(args, format);
+ 2076 : vsnprintf(outputString, size, format, args);
+ 2077 6687 : va_end(args);
+ 2078 :
+ 2079 6687 : dlt_log(prio, outputString);
+ 2080 :
+ 2081 6687 : free(outputString);
+ 2082 : outputString = NULL;
+ 2083 :
+ 2084 6687 : return DLT_RETURN_OK;
+ 2085 : }
+ 2086 :
+ 2087 6702 : DltReturnValue dlt_receiver_init(DltReceiver *receiver, int fd, DltReceiverType type, int buffersize)
+ 2088 : {
+ 2089 6702 : if (NULL == receiver)
+ 2090 : return DLT_RETURN_WRONG_PARAMETER;
+ 2091 :
+ 2092 6702 : receiver->fd = fd;
+ 2093 6702 : receiver->type = type;
+ 2094 :
+ 2095 : /** Reuse the receiver buffer if it exists and the buffer size
+ 2096 : * is not changed. If not, free the old one and allocate a new buffer.
+ 2097 : */
+ 2098 6702 : if ((NULL != receiver->buffer) && ( buffersize != receiver->buffersize)) {
+ 2099 0 : free(receiver->buffer);
+ 2100 0 : receiver->buffer = NULL;
+ 2101 : }
+ 2102 :
+ 2103 6702 : if (NULL == receiver->buffer) {
+ 2104 6702 : receiver->lastBytesRcvd = 0;
+ 2105 6702 : receiver->bytesRcvd = 0;
+ 2106 6702 : receiver->totalBytesRcvd = 0;
+ 2107 6702 : receiver->buf = NULL;
+ 2108 6702 : receiver->backup_buf = NULL;
+ 2109 6702 : receiver->buffer = (char *)calloc(1, (size_t)buffersize);
+ 2110 6702 : receiver->buffersize = (uint32_t)buffersize;
+ 2111 : }
+ 2112 :
+ 2113 6702 : if (NULL == receiver->buffer) {
+ 2114 0 : dlt_log(LOG_ERR, "allocate memory for receiver buffer failed.\n");
+ 2115 0 : return DLT_RETURN_ERROR;
+ 2116 : }
+ 2117 : else {
+ 2118 6702 : receiver->buf = receiver->buffer;
+ 2119 : }
+ 2120 :
+ 2121 6702 : return DLT_RETURN_OK;
+ 2122 : }
+ 2123 :
+ 2124 2 : DltReturnValue dlt_receiver_init_global_buffer(DltReceiver *receiver, int fd, DltReceiverType type, char **buffer)
+ 2125 : {
+ 2126 2 : if (receiver == NULL)
+ 2127 : return DLT_RETURN_WRONG_PARAMETER;
+ 2128 :
+ 2129 2 : if (*buffer == NULL) {
+ 2130 : /* allocating the buffer once and using it for all application receivers
+ 2131 : * by keeping allocated buffer in app_recv_buffer global handle
+ 2132 : */
+ 2133 2 : *buffer = (char *)malloc(DLT_RECEIVE_BUFSIZE);
+ 2134 :
+ 2135 2 : if (*buffer == NULL)
+ 2136 : return DLT_RETURN_ERROR;
+ 2137 : }
+ 2138 :
+ 2139 2 : receiver->lastBytesRcvd = 0;
+ 2140 2 : receiver->bytesRcvd = 0;
+ 2141 2 : receiver->totalBytesRcvd = 0;
+ 2142 2 : receiver->buffersize = DLT_RECEIVE_BUFSIZE;
+ 2143 2 : receiver->fd = fd;
+ 2144 2 : receiver->type = type;
+ 2145 2 : receiver->buffer = *buffer;
+ 2146 2 : receiver->backup_buf = NULL;
+ 2147 2 : receiver->buf = receiver->buffer;
+ 2148 :
+ 2149 2 : return DLT_RETURN_OK;
+ 2150 : }
+ 2151 :
+ 2152 6702 : DltReturnValue dlt_receiver_free(DltReceiver *receiver)
+ 2153 : {
+ 2154 :
+ 2155 6702 : if (receiver == NULL)
+ 2156 : return DLT_RETURN_WRONG_PARAMETER;
+ 2157 :
+ 2158 6702 : if (receiver->buffer)
+ 2159 6700 : free(receiver->buffer);
+ 2160 :
+ 2161 6702 : if (receiver->backup_buf)
+ 2162 0 : free(receiver->backup_buf);
+ 2163 :
+ 2164 6702 : receiver->buffer = NULL;
+ 2165 6702 : receiver->buf = NULL;
+ 2166 6702 : receiver->backup_buf = NULL;
+ 2167 :
+ 2168 6702 : return DLT_RETURN_OK;
+ 2169 : }
+ 2170 :
+ 2171 2 : DltReturnValue dlt_receiver_free_global_buffer(DltReceiver *receiver)
+ 2172 : {
+ 2173 :
+ 2174 2 : if (receiver == NULL)
+ 2175 : return DLT_RETURN_WRONG_PARAMETER;
+ 2176 :
+ 2177 2 : if (receiver->backup_buf)
+ 2178 0 : free(receiver->backup_buf);
+ 2179 :
+ 2180 2 : receiver->buffer = NULL;
+ 2181 2 : receiver->buf = NULL;
+ 2182 2 : receiver->backup_buf = NULL;
+ 2183 :
+ 2184 2 : return DLT_RETURN_OK;
+ 2185 : }
+ 2186 :
+ 2187 12 : int dlt_receiver_receive(DltReceiver *receiver)
+ 2188 : {
+ 2189 : socklen_t addrlen;
+ 2190 :
+ 2191 12 : if (receiver == NULL)
+ 2192 : return -1;
+ 2193 :
+ 2194 12 : if (receiver->buffer == NULL)
+ 2195 : return -1;
+ 2196 :
+ 2197 11 : receiver->buf = (char *)receiver->buffer;
+ 2198 11 : receiver->lastBytesRcvd = receiver->bytesRcvd;
+ 2199 :
+ 2200 11 : if ((receiver->lastBytesRcvd) && (receiver->backup_buf != NULL)) {
+ 2201 2 : memcpy(receiver->buf, receiver->backup_buf, (size_t)receiver->lastBytesRcvd);
+ 2202 2 : free(receiver->backup_buf);
+ 2203 2 : receiver->backup_buf = NULL;
+ 2204 : }
+ 2205 :
+ 2206 11 : if (receiver->type == DLT_RECEIVE_SOCKET)
+ 2207 : /* wait for data from socket */
+ 2208 11 : receiver->bytesRcvd = recv(receiver->fd,
+ 2209 11 : receiver->buf + receiver->lastBytesRcvd,
+ 2210 11 : receiver->buffersize - (uint32_t) receiver->lastBytesRcvd,
+ 2211 : 0);
+ 2212 0 : else if (receiver->type == DLT_RECEIVE_FD)
+ 2213 : /* wait for data from fd */
+ 2214 0 : receiver->bytesRcvd = read(receiver->fd,
+ 2215 0 : receiver->buf + receiver->lastBytesRcvd,
+ 2216 0 : receiver->buffersize - (uint32_t) receiver->lastBytesRcvd);
+ 2217 :
+ 2218 : else { /* receiver->type == DLT_RECEIVE_UDP_SOCKET */
+ 2219 : /* wait for data from UDP socket */
+ 2220 0 : addrlen = sizeof(receiver->addr);
+ 2221 0 : receiver->bytesRcvd = recvfrom(receiver->fd,
+ 2222 0 : receiver->buf + receiver->lastBytesRcvd,
+ 2223 0 : receiver->buffersize - receiver->lastBytesRcvd,
+ 2224 : 0,
+ 2225 0 : (struct sockaddr *)&(receiver->addr),
+ 2226 : &addrlen);
+ 2227 : }
+ 2228 :
+ 2229 11 : if (receiver->bytesRcvd <= 0) {
+ 2230 0 : receiver->bytesRcvd = 0;
+ 2231 0 : return receiver->bytesRcvd;
+ 2232 : } /* if */
+ 2233 :
+ 2234 11 : receiver->totalBytesRcvd += receiver->bytesRcvd;
+ 2235 11 : receiver->bytesRcvd += receiver->lastBytesRcvd;
+ 2236 :
+ 2237 11 : return receiver->bytesRcvd;
+ 2238 : }
+ 2239 :
+ 2240 21 : DltReturnValue dlt_receiver_remove(DltReceiver *receiver, int size)
+ 2241 : {
+ 2242 21 : if (receiver == NULL)
+ 2243 : return DLT_RETURN_WRONG_PARAMETER;
+ 2244 :
+ 2245 21 : if (receiver->buf == NULL)
+ 2246 : return DLT_RETURN_ERROR;
+ 2247 :
+ 2248 21 : if ((size > receiver->bytesRcvd) || (size <= 0)) {
+ 2249 0 : receiver->buf = receiver->buf + receiver->bytesRcvd;
+ 2250 0 : receiver->bytesRcvd = 0;
+ 2251 0 : return DLT_RETURN_WRONG_PARAMETER;
+ 2252 : }
+ 2253 :
+ 2254 21 : receiver->bytesRcvd = receiver->bytesRcvd - size;
+ 2255 0 : receiver->buf = receiver->buf + size;
+ 2256 :
+ 2257 21 : return DLT_RETURN_OK;
+ 2258 : }
+ 2259 :
+ 2260 11 : DltReturnValue dlt_receiver_move_to_begin(DltReceiver *receiver)
+ 2261 : {
+ 2262 11 : if (receiver == NULL)
+ 2263 : return DLT_RETURN_WRONG_PARAMETER;
+ 2264 :
+ 2265 11 : if ((receiver->buffer == NULL) || (receiver->buf == NULL))
+ 2266 : return DLT_RETURN_ERROR;
+ 2267 :
+ 2268 11 : if ((receiver->buffer != receiver->buf) && (receiver->bytesRcvd != 0)) {
+ 2269 2 : receiver->backup_buf = calloc((size_t)(receiver->bytesRcvd + 1), sizeof(char));
+ 2270 :
+ 2271 2 : if (receiver->backup_buf == NULL)
+ 2272 0 : dlt_vlog(LOG_WARNING,
+ 2273 : "Can't allocate memory for backup buf, there will be atleast"
+ 2274 : "one corrupted message for fd[%d] \n", receiver->fd);
+ 2275 : else
+ 2276 2 : memcpy(receiver->backup_buf, receiver->buf, (size_t)receiver->bytesRcvd);
+ 2277 : }
+ 2278 :
+ 2279 : return DLT_RETURN_OK;
+ 2280 : }
+ 2281 :
+ 2282 0 : int dlt_receiver_check_and_get(DltReceiver *receiver,
+ 2283 : void *dest,
+ 2284 : unsigned int to_get,
+ 2285 : unsigned int flags)
+ 2286 : {
+ 2287 0 : size_t min_size = (size_t)to_get;
+ 2288 : uint8_t *src = NULL;
+ 2289 :
+ 2290 0 : if (flags & DLT_RCV_SKIP_HEADER)
+ 2291 0 : min_size += sizeof(DltUserHeader);
+ 2292 :
+ 2293 0 : if (!receiver ||
+ 2294 0 : (receiver->bytesRcvd < (int32_t) min_size) ||
+ 2295 0 : !receiver->buf ||
+ 2296 : !dest)
+ 2297 : return DLT_RETURN_WRONG_PARAMETER;
+ 2298 :
+ 2299 : src = (uint8_t *)receiver->buf;
+ 2300 :
+ 2301 0 : if (flags & DLT_RCV_SKIP_HEADER)
+ 2302 0 : src += sizeof(DltUserHeader);
+ 2303 :
+ 2304 : memcpy(dest, src, to_get);
+ 2305 :
+ 2306 0 : if (flags & DLT_RCV_REMOVE) {
+ 2307 0 : if (dlt_receiver_remove(receiver, (int)min_size) != DLT_RETURN_OK) {
+ 2308 0 : dlt_log(LOG_WARNING, "Can't remove bytes from receiver\n");
+ 2309 0 : return DLT_RETURN_ERROR;
+ 2310 : }
+ 2311 : }
+ 2312 :
+ 2313 0 : return to_get;
+ 2314 : }
+ 2315 :
+ 2316 234 : DltReturnValue dlt_set_storageheader(DltStorageHeader *storageheader, const char *ecu)
+ 2317 : {
+ 2318 :
+ 2319 : #if !defined(_MSC_VER)
+ 2320 : struct timeval tv;
+ 2321 : #endif
+ 2322 :
+ 2323 234 : if ((storageheader == NULL) || (ecu == NULL))
+ 2324 : return DLT_RETURN_WRONG_PARAMETER;
+ 2325 :
+ 2326 : /* get time of day */
+ 2327 : #if defined(_MSC_VER)
+ 2328 : time(&(storageheader->seconds));
+ 2329 : #else
+ 2330 234 : gettimeofday(&tv, NULL);
+ 2331 : #endif
+ 2332 :
+ 2333 : /* prepare storage header */
+ 2334 234 : storageheader->pattern[0] = 'D';
+ 2335 234 : storageheader->pattern[1] = 'L';
+ 2336 234 : storageheader->pattern[2] = 'T';
+ 2337 234 : storageheader->pattern[3] = 0x01;
+ 2338 :
+ 2339 234 : dlt_set_id(storageheader->ecu, ecu);
+ 2340 :
+ 2341 : /* Set current time */
+ 2342 : #if defined(_MSC_VER)
+ 2343 : storageheader->microseconds = 0;
+ 2344 : #else
+ 2345 234 : storageheader->seconds = (uint32_t) tv.tv_sec; /* value is long */
+ 2346 234 : storageheader->microseconds = (int32_t) tv.tv_usec; /* value is long */
+ 2347 : #endif
+ 2348 :
+ 2349 234 : return DLT_RETURN_OK;
+ 2350 : }
+ 2351 :
+ 2352 7 : DltReturnValue dlt_check_rcv_data_size(int received, int required)
+ 2353 : {
+ 2354 : int _ret = DLT_RETURN_OK;
+ 2355 7 : if (received < required) {
+ 2356 1 : dlt_vlog(LOG_WARNING, "%s: Received data not complete\n", __func__);
+ 2357 : _ret = DLT_RETURN_ERROR;
+ 2358 : }
+ 2359 :
+ 2360 7 : return _ret;
+ 2361 : }
+ 2362 :
+ 2363 5571 : DltReturnValue dlt_check_storageheader(DltStorageHeader *storageheader)
+ 2364 : {
+ 2365 5571 : if (storageheader == NULL)
+ 2366 : return DLT_RETURN_WRONG_PARAMETER;
+ 2367 :
+ 2368 11142 : return ((storageheader->pattern[0] == 'D') &&
+ 2369 5571 : (storageheader->pattern[1] == 'L') &&
+ 2370 5571 : (storageheader->pattern[2] == 'T') &&
+ 2371 5571 : (storageheader->pattern[3] == 1))
+ 2372 11142 : ? DLT_RETURN_TRUE : DLT_RETURN_OK;
+ 2373 : }
+ 2374 :
+ 2375 0 : DltReturnValue dlt_buffer_init_static_server(DltBuffer *buf, const unsigned char *ptr, uint32_t size)
+ 2376 : {
+ 2377 0 : if ((buf == NULL) || (ptr == NULL))
+ 2378 : return DLT_RETURN_WRONG_PARAMETER;
+ 2379 :
+ 2380 : DltBufferHead *head;
+ 2381 :
+ 2382 : /* Init parameters */
+ 2383 0 : buf->shm = (unsigned char *)ptr;
+ 2384 0 : buf->min_size = size;
+ 2385 0 : buf->max_size = size;
+ 2386 0 : buf->step_size = 0;
+ 2387 :
+ 2388 : /* Init pointers */
+ 2389 : head = (DltBufferHead *)buf->shm;
+ 2390 0 : head->read = 0;
+ 2391 0 : head->write = 0;
+ 2392 0 : head->count = 0;
+ 2393 0 : buf->mem = (unsigned char *)(buf->shm + sizeof(DltBufferHead));
+ 2394 0 : buf->size = (unsigned int) buf->min_size - (unsigned int) sizeof(DltBufferHead);
+ 2395 :
+ 2396 : /* clear memory */
+ 2397 0 : memset(buf->mem, 0, buf->size);
+ 2398 :
+ 2399 0 : dlt_vlog(LOG_DEBUG,
+ 2400 : "%s: Buffer: Size %u, Start address %lX\n",
+ 2401 0 : __func__, buf->size, (unsigned long)buf->mem);
+ 2402 :
+ 2403 0 : return DLT_RETURN_OK; /* OK */
+ 2404 : }
+ 2405 :
+ 2406 0 : DltReturnValue dlt_buffer_init_static_client(DltBuffer *buf, const unsigned char *ptr, uint32_t size)
+ 2407 : {
+ 2408 0 : if ((buf == NULL) || (ptr == NULL))
+ 2409 : return DLT_RETURN_WRONG_PARAMETER;
+ 2410 :
+ 2411 : /* Init parameters */
+ 2412 0 : buf->shm = (unsigned char *)ptr;
+ 2413 0 : buf->min_size = size;
+ 2414 0 : buf->max_size = size;
+ 2415 0 : buf->step_size = 0;
+ 2416 :
+ 2417 : /* Init pointers */
+ 2418 0 : buf->mem = (unsigned char *)(buf->shm + sizeof(DltBufferHead));
+ 2419 0 : buf->size = (uint32_t)(buf->min_size - sizeof(DltBufferHead));
+ 2420 :
+ 2421 0 : dlt_vlog(LOG_DEBUG,
+ 2422 : "%s: Buffer: Size %u, Start address %lX\n",
+ 2423 : __func__, buf->size, (unsigned long)buf->mem);
+ 2424 :
+ 2425 0 : return DLT_RETURN_OK; /* OK */
+ 2426 : }
+ 2427 :
+ 2428 6811 : DltReturnValue dlt_buffer_init_dynamic(DltBuffer *buf, uint32_t min_size, uint32_t max_size, uint32_t step_size)
+ 2429 : {
+ 2430 : /*Do not DLT_SEM_LOCK inside here! */
+ 2431 : DltBufferHead *head;
+ 2432 :
+ 2433 : /* catch null pointer */
+ 2434 6811 : if (buf == NULL)
+ 2435 : return DLT_RETURN_WRONG_PARAMETER;
+ 2436 :
+ 2437 : /* catch 0 logical errors */
+ 2438 6803 : if ((min_size == 0) || (max_size == 0) || (step_size == 0))
+ 2439 : return DLT_RETURN_WRONG_PARAMETER;
+ 2440 :
+ 2441 6796 : if (min_size > max_size)
+ 2442 : return DLT_RETURN_WRONG_PARAMETER;
+ 2443 :
+ 2444 6796 : if (step_size > max_size)
+ 2445 : return DLT_RETURN_WRONG_PARAMETER;
+ 2446 :
+ 2447 : /* Init parameters */
+ 2448 6796 : buf->min_size = min_size;
+ 2449 6796 : buf->max_size = max_size;
+ 2450 6796 : buf->step_size = step_size;
+ 2451 :
+ 2452 : /* allocat memory */
+ 2453 6796 : buf->shm = malloc(buf->min_size);
+ 2454 :
+ 2455 6796 : if (buf->shm == NULL) {
+ 2456 0 : dlt_vlog(LOG_EMERG,
+ 2457 : "%s: Buffer: Cannot allocate %u bytes\n",
+ 2458 : __func__, buf->min_size);
+ 2459 0 : return DLT_RETURN_ERROR;
+ 2460 : }
+ 2461 :
+ 2462 : /* Init pointers */
+ 2463 : head = (DltBufferHead *)buf->shm;
+ 2464 6796 : head->read = 0;
+ 2465 6796 : head->write = 0;
+ 2466 6796 : head->count = 0;
+ 2467 6796 : buf->mem = (unsigned char *)(buf->shm + sizeof(DltBufferHead));
+ 2468 :
+ 2469 6796 : if (buf->min_size < (uint32_t)sizeof(DltBufferHead)) {
+ 2470 0 : dlt_vlog(LOG_ERR,
+ 2471 : "%s: min_size is too small [%u]\n",
+ 2472 : __func__, buf->min_size);
+ 2473 0 : return DLT_RETURN_WRONG_PARAMETER;
+ 2474 : }
+ 2475 :
+ 2476 6796 : buf->size = (uint32_t) (buf->min_size - sizeof(DltBufferHead));
+ 2477 :
+ 2478 6796 : dlt_vlog(LOG_DEBUG,
+ 2479 : "%s: Buffer: Size %u, Start address %lX\n",
+ 2480 : __func__, buf->size, (unsigned long)buf->mem);
+ 2481 :
+ 2482 : /* clear memory */
+ 2483 6796 : memset(buf->mem, 0, (size_t)buf->size);
+ 2484 :
+ 2485 6796 : return DLT_RETURN_OK; /* OK */
+ 2486 : }
+ 2487 :
+ 2488 0 : DltReturnValue dlt_buffer_free_static(DltBuffer *buf)
+ 2489 : {
+ 2490 : /* catch null pointer */
+ 2491 0 : if (buf == NULL)
+ 2492 : return DLT_RETURN_WRONG_PARAMETER;
+ 2493 :
+ 2494 0 : if (buf->mem == NULL) {
+ 2495 : /* buffer not initialized */
+ 2496 0 : dlt_vlog(LOG_WARNING, "%s: Buffer: Buffer not initialized\n", __func__);
+ 2497 0 : return DLT_RETURN_ERROR; /* ERROR */
+ 2498 : }
+ 2499 :
+ 2500 : return DLT_RETURN_OK;
+ 2501 : }
+ 2502 :
+ 2503 6785 : DltReturnValue dlt_buffer_free_dynamic(DltBuffer *buf)
+ 2504 : {
+ 2505 : /* catch null pointer */
+ 2506 6785 : if (buf == NULL)
+ 2507 : return DLT_RETURN_WRONG_PARAMETER;
+ 2508 :
+ 2509 6784 : if (buf->shm == NULL) {
+ 2510 : /* buffer not initialized */
+ 2511 0 : dlt_vlog(LOG_WARNING, "%s: Buffer: Buffer not initialized\n", __func__);
+ 2512 0 : return DLT_RETURN_ERROR; /* ERROR */
+ 2513 : }
+ 2514 :
+ 2515 6784 : free(buf->shm);
+ 2516 6784 : buf->shm = NULL;
+ 2517 6784 : buf->mem = NULL;
+ 2518 :
+ 2519 6784 : return DLT_RETURN_OK;
+ 2520 : }
+ 2521 :
+ 2522 24692 : void dlt_buffer_write_block(DltBuffer *buf, int *write, const unsigned char *data, unsigned int size)
+ 2523 : {
+ 2524 : /* catch null pointer */
+ 2525 24692 : if ((buf != NULL) && (write != NULL) && (data != NULL)) {
+ 2526 23673 : if (size <= buf->size){
+ 2527 23673 : if (( (unsigned int) (*write ) + size) <= buf->size) {
+ 2528 : /* write one block */
+ 2529 23672 : memcpy(buf->mem + *write, data, size);
+ 2530 23672 : *write += (int) size;
+ 2531 : }
+ 2532 : else {
+ 2533 : /* when (*write) = buf->size, write only the second block
+ 2534 : * and update write position correspondingly.
+ 2535 : */
+ 2536 1 : if((unsigned int) (*write) <= buf->size) {
+ 2537 : /* write two blocks */
+ 2538 1 : memcpy(buf->mem + *write, data, buf->size - (unsigned int) (*write));
+ 2539 1 : memcpy(buf->mem, data + buf->size - *write, size - buf->size + (unsigned int) (*write));
+ 2540 1 : *write += (int) (size - buf->size);
+ 2541 : }
+ 2542 : }
+ 2543 : }
+ 2544 : else {
+ 2545 0 : dlt_vlog(LOG_WARNING, "%s: Write error: ring buffer to small\n", __func__);
+ 2546 : }
+ 2547 : }
+ 2548 : else {
+ 2549 1019 : dlt_vlog(LOG_WARNING, "%s: Wrong parameter: Null pointer\n", __func__);
+ 2550 : }
+ 2551 24692 : }
+ 2552 :
+ 2553 45 : void dlt_buffer_read_block(DltBuffer *buf, int *read, unsigned char *data, unsigned int size)
+ 2554 : {
+ 2555 : /* catch nullpointer */
+ 2556 45 : if ((buf != NULL) && (read != NULL) && (data != NULL)) {
+ 2557 29 : if (((unsigned int)(*read) + size) <= buf->size) {
+ 2558 : /* read one block */
+ 2559 27 : memcpy(data, buf->mem + *read, size);
+ 2560 27 : *read += (int)size;
+ 2561 : }
+ 2562 : else {
+ 2563 : /* when (*read) = buf->size, read only the second block
+ 2564 : * and update read position correspondingly.
+ 2565 : */
+ 2566 2 : if ((unsigned int)(*read) <= buf->size) {
+ 2567 : /* read two blocks */
+ 2568 1 : memcpy(data, buf->mem + *read, buf->size - (unsigned int)(*read));
+ 2569 1 : memcpy(data + buf->size - *read, buf->mem, size - buf->size + (unsigned int)(*read));
+ 2570 1 : *read += (int) (size - buf->size);
+ 2571 : }
+ 2572 : }
+ 2573 : }
+ 2574 : else {
+ 2575 16 : dlt_vlog(LOG_WARNING, "%s: Wrong parameter: Null pointer\n", __func__);
+ 2576 : }
+ 2577 45 : }
+ 2578 :
+ 2579 852 : int dlt_buffer_check_size(DltBuffer *buf, int needed)
+ 2580 : {
+ 2581 852 : if (buf == NULL)
+ 2582 : return DLT_RETURN_WRONG_PARAMETER;
+ 2583 :
+ 2584 852 : if ((buf->size + sizeof(DltBufferHead) + (size_t) needed) > buf->max_size)
+ 2585 0 : return DLT_RETURN_ERROR;
+ 2586 :
+ 2587 : return DLT_RETURN_OK;
+ 2588 : }
+ 2589 :
+ 2590 7 : int dlt_buffer_increase_size(DltBuffer *buf)
+ 2591 : {
+ 2592 : DltBufferHead *head, *new_head;
+ 2593 : unsigned char *new_ptr;
+ 2594 :
+ 2595 : /* catch null pointer */
+ 2596 7 : if (buf == NULL) {
+ 2597 1 : dlt_vlog(LOG_WARNING, "%s: Wrong parameter: Null pointer\n", __func__);
+ 2598 1 : return DLT_RETURN_WRONG_PARAMETER;
+ 2599 : }
+ 2600 :
+ 2601 : /* check size */
+ 2602 6 : if (buf->step_size == 0)
+ 2603 : /* cannot increase size */
+ 2604 : return DLT_RETURN_ERROR;
+ 2605 :
+ 2606 : /* check size */
+ 2607 6 : if ((buf->size + sizeof(DltBufferHead) + buf->step_size) > buf->max_size)
+ 2608 : /* max size reached, do not increase */
+ 2609 : return DLT_RETURN_ERROR;
+ 2610 :
+ 2611 : /* allocate new buffer */
+ 2612 6 : new_ptr = malloc(buf->size + sizeof(DltBufferHead) + buf->step_size);
+ 2613 :
+ 2614 6 : if (new_ptr == NULL) {
+ 2615 0 : dlt_vlog(LOG_WARNING,
+ 2616 : "%s: Buffer: Cannot increase size because allocate %u bytes failed\n",
+ 2617 : __func__, buf->min_size);
+ 2618 0 : return DLT_RETURN_ERROR;
+ 2619 : }
+ 2620 :
+ 2621 : /* copy data */
+ 2622 6 : head = (DltBufferHead *)buf->shm;
+ 2623 : new_head = (DltBufferHead *)new_ptr;
+ 2624 :
+ 2625 6 : if (head->read < head->write) {
+ 2626 4 : memcpy(new_ptr + sizeof(DltBufferHead), buf->mem + head->read, (size_t)(head->write - head->read));
+ 2627 4 : new_head->read = 0;
+ 2628 4 : new_head->write = head->write - head->read;
+ 2629 4 : new_head->count = head->count;
+ 2630 : }
+ 2631 : else {
+ 2632 2 : memcpy(new_ptr + sizeof(DltBufferHead), buf->mem + head->read, buf->size - (uint32_t)(head->read));
+ 2633 2 : memcpy(new_ptr + sizeof(DltBufferHead) + buf->size - head->read, buf->mem, (size_t)head->write);
+ 2634 2 : new_head->read = 0;
+ 2635 2 : new_head->write = (int)(buf->size) + head->write - head->read;
+ 2636 2 : new_head->count = head->count;
+ 2637 : }
+ 2638 :
+ 2639 : /* free old data */
+ 2640 6 : free(buf->shm);
+ 2641 :
+ 2642 : /* update data */
+ 2643 6 : buf->shm = new_ptr;
+ 2644 6 : buf->mem = new_ptr + sizeof(DltBufferHead);
+ 2645 6 : buf->size += buf->step_size;
+ 2646 :
+ 2647 6 : dlt_vlog(LOG_DEBUG,
+ 2648 : "%s: Buffer: Size increased to %u bytes with start address %lX\n",
+ 2649 : __func__,
+ 2650 : buf->size + (int32_t)sizeof(DltBufferHead),
+ 2651 : (unsigned long)buf->mem);
+ 2652 :
+ 2653 6 : return DLT_RETURN_OK; /* OK */
+ 2654 : }
+ 2655 :
+ 2656 7 : int dlt_buffer_minimize_size(DltBuffer *buf)
+ 2657 : {
+ 2658 : unsigned char *new_ptr;
+ 2659 :
+ 2660 : /* catch null pointer */
+ 2661 7 : if (buf == NULL) {
+ 2662 1 : dlt_vlog(LOG_WARNING, "%s: Wrong parameter: Null pointer\n", __func__);
+ 2663 1 : return DLT_RETURN_WRONG_PARAMETER;
+ 2664 : }
+ 2665 :
+ 2666 6 : if ((buf->size + sizeof(DltBufferHead)) == buf->min_size)
+ 2667 : /* already minimized */
+ 2668 : return DLT_RETURN_OK;
+ 2669 :
+ 2670 : /* allocate new buffer */
+ 2671 0 : new_ptr = malloc(buf->min_size);
+ 2672 :
+ 2673 0 : if (new_ptr == NULL) {
+ 2674 0 : dlt_vlog(LOG_WARNING,
+ 2675 : "%s: Buffer: Cannot set to min size of %u bytes\n",
+ 2676 : __func__, buf->min_size);
+ 2677 0 : return DLT_RETURN_ERROR;
+ 2678 : }
+ 2679 :
+ 2680 : /* free old data */
+ 2681 0 : free(buf->shm);
+ 2682 :
+ 2683 : /* update data */
+ 2684 0 : buf->shm = new_ptr;
+ 2685 0 : buf->mem = new_ptr + sizeof(DltBufferHead);
+ 2686 0 : buf->size = (uint32_t)(buf->min_size - sizeof(DltBufferHead));
+ 2687 :
+ 2688 : /* reset pointers and counters */
+ 2689 0 : ((int *)(buf->shm))[0] = 0; /* pointer to write memory */
+ 2690 0 : ((int *)(buf->shm))[1] = 0; /* pointer to read memory */
+ 2691 0 : ((int *)(buf->shm))[2] = 0; /* number of packets */
+ 2692 :
+ 2693 0 : dlt_vlog(LOG_DEBUG,
+ 2694 : "%s: Buffer: Buffer minimized to Size %u bytes with start address %lX\n",
+ 2695 : __func__, buf->size, (unsigned long)buf->mem);
+ 2696 :
+ 2697 : /* clear memory */
+ 2698 0 : memset(buf->mem, 0, buf->size);
+ 2699 :
+ 2700 0 : return DLT_RETURN_OK; /* OK */
+ 2701 : }
+ 2702 :
+ 2703 9 : int dlt_buffer_reset(DltBuffer *buf)
+ 2704 : {
+ 2705 : /* catch null pointer */
+ 2706 9 : if (buf == NULL) {
+ 2707 1 : dlt_vlog(LOG_WARNING, "%s: Wrong parameter: Null pointer\n", __func__);
+ 2708 1 : return DLT_RETURN_WRONG_PARAMETER;
+ 2709 : }
+ 2710 :
+ 2711 8 : dlt_vlog(LOG_WARNING,
+ 2712 : "%s: Buffer: Buffer reset triggered. Size: %u, Start address: %lX\n",
+ 2713 8 : __func__, buf->size, (unsigned long)buf->mem);
+ 2714 :
+ 2715 : /* reset pointers and counters */
+ 2716 8 : ((int *)(buf->shm))[0] = 0; /* pointer to write memory */
+ 2717 8 : ((int *)(buf->shm))[1] = 0; /* pointer to read memory */
+ 2718 8 : ((int *)(buf->shm))[2] = 0; /* number of packets */
+ 2719 :
+ 2720 : /* clear memory */
+ 2721 8 : memset(buf->mem, 0, buf->size);
+ 2722 :
+ 2723 8 : return DLT_RETURN_OK; /* OK */
+ 2724 : }
+ 2725 :
+ 2726 7516 : DltReturnValue dlt_buffer_push(DltBuffer *buf, const unsigned char *data, unsigned int size)
+ 2727 : {
+ 2728 7516 : return dlt_buffer_push3(buf, data, size, 0, 0, 0, 0);
+ 2729 : }
+ 2730 :
+ 2731 9839 : int dlt_buffer_push3(DltBuffer *buf,
+ 2732 : const unsigned char *data1,
+ 2733 : unsigned int size1,
+ 2734 : const unsigned char *data2,
+ 2735 : unsigned int size2,
+ 2736 : const unsigned char *data3,
+ 2737 : unsigned int size3)
+ 2738 : {
+ 2739 : int free_size;
+ 2740 : int write, read, count;
+ 2741 : DltBufferBlockHead head;
+ 2742 :
+ 2743 : /* catch null pointer */
+ 2744 9839 : if (buf == NULL)
+ 2745 : return DLT_RETURN_WRONG_PARAMETER;
+ 2746 :
+ 2747 9771 : if (buf->shm == NULL) {
+ 2748 : /* buffer not initialised */
+ 2749 0 : dlt_vlog(LOG_ERR, "%s: Buffer: Buffer not initialized\n", __func__);
+ 2750 0 : return DLT_RETURN_ERROR; /* ERROR */
+ 2751 : }
+ 2752 :
+ 2753 : /* get current write pointer */
+ 2754 9771 : write = ((int *)(buf->shm))[0];
+ 2755 9771 : read = ((int *)(buf->shm))[1];
+ 2756 9771 : count = ((int *)(buf->shm))[2];
+ 2757 :
+ 2758 : /* check pointers */
+ 2759 9771 : if (((unsigned int)read > buf->size) || ((unsigned int)write > buf->size)) {
+ 2760 0 : dlt_vlog(LOG_ERR,
+ 2761 : "%s: Buffer: Pointer out of range. Read: %d, Write: %d, Size: %u\n",
+ 2762 : __func__, read, write, buf->size);
+ 2763 0 : dlt_buffer_reset(buf);
+ 2764 0 : return DLT_RETURN_ERROR; /* ERROR */
+ 2765 : }
+ 2766 :
+ 2767 : /* calculate free size */
+ 2768 9771 : if (read > write)
+ 2769 0 : free_size = read - write;
+ 2770 9771 : else if (count && (write == read))
+ 2771 : free_size = 0;
+ 2772 : else
+ 2773 9771 : free_size = (int)buf->size - write + read;
+ 2774 :
+ 2775 : /* check size */
+ 2776 9775 : while (free_size < (int) (sizeof(DltBufferBlockHead) + size1 + size2 + size3)) {
+ 2777 : /* try to increase size if possible */
+ 2778 4 : if (dlt_buffer_increase_size(buf))
+ 2779 : /* increase size is not possible */
+ 2780 : /*dlt_log(LOG_ERR, "Buffer: Buffer is full\n"); */
+ 2781 : return DLT_RETURN_ERROR; /* ERROR */
+ 2782 :
+ 2783 : /* update pointers */
+ 2784 4 : write = ((int *)(buf->shm))[0];
+ 2785 4 : read = ((int *)(buf->shm))[1];
+ 2786 :
+ 2787 : /* update free size */
+ 2788 4 : if (read > write)
+ 2789 0 : free_size = read - write;
+ 2790 4 : else if (count && (write == read))
+ 2791 : free_size = 0;
+ 2792 : else
+ 2793 4 : free_size = buf->size - write + read;
+ 2794 : }
+ 2795 :
+ 2796 : /* set header */
+ 2797 : strncpy(head.head, DLT_BUFFER_HEAD, 4);
+ 2798 : head.head[3] = 0;
+ 2799 9771 : head.status = 2;
+ 2800 9771 : head.size = (int)(size1 + size2 + size3);
+ 2801 :
+ 2802 : /* write data */
+ 2803 9771 : dlt_buffer_write_block(buf, &write, (unsigned char *)&head, sizeof(DltBufferBlockHead));
+ 2804 :
+ 2805 9771 : if (size1)
+ 2806 9771 : dlt_buffer_write_block(buf, &write, data1, size1);
+ 2807 :
+ 2808 9771 : if (size2)
+ 2809 2257 : dlt_buffer_write_block(buf, &write, data2, size2);
+ 2810 :
+ 2811 9771 : if (size3)
+ 2812 1873 : dlt_buffer_write_block(buf, &write, data3, size3);
+ 2813 :
+ 2814 : /* update global shm pointers */
+ 2815 9771 : ((int *)(buf->shm))[0] = write; /* set new write pointer */
+ 2816 9771 : ((int *)(buf->shm))[2] += 1; /* increase counter */
+ 2817 :
+ 2818 9771 : return DLT_RETURN_OK; /* OK */
+ 2819 :
+ 2820 : }
+ 2821 :
+ 2822 59 : int dlt_buffer_get(DltBuffer *buf, unsigned char *data, int max_size, int delete)
+ 2823 : {
+ 2824 : int used_size;
+ 2825 : int write, read, count;
+ 2826 59 : char head_compare[] = DLT_BUFFER_HEAD;
+ 2827 : DltBufferBlockHead head;
+ 2828 :
+ 2829 : /* catch null pointer */
+ 2830 59 : if (buf == NULL)
+ 2831 : return DLT_RETURN_WRONG_PARAMETER;
+ 2832 :
+ 2833 42 : if (buf->shm == NULL) {
+ 2834 : /* shm not initialised */
+ 2835 0 : dlt_vlog(LOG_ERR, "%s: Buffer: SHM not initialized\n", __func__);
+ 2836 0 : return DLT_RETURN_ERROR; /* ERROR */
+ 2837 : }
+ 2838 :
+ 2839 : /* get current write pointer */
+ 2840 42 : write = ((int *)(buf->shm))[0];
+ 2841 42 : read = ((int *)(buf->shm))[1];
+ 2842 42 : count = ((int *)(buf->shm))[2];
+ 2843 :
+ 2844 : /* check pointers */
+ 2845 42 : if (((unsigned int)read > buf->size) || ((unsigned int)write > buf->size) || (count < 0)) {
+ 2846 3 : dlt_vlog(LOG_ERR,
+ 2847 : "%s: Buffer: Pointer out of range. Read: %d, Write: %d, Count: %d, Size: %u\n",
+ 2848 : __func__, read, write, count, buf->size);
+ 2849 3 : dlt_buffer_reset(buf);
+ 2850 3 : return DLT_RETURN_ERROR; /* ERROR */
+ 2851 : }
+ 2852 :
+ 2853 : /* check if data is in there */
+ 2854 39 : if (count == 0) {
+ 2855 22 : if (write != read) {
+ 2856 1 : dlt_vlog(LOG_ERR,
+ 2857 : "%s: Buffer: SHM should be empty, but is not. Read: %d, Write: %d\n",
+ 2858 : __func__, read, write);
+ 2859 1 : dlt_buffer_reset(buf);
+ 2860 : }
+ 2861 :
+ 2862 22 : return DLT_RETURN_ERROR; /* ERROR */
+ 2863 : }
+ 2864 :
+ 2865 : /* calculate used size */
+ 2866 17 : if (write > read)
+ 2867 16 : used_size = write - read;
+ 2868 : else
+ 2869 1 : used_size = (int)buf->size - read + write;
+ 2870 :
+ 2871 : /* first check size */
+ 2872 17 : if (used_size < (int)(sizeof(DltBufferBlockHead))) {
+ 2873 1 : dlt_vlog(LOG_ERR,
+ 2874 : "%s: Buffer: Used size is smaller than buffer block header size. Used size: %d\n",
+ 2875 : __func__, used_size);
+ 2876 1 : dlt_buffer_reset(buf);
+ 2877 1 : return DLT_RETURN_ERROR; /* ERROR */
+ 2878 : }
+ 2879 :
+ 2880 : /* read header */
+ 2881 16 : dlt_buffer_read_block(buf, &read, (unsigned char *)&head, sizeof(DltBufferBlockHead));
+ 2882 :
+ 2883 : /* check header */
+ 2884 16 : if (memcmp((unsigned char *)(head.head), head_compare, sizeof(head_compare)) != 0) {
+ 2885 1 : dlt_vlog(LOG_ERR, "%s: Buffer: Header head check failed\n", __func__);
+ 2886 1 : dlt_buffer_reset(buf);
+ 2887 1 : return DLT_RETURN_ERROR; /* ERROR */
+ 2888 : }
+ 2889 :
+ 2890 15 : if (head.status != 2) {
+ 2891 0 : dlt_vlog(LOG_ERR, "%s: Buffer: Header status check failed\n", __func__);
+ 2892 0 : dlt_buffer_reset(buf);
+ 2893 0 : return DLT_RETURN_ERROR; /* ERROR */
+ 2894 : }
+ 2895 :
+ 2896 : /* second check size */
+ 2897 15 : if (used_size < ((int)sizeof(DltBufferBlockHead) + head.size)) {
+ 2898 1 : dlt_vlog(LOG_ERR,
+ 2899 : "%s: Buffer: Used size is smaller than buffer block header size And read header size. Used size: %d\n",
+ 2900 : __func__, used_size);
+ 2901 1 : dlt_buffer_reset(buf);
+ 2902 1 : return DLT_RETURN_ERROR; /* ERROR */
+ 2903 : }
+ 2904 :
+ 2905 : /* third check size */
+ 2906 14 : if (max_size && (head.size > max_size))
+ 2907 1 : dlt_vlog(LOG_WARNING,
+ 2908 : "%s: Buffer: Max size is smaller than read header size. Max size: %d\n",
+ 2909 : __func__, max_size);
+ 2910 :
+ 2911 : /* nothing to do but data does not fit provided buffer */
+ 2912 :
+ 2913 14 : if ((data != NULL) && max_size) {
+ 2914 : /* read data */
+ 2915 11 : dlt_buffer_read_block(buf, &read, data, (unsigned int)head.size);
+ 2916 :
+ 2917 11 : if (delete)
+ 2918 : /* update buffer pointers */
+ 2919 3 : ((int *)(buf->shm))[1] = read; /* set new read pointer */
+ 2920 :
+ 2921 : }
+ 2922 3 : else if (delete)
+ 2923 : {
+ 2924 3 : if ((unsigned int)(read + head.size) <= buf->size)
+ 2925 3 : ((int *)(buf->shm))[1] = read + head.size; /* set new read pointer */
+ 2926 : else
+ 2927 0 : ((int *)(buf->shm))[1] = read + head.size - (int)buf->size; /* set new read pointer */
+ 2928 :
+ 2929 : }
+ 2930 :
+ 2931 14 : if (delete) {
+ 2932 6 : ((int *)(buf->shm))[2] -= 1; /* decrease counter */
+ 2933 :
+ 2934 6 : if (((int *)(buf->shm))[2] == 0)
+ 2935 : /* try to minimize size */
+ 2936 4 : dlt_buffer_minimize_size(buf);
+ 2937 : }
+ 2938 :
+ 2939 14 : return head.size; /* OK */
+ 2940 : }
+ 2941 :
+ 2942 8 : int dlt_buffer_pull(DltBuffer *buf, unsigned char *data, int max_size)
+ 2943 : {
+ 2944 8 : return dlt_buffer_get(buf, data, max_size, 1);
+ 2945 : }
+ 2946 :
+ 2947 10 : int dlt_buffer_copy(DltBuffer *buf, unsigned char *data, int max_size)
+ 2948 : {
+ 2949 10 : return dlt_buffer_get(buf, data, max_size, 0);
+ 2950 : }
+ 2951 :
+ 2952 5 : int dlt_buffer_remove(DltBuffer *buf)
+ 2953 : {
+ 2954 5 : return dlt_buffer_get(buf, 0, 0, 1);
+ 2955 : }
+ 2956 :
+ 2957 2 : void dlt_buffer_info(DltBuffer *buf)
+ 2958 : {
+ 2959 : /* check nullpointer */
+ 2960 2 : if (buf == NULL) {
+ 2961 1 : dlt_vlog(LOG_WARNING, "%s: Wrong parameter: Null pointer\n", __func__);
+ 2962 1 : return;
+ 2963 : }
+ 2964 :
+ 2965 1 : dlt_vlog(LOG_DEBUG,
+ 2966 : "Buffer: Available size: %u, Buffer: Buffer full start address: %lX, Buffer: Buffer start address: %lX\n",
+ 2967 1 : buf->size, (unsigned long)buf->shm, (unsigned long)buf->mem);
+ 2968 : }
+ 2969 :
+ 2970 2 : void dlt_buffer_status(DltBuffer *buf)
+ 2971 : {
+ 2972 : int write, read, count;
+ 2973 :
+ 2974 : /* check nullpointer */
+ 2975 2 : if (buf == NULL) {
+ 2976 1 : dlt_vlog(LOG_WARNING, "%s: Wrong parameter: Null pointer\n", __func__);
+ 2977 1 : return;
+ 2978 : }
+ 2979 :
+ 2980 : /* check if buffer available */
+ 2981 1 : if (buf->shm == NULL)
+ 2982 : return;
+ 2983 :
+ 2984 1 : write = ((int *)(buf->shm))[0];
+ 2985 1 : read = ((int *)(buf->shm))[1];
+ 2986 1 : count = ((int *)(buf->shm))[2];
+ 2987 :
+ 2988 1 : dlt_vlog(LOG_DEBUG,
+ 2989 : "Buffer: Write: %d, Read: %d, Count: %d\n",
+ 2990 : write, read, count);
+ 2991 : }
+ 2992 :
+ 2993 3 : uint32_t dlt_buffer_get_total_size(DltBuffer *buf)
+ 2994 : {
+ 2995 : /* catch null pointer */
+ 2996 3 : if (buf == NULL)
+ 2997 : return DLT_RETURN_WRONG_PARAMETER;
+ 2998 :
+ 2999 2 : return buf->max_size;
+ 3000 : }
+ 3001 :
+ 3002 2503 : int dlt_buffer_get_used_size(DltBuffer *buf)
+ 3003 : {
+ 3004 : int write, read, count;
+ 3005 :
+ 3006 : /* catch null pointer */
+ 3007 2503 : if (buf == NULL)
+ 3008 : return DLT_RETURN_WRONG_PARAMETER;
+ 3009 :
+ 3010 : /* check if buffer available */
+ 3011 2502 : if (buf->shm == NULL)
+ 3012 : return DLT_RETURN_OK;
+ 3013 :
+ 3014 2502 : write = ((int *)(buf->shm))[0];
+ 3015 2502 : read = ((int *)(buf->shm))[1];
+ 3016 2502 : count = ((int *)(buf->shm))[2];
+ 3017 :
+ 3018 2502 : if (count == 0)
+ 3019 : return DLT_RETURN_OK;
+ 3020 :
+ 3021 2501 : if (write > read)
+ 3022 2501 : return write - read;
+ 3023 :
+ 3024 0 : return (int)buf->size - read + write;
+ 3025 : }
+ 3026 :
+ 3027 2672 : int dlt_buffer_get_message_count(DltBuffer *buf)
+ 3028 : {
+ 3029 : /* catch null pointer */
+ 3030 2672 : if (buf == NULL)
+ 3031 : return DLT_RETURN_WRONG_PARAMETER;
+ 3032 :
+ 3033 : /* check if buffer available */
+ 3034 2672 : if (buf->shm == NULL)
+ 3035 : return DLT_RETURN_OK;
+ 3036 :
+ 3037 2672 : return ((int *)(buf->shm))[2];
+ 3038 : }
+ 3039 :
+ 3040 : #if !defined (__WIN32__)
+ 3041 :
+ 3042 0 : DltReturnValue dlt_setup_serial(int fd, speed_t speed)
+ 3043 : {
+ 3044 : # if !defined (__WIN32__) && !defined(_MSC_VER)
+ 3045 : struct termios config;
+ 3046 :
+ 3047 0 : if (isatty(fd) == 0)
+ 3048 : return DLT_RETURN_ERROR;
+ 3049 :
+ 3050 0 : if (tcgetattr(fd, &config) < 0)
+ 3051 : return DLT_RETURN_ERROR;
+ 3052 :
+ 3053 : /* Input flags - Turn off input processing
+ 3054 : * convert break to null byte, no CR to NL translation,
+ 3055 : * no NL to CR translation, don't mark parity errors or breaks
+ 3056 : * no input parity check, don't strip high bit off,
+ 3057 : * no XON/XOFF software flow control
+ 3058 : */
+ 3059 0 : config.c_iflag &= ~(IGNBRK | BRKINT | ICRNL |
+ 3060 : INLCR | PARMRK | INPCK | ISTRIP | IXON);
+ 3061 :
+ 3062 : /* Output flags - Turn off output processing
+ 3063 : * no CR to NL translation, no NL to CR-NL translation,
+ 3064 : * no NL to CR translation, no column 0 CR suppression,
+ 3065 : * no Ctrl-D suppression, no fill characters, no case mapping,
+ 3066 : * no local output processing
+ 3067 : *
+ 3068 : * config.c_oflag &= ~(OCRNL | ONLCR | ONLRET |
+ 3069 : * ONOCR | ONOEOT| OFILL | OLCUC | OPOST);
+ 3070 : */
+ 3071 0 : config.c_oflag = 0;
+ 3072 :
+ 3073 : /* No line processing:
+ 3074 : * echo off, echo newline off, canonical mode off,
+ 3075 : * extended input processing off, signal chars off
+ 3076 : */
+ 3077 0 : config.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG);
+ 3078 :
+ 3079 : /* Turn off character processing
+ 3080 : * clear current char size mask, no parity checking,
+ 3081 : * no output processing, force 8 bit input
+ 3082 : */
+ 3083 0 : config.c_cflag &= ~(CSIZE | PARENB);
+ 3084 0 : config.c_cflag |= CS8;
+ 3085 :
+ 3086 : /* One input byte is enough to return from read()
+ 3087 : * Inter-character timer off
+ 3088 : */
+ 3089 0 : config.c_cc[VMIN] = 1;
+ 3090 0 : config.c_cc[VTIME] = 0;
+ 3091 :
+ 3092 : /* Communication speed (simple version, using the predefined
+ 3093 : * constants)
+ 3094 : */
+ 3095 0 : if ((cfsetispeed(&config, speed) < 0) || (cfsetospeed(&config, speed) < 0))
+ 3096 0 : return DLT_RETURN_ERROR;
+ 3097 :
+ 3098 : /* Finally, apply the configuration
+ 3099 : */
+ 3100 0 : if (tcsetattr(fd, TCSAFLUSH, &config) < 0)
+ 3101 0 : return DLT_RETURN_ERROR;
+ 3102 :
+ 3103 : return DLT_RETURN_OK;
+ 3104 : # else
+ 3105 : return DLT_RETURN_ERROR;
+ 3106 : # endif
+ 3107 : }
+ 3108 :
+ 3109 0 : speed_t dlt_convert_serial_speed(int baudrate)
+ 3110 : {
+ 3111 : # if !defined (__WIN32__) && !defined(_MSC_VER) && !defined(__CYGWIN__)
+ 3112 : speed_t ret;
+ 3113 :
+ 3114 0 : switch (baudrate) {
+ 3115 : case 50:
+ 3116 : {
+ 3117 : ret = B50;
+ 3118 : break;
+ 3119 : }
+ 3120 0 : case 75:
+ 3121 : {
+ 3122 : ret = B75;
+ 3123 0 : break;
+ 3124 : }
+ 3125 0 : case 110:
+ 3126 : {
+ 3127 : ret = B110;
+ 3128 0 : break;
+ 3129 : }
+ 3130 0 : case 134:
+ 3131 : {
+ 3132 : ret = B134;
+ 3133 0 : break;
+ 3134 : }
+ 3135 0 : case 150:
+ 3136 : {
+ 3137 : ret = B150;
+ 3138 0 : break;
+ 3139 : }
+ 3140 0 : case 200:
+ 3141 : {
+ 3142 : ret = B200;
+ 3143 0 : break;
+ 3144 : }
+ 3145 0 : case 300:
+ 3146 : {
+ 3147 : ret = B300;
+ 3148 0 : break;
+ 3149 : }
+ 3150 0 : case 600:
+ 3151 : {
+ 3152 : ret = B600;
+ 3153 0 : break;
+ 3154 : }
+ 3155 0 : case 1200:
+ 3156 : {
+ 3157 : ret = B1200;
+ 3158 0 : break;
+ 3159 : }
+ 3160 0 : case 1800:
+ 3161 : {
+ 3162 : ret = B1800;
+ 3163 0 : break;
+ 3164 : }
+ 3165 0 : case 2400:
+ 3166 : {
+ 3167 : ret = B2400;
+ 3168 0 : break;
+ 3169 : }
+ 3170 0 : case 4800:
+ 3171 : {
+ 3172 : ret = B4800;
+ 3173 0 : break;
+ 3174 : }
+ 3175 0 : case 9600:
+ 3176 : {
+ 3177 : ret = B9600;
+ 3178 0 : break;
+ 3179 : }
+ 3180 0 : case 19200:
+ 3181 : {
+ 3182 : ret = B19200;
+ 3183 0 : break;
+ 3184 : }
+ 3185 0 : case 38400:
+ 3186 : {
+ 3187 : ret = B38400;
+ 3188 0 : break;
+ 3189 : }
+ 3190 0 : case 57600:
+ 3191 : {
+ 3192 : ret = B57600;
+ 3193 0 : break;
+ 3194 : }
+ 3195 0 : case 115200:
+ 3196 : {
+ 3197 : ret = B115200;
+ 3198 0 : break;
+ 3199 : }
+ 3200 : # ifdef __linux__
+ 3201 0 : case 230400:
+ 3202 : {
+ 3203 : ret = B230400;
+ 3204 0 : break;
+ 3205 : }
+ 3206 0 : case 460800:
+ 3207 : {
+ 3208 : ret = B460800;
+ 3209 0 : break;
+ 3210 : }
+ 3211 0 : case 500000:
+ 3212 : {
+ 3213 : ret = B500000;
+ 3214 0 : break;
+ 3215 : }
+ 3216 0 : case 576000:
+ 3217 : {
+ 3218 : ret = B576000;
+ 3219 0 : break;
+ 3220 : }
+ 3221 0 : case 921600:
+ 3222 : {
+ 3223 : ret = B921600;
+ 3224 0 : break;
+ 3225 : }
+ 3226 0 : case 1000000:
+ 3227 : {
+ 3228 : ret = B1000000;
+ 3229 0 : break;
+ 3230 : }
+ 3231 0 : case 1152000:
+ 3232 : {
+ 3233 : ret = B1152000;
+ 3234 0 : break;
+ 3235 : }
+ 3236 0 : case 1500000:
+ 3237 : {
+ 3238 : ret = B1500000;
+ 3239 0 : break;
+ 3240 : }
+ 3241 0 : case 2000000:
+ 3242 : {
+ 3243 : ret = B2000000;
+ 3244 0 : break;
+ 3245 : }
+ 3246 0 : case 2500000:
+ 3247 : {
+ 3248 : ret = B2500000;
+ 3249 0 : break;
+ 3250 : }
+ 3251 0 : case 3000000:
+ 3252 : {
+ 3253 : ret = B3000000;
+ 3254 0 : break;
+ 3255 : }
+ 3256 0 : case 3500000:
+ 3257 : {
+ 3258 : ret = B3500000;
+ 3259 0 : break;
+ 3260 : }
+ 3261 0 : case 4000000:
+ 3262 : {
+ 3263 : ret = B4000000;
+ 3264 0 : break;
+ 3265 : }
+ 3266 : # endif /* __linux__ */
+ 3267 0 : default:
+ 3268 : {
+ 3269 : ret = B115200;
+ 3270 0 : break;
+ 3271 : }
+ 3272 : }
+ 3273 :
+ 3274 0 : return ret;
+ 3275 : # else
+ 3276 : return 0;
+ 3277 : # endif
+ 3278 : }
+ 3279 :
+ 3280 : #endif
+ 3281 :
+ 3282 6 : void dlt_get_version(char *buf, size_t size)
+ 3283 : {
+ 3284 6 : if ((buf == NULL) && (size > 0)) {
+ 3285 0 : dlt_log(LOG_WARNING, "Wrong parameter: Null pointer\n");
+ 3286 0 : return;
+ 3287 : }
+ 3288 :
+ 3289 : /* Clang does not like these macros, because they are not reproducable */
+ 3290 : #pragma GCC diagnostic push
+ 3291 : #pragma GCC diagnostic ignored "-Wdate-time"
+ 3292 : snprintf(buf,
+ 3293 : size,
+ 3294 : "DLT Package Version: %s %s, Package Revision: %s, build on %s %s\n%s %s %s %s\n",
+ 3295 : _DLT_PACKAGE_VERSION,
+ 3296 : _DLT_PACKAGE_VERSION_STATE,
+ 3297 : _DLT_PACKAGE_REVISION,
+ 3298 : __DATE__,
+ 3299 : __TIME__,
+ 3300 : _DLT_SYSTEMD_ENABLE,
+ 3301 : _DLT_SYSTEMD_WATCHDOG_ENABLE,
+ 3302 : _DLT_TEST_ENABLE,
+ 3303 : _DLT_SHM_ENABLE);
+ 3304 : #pragma GCC diagnostic pop
+ 3305 : }
+ 3306 :
+ 3307 2 : void dlt_get_major_version(char *buf, size_t size)
+ 3308 : {
+ 3309 2 : if ((buf == NULL) && (size > 0)) {
+ 3310 0 : dlt_log(LOG_WARNING, "Wrong parameter: Null pointer\n");
+ 3311 0 : return;
+ 3312 : }
+ 3313 :
+ 3314 : snprintf(buf, size, "%s", _DLT_PACKAGE_MAJOR_VERSION);
+ 3315 : }
+ 3316 :
+ 3317 2 : void dlt_get_minor_version(char *buf, size_t size)
+ 3318 : {
+ 3319 2 : if ((buf == NULL) && (size > 0)) {
+ 3320 0 : dlt_log(LOG_WARNING, "Wrong parameter: Null pointer\n");
+ 3321 0 : return;
+ 3322 : }
+ 3323 :
+ 3324 : snprintf(buf, size, "%s", _DLT_PACKAGE_MINOR_VERSION);
+ 3325 : }
+ 3326 :
+ 3327 :
+ 3328 247 : uint32_t dlt_uptime(void)
+ 3329 : {
+ 3330 :
+ 3331 : #if defined (__WIN32__) || defined(_MSC_VER)
+ 3332 :
+ 3333 : return (uint32_t)(GetTickCount() * 10); /* GetTickCount() return DWORD */
+ 3334 :
+ 3335 : #else
+ 3336 : struct timespec ts;
+ 3337 :
+ 3338 247 : if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0)
+ 3339 247 : return (uint32_t)ts.tv_sec * 10000 + (uint32_t)ts.tv_nsec / 100000; /* in 0.1 ms = 100 us */
+ 3340 : else
+ 3341 : return 0;
+ 3342 :
+ 3343 : #endif
+ 3344 :
+ 3345 : }
+ 3346 :
+ 3347 328 : DltReturnValue dlt_message_print_header(DltMessage *message, char *text, uint32_t size, int verbose)
+ 3348 : {
+ 3349 328 : if ((message == NULL) || (text == NULL))
+ 3350 : return DLT_RETURN_WRONG_PARAMETER;
+ 3351 :
+ 3352 316 : if (dlt_message_header(message, text, size, verbose) < DLT_RETURN_OK)
+ 3353 : return DLT_RETURN_ERROR;
+ 3354 316 : dlt_user_printf("%s\n", text);
+ 3355 :
+ 3356 316 : return DLT_RETURN_OK;
+ 3357 : }
+ 3358 :
+ 3359 328 : DltReturnValue dlt_message_print_hex(DltMessage *message, char *text, uint32_t size, int verbose)
+ 3360 : {
+ 3361 328 : if ((message == NULL) || (text == NULL))
+ 3362 : return DLT_RETURN_WRONG_PARAMETER;
+ 3363 :
+ 3364 316 : if (dlt_message_header(message, text, size, verbose) < DLT_RETURN_OK)
+ 3365 : return DLT_RETURN_ERROR;
+ 3366 316 : dlt_user_printf("%s ", text);
+ 3367 :
+ 3368 316 : if (dlt_message_payload(message, text, size, DLT_OUTPUT_HEX, verbose) < DLT_RETURN_OK)
+ 3369 : return DLT_RETURN_ERROR;
+ 3370 316 : dlt_user_printf("[%s]\n", text);
+ 3371 :
+ 3372 316 : return DLT_RETURN_OK;
+ 3373 : }
+ 3374 :
+ 3375 328 : DltReturnValue dlt_message_print_ascii(DltMessage *message, char *text, uint32_t size, int verbose)
+ 3376 : {
+ 3377 328 : if ((message == NULL) || (text == NULL))
+ 3378 : return DLT_RETURN_WRONG_PARAMETER;
+ 3379 :
+ 3380 316 : if (dlt_message_header(message, text, size, verbose) < DLT_RETURN_OK)
+ 3381 : return DLT_RETURN_ERROR;
+ 3382 316 : dlt_user_printf("%s ", text);
+ 3383 :
+ 3384 316 : if (dlt_message_payload(message, text, size, DLT_OUTPUT_ASCII, verbose) < DLT_RETURN_OK)
+ 3385 : return DLT_RETURN_ERROR;
+ 3386 316 : dlt_user_printf("[%s]\n", text);
+ 3387 :
+ 3388 316 : return DLT_RETURN_OK;
+ 3389 : }
+ 3390 :
+ 3391 328 : DltReturnValue dlt_message_print_mixed_plain(DltMessage *message, char *text, uint32_t size, int verbose)
+ 3392 : {
+ 3393 328 : if ((message == NULL) || (text == NULL))
+ 3394 : return DLT_RETURN_WRONG_PARAMETER;
+ 3395 :
+ 3396 316 : if (dlt_message_header(message, text, size, verbose) < DLT_RETURN_OK)
+ 3397 : return DLT_RETURN_ERROR;
+ 3398 316 : dlt_user_printf("%s \n", text);
+ 3399 :
+ 3400 316 : if (dlt_message_payload(message, text, size, DLT_OUTPUT_MIXED_FOR_PLAIN, verbose) < DLT_RETURN_OK)
+ 3401 : return DLT_RETURN_ERROR;
+ 3402 316 : dlt_user_printf("[%s]\n", text);
+ 3403 :
+ 3404 316 : return DLT_RETURN_OK;
+ 3405 : }
+ 3406 :
+ 3407 328 : DltReturnValue dlt_message_print_mixed_html(DltMessage *message, char *text, uint32_t size, int verbose)
+ 3408 : {
+ 3409 328 : if ((message == NULL) || (text == NULL))
+ 3410 : return DLT_RETURN_WRONG_PARAMETER;
+ 3411 :
+ 3412 316 : if (dlt_message_header(message, text, size, verbose) < DLT_RETURN_OK)
+ 3413 : return DLT_RETURN_ERROR;
+ 3414 316 : dlt_user_printf("%s \n", text);
+ 3415 :
+ 3416 316 : if (dlt_message_payload(message, text, size, DLT_OUTPUT_MIXED_FOR_HTML, verbose) < DLT_RETURN_OK)
+ 3417 : return DLT_RETURN_ERROR;
+ 3418 :
+ 3419 316 : dlt_user_printf("[%s]\n", text);
+ 3420 :
+ 3421 316 : return DLT_RETURN_OK;
+ 3422 : }
+ 3423 :
+ 3424 751 : DltReturnValue dlt_message_argument_print(DltMessage *msg,
+ 3425 : uint32_t type_info,
+ 3426 : uint8_t **ptr,
+ 3427 : int32_t *datalength,
+ 3428 : char *text,
+ 3429 : size_t textlength,
+ 3430 : int byteLength,
+ 3431 : int __attribute__((unused)) verbose)
+ 3432 : {
+ 3433 : /* check null pointers */
+ 3434 751 : if ((msg == NULL) || (ptr == NULL) || (datalength == NULL) || (text == NULL))
+ 3435 : return DLT_RETURN_WRONG_PARAMETER;
+ 3436 :
+ 3437 : uint16_t length = 0, length2 = 0, length3 = 0;
+ 3438 :
+ 3439 : uint8_t value8u = 0;
+ 3440 : uint16_t value16u = 0, value16u_tmp = 0;
+ 3441 : uint32_t value32u = 0, value32u_tmp = 0;
+ 3442 : uint64_t value64u = 0, value64u_tmp = 0;
+ 3443 :
+ 3444 : int8_t value8i = 0;
+ 3445 : int16_t value16i = 0, value16i_tmp = 0;
+ 3446 : int32_t value32i = 0, value32i_tmp = 0;
+ 3447 : int64_t value64i = 0, value64i_tmp = 0;
+ 3448 :
+ 3449 736 : float32_t value32f = 0, value32f_tmp = 0;
+ 3450 736 : int32_t value32f_tmp_int32i = 0, value32f_tmp_int32i_swaped = 0;
+ 3451 736 : float64_t value64f = 0, value64f_tmp = 0;
+ 3452 736 : int64_t value64f_tmp_int64i = 0, value64f_tmp_int64i_swaped = 0;
+ 3453 :
+ 3454 : uint32_t quantisation_tmp = 0;
+ 3455 :
+ 3456 : // pointer to the value string
+ 3457 : char* value_text = text;
+ 3458 : // pointer to the "unit" attribute string, if there is one (only for *INT and FLOAT*)
+ 3459 : const uint8_t* unit_text_src = NULL;
+ 3460 : // length of the "unit" attribute string, if there is one (only for *INT and FLOAT*)
+ 3461 : size_t unit_text_len = 0;
+ 3462 :
+ 3463 : /* apparently this makes no sense but needs to be done to prevent compiler warning.
+ 3464 : * This variable is only written by DLT_MSG_READ_VALUE macro in if (type_info & DLT_TYPE_INFO_FIXP)
+ 3465 : * case but never read anywhere */
+ 3466 : quantisation_tmp += quantisation_tmp;
+ 3467 :
+ 3468 736 : if ((type_info & DLT_TYPE_INFO_STRG) &&
+ 3469 147 : (((type_info & DLT_TYPE_INFO_SCOD) == DLT_SCOD_ASCII) || ((type_info & DLT_TYPE_INFO_SCOD) == DLT_SCOD_UTF8))) {
+ 3470 : /* string type or utf8-encoded string type */
+ 3471 147 : if (byteLength < 0) {
+ 3472 147 : DLT_MSG_READ_VALUE(value16u_tmp, *ptr, *datalength, uint16_t);
+ 3473 :
+ 3474 147 : if ((*datalength) < 0)
+ 3475 : return DLT_RETURN_ERROR;
+ 3476 :
+ 3477 147 : length = (uint16_t) DLT_ENDIAN_GET_16(msg->standardheader->htyp, value16u_tmp);
+ 3478 : }
+ 3479 : else {
+ 3480 0 : length = (uint16_t)byteLength;
+ 3481 : }
+ 3482 :
+ 3483 147 : if (type_info & DLT_TYPE_INFO_VARI) {
+ 3484 0 : DLT_MSG_READ_VALUE(value16u_tmp, *ptr, *datalength, uint16_t);
+ 3485 :
+ 3486 0 : if ((*datalength) < 0)
+ 3487 : return DLT_RETURN_ERROR;
+ 3488 :
+ 3489 0 : length2 = (uint16_t) DLT_ENDIAN_GET_16(msg->standardheader->htyp, value16u_tmp);
+ 3490 :
+ 3491 0 : if ((*datalength) < length2)
+ 3492 : return DLT_RETURN_ERROR;
+ 3493 :
+ 3494 0 : if (print_with_attributes) {
+ 3495 : // Print "name" attribute, if we have one with non-zero size.
+ 3496 0 : if (length2 > 1) {
+ 3497 0 : snprintf(text, textlength, "%s:", *ptr);
+ 3498 0 : value_text += length2+1-1; // +1 for ":" and -1 for NUL
+ 3499 0 : textlength -= length2+1-1;
+ 3500 : }
+ 3501 : }
+ 3502 :
+ 3503 0 : *ptr += length2;
+ 3504 0 : *datalength -= length2;
+ 3505 : }
+ 3506 :
+ 3507 147 : DLT_MSG_READ_STRING(value_text, *ptr, *datalength, textlength, length);
+ 3508 :
+ 3509 147 : if ((*datalength) < 0)
+ 3510 : return DLT_RETURN_ERROR;
+ 3511 : }
+ 3512 589 : else if (type_info & DLT_TYPE_INFO_BOOL)
+ 3513 : {
+ 3514 : /* Boolean type */
+ 3515 112 : if (type_info & DLT_TYPE_INFO_VARI) {
+ 3516 0 : DLT_MSG_READ_VALUE(value16u_tmp, *ptr, *datalength, uint16_t);
+ 3517 :
+ 3518 0 : if ((*datalength) < 0)
+ 3519 : return DLT_RETURN_ERROR;
+ 3520 :
+ 3521 0 : length2 = (uint16_t) DLT_ENDIAN_GET_16(msg->standardheader->htyp, value16u_tmp);
+ 3522 :
+ 3523 0 : if ((*datalength) < length2)
+ 3524 : return DLT_RETURN_ERROR;
+ 3525 :
+ 3526 0 : if (print_with_attributes) {
+ 3527 : // Print "name" attribute, if we have one with non-zero size.
+ 3528 0 : if (length2 > 1) {
+ 3529 0 : snprintf(text, textlength, "%s:", *ptr);
+ 3530 0 : value_text += length2+1-1; // +1 for ":" and -1 for NUL
+ 3531 0 : textlength -= length2+1-2;
+ 3532 : }
+ 3533 : }
+ 3534 :
+ 3535 0 : *ptr += length2;
+ 3536 0 : *datalength -= length2;
+ 3537 : }
+ 3538 :
+ 3539 : value8u = 0;
+ 3540 112 : DLT_MSG_READ_VALUE(value8u, *ptr, *datalength, uint8_t); /* No endian conversion necessary */
+ 3541 :
+ 3542 112 : if ((*datalength) < 0)
+ 3543 : return DLT_RETURN_ERROR;
+ 3544 :
+ 3545 110 : snprintf(value_text, textlength, "%d", value8u);
+ 3546 : }
+ 3547 477 : else if ((type_info & DLT_TYPE_INFO_UINT) && (DLT_SCOD_BIN == (type_info & DLT_TYPE_INFO_SCOD)))
+ 3548 : {
+ 3549 0 : if (DLT_TYLE_8BIT == (type_info & DLT_TYPE_INFO_TYLE)) {
+ 3550 0 : DLT_MSG_READ_VALUE(value8u, *ptr, *datalength, uint8_t); /* No endian conversion necessary */
+ 3551 :
+ 3552 0 : if ((*datalength) < 0)
+ 3553 0 : return DLT_RETURN_ERROR;
+ 3554 :
+ 3555 0 : char binary[10] = { '\0' }; /* e.g.: "0b1100 0010" */
+ 3556 : int i;
+ 3557 :
+ 3558 0 : for (i = (1 << 7); i > 0; i >>= 1) {
+ 3559 0 : if ((1 << 3) == i)
+ 3560 : strcat(binary, " ");
+ 3561 :
+ 3562 0 : strcat(binary, (i == (value8u & i)) ? "1" : "0");
+ 3563 : }
+ 3564 :
+ 3565 : snprintf(value_text, textlength, "0b%s", binary);
+ 3566 : }
+ 3567 :
+ 3568 0 : if (DLT_TYLE_16BIT == (type_info & DLT_TYPE_INFO_TYLE)) {
+ 3569 0 : DLT_MSG_READ_VALUE(value16u, *ptr, *datalength, uint16_t);
+ 3570 :
+ 3571 0 : if ((*datalength) < 0)
+ 3572 0 : return DLT_RETURN_ERROR;
+ 3573 :
+ 3574 0 : char binary[20] = { '\0' }; /* e.g.: "0b1100 0010 0011 0110" */
+ 3575 : int i;
+ 3576 :
+ 3577 0 : for (i = (1 << 15); i > 0; i >>= 1) {
+ 3578 0 : if (((1 << 3) == i) || ((1 << 7) == i) || ((1 << 11) == i))
+ 3579 : strcat(binary, " ");
+ 3580 :
+ 3581 0 : strcat(binary, (i == (value16u & i)) ? "1" : "0");
+ 3582 : }
+ 3583 :
+ 3584 : snprintf(value_text, textlength, "0b%s", binary);
+ 3585 : }
+ 3586 : }
+ 3587 477 : else if ((type_info & DLT_TYPE_INFO_UINT) && (DLT_SCOD_HEX == (type_info & DLT_TYPE_INFO_SCOD)))
+ 3588 : {
+ 3589 0 : if (DLT_TYLE_8BIT == (type_info & DLT_TYPE_INFO_TYLE)) {
+ 3590 0 : DLT_MSG_READ_VALUE(value8u, *ptr, *datalength, uint8_t); /* No endian conversion necessary */
+ 3591 :
+ 3592 0 : if ((*datalength) < 0)
+ 3593 : return DLT_RETURN_ERROR;
+ 3594 :
+ 3595 0 : snprintf(value_text, textlength, "0x%02x", value8u);
+ 3596 : }
+ 3597 :
+ 3598 0 : if (DLT_TYLE_16BIT == (type_info & DLT_TYPE_INFO_TYLE)) {
+ 3599 0 : DLT_MSG_READ_VALUE(value16u, *ptr, *datalength, uint16_t);
+ 3600 :
+ 3601 0 : if ((*datalength) < 0)
+ 3602 : return DLT_RETURN_ERROR;
+ 3603 :
+ 3604 0 : snprintf(value_text, textlength, "0x%04x", value16u);
+ 3605 : }
+ 3606 :
+ 3607 0 : if (DLT_TYLE_32BIT == (type_info & DLT_TYPE_INFO_TYLE)) {
+ 3608 0 : DLT_MSG_READ_VALUE(value32u, *ptr, *datalength, uint32_t);
+ 3609 :
+ 3610 0 : if ((*datalength) < 0)
+ 3611 : return DLT_RETURN_ERROR;
+ 3612 :
+ 3613 : snprintf(value_text, textlength, "0x%08x", value32u);
+ 3614 : }
+ 3615 :
+ 3616 0 : if (DLT_TYLE_64BIT == (type_info & DLT_TYPE_INFO_TYLE)) {
+ 3617 0 : *ptr += 4;
+ 3618 0 : DLT_MSG_READ_VALUE(value32u, *ptr, *datalength, uint32_t);
+ 3619 :
+ 3620 0 : if ((*datalength) < 0)
+ 3621 : return DLT_RETURN_ERROR;
+ 3622 :
+ 3623 : snprintf(value_text, textlength, "0x%08x", value32u);
+ 3624 0 : *ptr -= 8;
+ 3625 0 : DLT_MSG_READ_VALUE(value32u, *ptr, *datalength, uint32_t);
+ 3626 :
+ 3627 0 : if ((*datalength) < 0)
+ 3628 : return DLT_RETURN_ERROR;
+ 3629 :
+ 3630 0 : snprintf(value_text + strlen(value_text), textlength - strlen(value_text), "%08x", value32u);
+ 3631 0 : *ptr += 4;
+ 3632 : }
+ 3633 : }
+ 3634 477 : else if ((type_info & DLT_TYPE_INFO_SINT) || (type_info & DLT_TYPE_INFO_UINT))
+ 3635 : {
+ 3636 : /* signed or unsigned argument received */
+ 3637 350 : if (type_info & DLT_TYPE_INFO_VARI) {
+ 3638 0 : DLT_MSG_READ_VALUE(value16u_tmp, *ptr, *datalength, uint16_t);
+ 3639 :
+ 3640 0 : if ((*datalength) < 0)
+ 3641 : return DLT_RETURN_ERROR;
+ 3642 :
+ 3643 0 : length2 = (uint16_t) DLT_ENDIAN_GET_16(msg->standardheader->htyp, value16u_tmp);
+ 3644 0 : DLT_MSG_READ_VALUE(value16u_tmp, *ptr, *datalength, uint16_t);
+ 3645 :
+ 3646 0 : if ((*datalength) < 0)
+ 3647 : return DLT_RETURN_ERROR;
+ 3648 :
+ 3649 0 : length3 = (uint16_t) DLT_ENDIAN_GET_16(msg->standardheader->htyp, value16u_tmp);
+ 3650 :
+ 3651 0 : if ((*datalength) < length2)
+ 3652 : return DLT_RETURN_ERROR;
+ 3653 :
+ 3654 0 : if (print_with_attributes) {
+ 3655 : // Print "name" attribute, if we have one with non-zero size.
+ 3656 0 : if (length2 > 1) {
+ 3657 0 : snprintf(text, textlength, "%s:", *ptr);
+ 3658 0 : value_text += length2+1-1; // +1 for the ":", and -1 for nul
+ 3659 0 : textlength -= length2+1-1;
+ 3660 : }
+ 3661 : }
+ 3662 :
+ 3663 0 : *ptr += length2;
+ 3664 0 : *datalength -= length2;
+ 3665 :
+ 3666 0 : if ((*datalength) < length3)
+ 3667 : return DLT_RETURN_ERROR;
+ 3668 :
+ 3669 : // We want to add the "unit" attribute only after the value, so remember its pointer and length here.
+ 3670 : unit_text_src = *ptr;
+ 3671 0 : unit_text_len = length3;
+ 3672 :
+ 3673 0 : *ptr += length3;
+ 3674 0 : *datalength -= length3;
+ 3675 : }
+ 3676 :
+ 3677 350 : if (type_info & DLT_TYPE_INFO_FIXP) {
+ 3678 0 : DLT_MSG_READ_VALUE(quantisation_tmp, *ptr, *datalength, uint32_t);
+ 3679 :
+ 3680 0 : if ((*datalength) < 0)
+ 3681 : return DLT_RETURN_ERROR;
+ 3682 :
+ 3683 0 : switch (type_info & DLT_TYPE_INFO_TYLE) {
+ 3684 0 : case DLT_TYLE_8BIT:
+ 3685 : case DLT_TYLE_16BIT:
+ 3686 : case DLT_TYLE_32BIT:
+ 3687 : {
+ 3688 0 : if ((*datalength) < 4)
+ 3689 : return DLT_RETURN_ERROR;
+ 3690 :
+ 3691 0 : *ptr += 4;
+ 3692 0 : *datalength -= 4;
+ 3693 0 : break;
+ 3694 : }
+ 3695 0 : case DLT_TYLE_64BIT:
+ 3696 : {
+ 3697 0 : if ((*datalength) < 8)
+ 3698 : return DLT_RETURN_ERROR;
+ 3699 :
+ 3700 0 : *ptr += 8;
+ 3701 0 : *datalength -= 8;
+ 3702 0 : break;
+ 3703 : }
+ 3704 0 : case DLT_TYLE_128BIT:
+ 3705 : {
+ 3706 0 : if ((*datalength) < 16)
+ 3707 : return DLT_RETURN_ERROR;
+ 3708 :
+ 3709 0 : *ptr += 16;
+ 3710 0 : *datalength -= 16;
+ 3711 0 : break;
+ 3712 : }
+ 3713 : default:
+ 3714 : {
+ 3715 : return DLT_RETURN_ERROR;
+ 3716 : }
+ 3717 : }
+ 3718 : }
+ 3719 :
+ 3720 350 : switch (type_info & DLT_TYPE_INFO_TYLE) {
+ 3721 14 : case DLT_TYLE_8BIT:
+ 3722 : {
+ 3723 14 : if (type_info & DLT_TYPE_INFO_SINT) {
+ 3724 : value8i = 0;
+ 3725 7 : DLT_MSG_READ_VALUE(value8i, *ptr, *datalength, int8_t); /* No endian conversion necessary */
+ 3726 :
+ 3727 7 : if ((*datalength) < 0)
+ 3728 : return DLT_RETURN_ERROR;
+ 3729 :
+ 3730 7 : snprintf(value_text, textlength, "%d", value8i);
+ 3731 : }
+ 3732 : else {
+ 3733 : value8u = 0;
+ 3734 7 : DLT_MSG_READ_VALUE(value8u, *ptr, *datalength, uint8_t); /* No endian conversion necessary */
+ 3735 :
+ 3736 7 : if ((*datalength) < 0)
+ 3737 : return DLT_RETURN_ERROR;
+ 3738 :
+ 3739 7 : snprintf(value_text, textlength, "%d", value8u);
+ 3740 : }
+ 3741 :
+ 3742 : break;
+ 3743 : }
+ 3744 21 : case DLT_TYLE_16BIT:
+ 3745 : {
+ 3746 21 : if (type_info & DLT_TYPE_INFO_SINT) {
+ 3747 : value16i = 0;
+ 3748 : value16i_tmp = 0;
+ 3749 7 : DLT_MSG_READ_VALUE(value16i_tmp, *ptr, *datalength, int16_t);
+ 3750 :
+ 3751 7 : if ((*datalength) < 0)
+ 3752 : return DLT_RETURN_ERROR;
+ 3753 :
+ 3754 7 : value16i = (int16_t) DLT_ENDIAN_GET_16(msg->standardheader->htyp, value16i_tmp);
+ 3755 7 : snprintf(value_text, textlength, "%hd", value16i);
+ 3756 : }
+ 3757 : else {
+ 3758 : value16u = 0;
+ 3759 : value16u_tmp = 0;
+ 3760 14 : DLT_MSG_READ_VALUE(value16u_tmp, *ptr, *datalength, uint16_t);
+ 3761 :
+ 3762 14 : if ((*datalength) < 0)
+ 3763 : return DLT_RETURN_ERROR;
+ 3764 :
+ 3765 14 : value16u = (uint16_t) DLT_ENDIAN_GET_16(msg->standardheader->htyp, value16u_tmp);
+ 3766 14 : snprintf(value_text, textlength, "%hu", value16u);
+ 3767 : }
+ 3768 :
+ 3769 : break;
+ 3770 : }
+ 3771 301 : case DLT_TYLE_32BIT:
+ 3772 : {
+ 3773 301 : if (type_info & DLT_TYPE_INFO_SINT) {
+ 3774 : value32i = 0;
+ 3775 : value32i_tmp = 0;
+ 3776 287 : DLT_MSG_READ_VALUE(value32i_tmp, *ptr, *datalength, int32_t);
+ 3777 :
+ 3778 287 : if ((*datalength) < 0)
+ 3779 : return DLT_RETURN_ERROR;
+ 3780 :
+ 3781 287 : value32i = (int32_t) DLT_ENDIAN_GET_32(msg->standardheader->htyp, (uint32_t)value32i_tmp);
+ 3782 : snprintf(value_text, textlength, "%d", value32i);
+ 3783 : }
+ 3784 : else {
+ 3785 : value32u = 0;
+ 3786 : value32u_tmp = 0;
+ 3787 14 : DLT_MSG_READ_VALUE(value32u_tmp, *ptr, *datalength, uint32_t);
+ 3788 :
+ 3789 14 : if ((*datalength) < 0)
+ 3790 : return DLT_RETURN_ERROR;
+ 3791 :
+ 3792 14 : value32u = DLT_ENDIAN_GET_32(msg->standardheader->htyp, value32u_tmp);
+ 3793 : snprintf(value_text, textlength, "%u", value32u);
+ 3794 : }
+ 3795 :
+ 3796 : break;
+ 3797 : }
+ 3798 14 : case DLT_TYLE_64BIT:
+ 3799 : {
+ 3800 14 : if (type_info & DLT_TYPE_INFO_SINT) {
+ 3801 : value64i = 0;
+ 3802 : value64i_tmp = 0;
+ 3803 7 : DLT_MSG_READ_VALUE(value64i_tmp, *ptr, *datalength, int64_t);
+ 3804 :
+ 3805 7 : if ((*datalength) < 0)
+ 3806 : return DLT_RETURN_ERROR;
+ 3807 :
+ 3808 7 : value64i = (int64_t) DLT_ENDIAN_GET_64(msg->standardheader->htyp, (uint64_t)value64i_tmp);
+ 3809 : #if defined (__WIN32__) && !defined(_MSC_VER)
+ 3810 : snprintf(value_text, textlength, "%I64d", value64i);
+ 3811 : #else
+ 3812 : snprintf(value_text, textlength, "%" PRId64, value64i);
+ 3813 : #endif
+ 3814 : }
+ 3815 : else {
+ 3816 : value64u = 0;
+ 3817 : value64u_tmp = 0;
+ 3818 7 : DLT_MSG_READ_VALUE(value64u_tmp, *ptr, *datalength, uint64_t);
+ 3819 :
+ 3820 7 : if ((*datalength) < 0)
+ 3821 : return DLT_RETURN_ERROR;
+ 3822 :
+ 3823 7 : value64u = DLT_ENDIAN_GET_64(msg->standardheader->htyp, value64u_tmp);
+ 3824 : #if defined (__WIN32__) && !defined(_MSC_VER)
+ 3825 : snprintf(value_text, textlength, "%I64u", value64u);
+ 3826 : #else
+ 3827 : snprintf(value_text, textlength, "%" PRIu64, value64u);
+ 3828 : #endif
+ 3829 : }
+ 3830 :
+ 3831 : break;
+ 3832 : }
+ 3833 0 : case DLT_TYLE_128BIT:
+ 3834 : {
+ 3835 0 : if (*datalength >= 16)
+ 3836 0 : dlt_print_hex_string(value_text, (int) textlength, *ptr, 16);
+ 3837 :
+ 3838 0 : if ((*datalength) < 16)
+ 3839 : return DLT_RETURN_ERROR;
+ 3840 :
+ 3841 0 : *ptr += 16;
+ 3842 0 : *datalength -= 16;
+ 3843 0 : break;
+ 3844 : }
+ 3845 : default:
+ 3846 : {
+ 3847 : return DLT_RETURN_ERROR;
+ 3848 : }
+ 3849 : }
+ 3850 : }
+ 3851 127 : else if (type_info & DLT_TYPE_INFO_FLOA)
+ 3852 : {
+ 3853 : /* float data argument */
+ 3854 14 : if (type_info & DLT_TYPE_INFO_VARI) {
+ 3855 0 : DLT_MSG_READ_VALUE(value16u_tmp, *ptr, *datalength, uint16_t);
+ 3856 :
+ 3857 0 : if ((*datalength) < 0)
+ 3858 : return DLT_RETURN_ERROR;
+ 3859 :
+ 3860 0 : length2 = DLT_ENDIAN_GET_16(msg->standardheader->htyp, value16u_tmp);
+ 3861 0 : DLT_MSG_READ_VALUE(value16u_tmp, *ptr, *datalength, uint16_t);
+ 3862 :
+ 3863 0 : if ((*datalength) < 0)
+ 3864 : return DLT_RETURN_ERROR;
+ 3865 :
+ 3866 0 : length3 = DLT_ENDIAN_GET_16(msg->standardheader->htyp, value16u_tmp);
+ 3867 :
+ 3868 0 : if ((*datalength) < length2)
+ 3869 : return DLT_RETURN_ERROR;
+ 3870 :
+ 3871 0 : if (print_with_attributes) {
+ 3872 : // Print "name" attribute, if we have one with non-zero size.
+ 3873 0 : if (length2 > 1) {
+ 3874 0 : snprintf(text, textlength, "%s:", *ptr);
+ 3875 0 : value_text += length2+1-1; // +1 for ":" and -1 for NUL
+ 3876 0 : textlength -= length2+1-1;
+ 3877 : }
+ 3878 : }
+ 3879 :
+ 3880 0 : *ptr += length2;
+ 3881 0 : *datalength -= length2;
+ 3882 :
+ 3883 0 : if ((*datalength) < length3)
+ 3884 : return DLT_RETURN_ERROR;
+ 3885 :
+ 3886 : // We want to add the "unit" attribute only after the value, so remember its pointer and length here.
+ 3887 : unit_text_src = *ptr;
+ 3888 0 : unit_text_len = length3;
+ 3889 :
+ 3890 0 : *ptr += length3;
+ 3891 0 : *datalength -= length3;
+ 3892 : }
+ 3893 :
+ 3894 14 : switch (type_info & DLT_TYPE_INFO_TYLE) {
+ 3895 0 : case DLT_TYLE_8BIT:
+ 3896 : {
+ 3897 0 : if (*datalength >= 1)
+ 3898 0 : dlt_print_hex_string(value_text, (int) textlength, *ptr, 1);
+ 3899 :
+ 3900 0 : if ((*datalength) < 1)
+ 3901 : return DLT_RETURN_ERROR;
+ 3902 :
+ 3903 0 : *ptr += 1;
+ 3904 0 : *datalength -= 1;
+ 3905 0 : break;
+ 3906 : }
+ 3907 0 : case DLT_TYLE_16BIT:
+ 3908 : {
+ 3909 0 : if (*datalength >= 2)
+ 3910 0 : dlt_print_hex_string(value_text, (int) textlength, *ptr, 2);
+ 3911 :
+ 3912 0 : if ((*datalength) < 2)
+ 3913 : return DLT_RETURN_ERROR;
+ 3914 :
+ 3915 0 : *ptr += 2;
+ 3916 0 : *datalength -= 2;
+ 3917 0 : break;
+ 3918 : }
+ 3919 : case DLT_TYLE_32BIT:
+ 3920 : {
+ 3921 : if (sizeof(float32_t) == 4) {
+ 3922 : value32f = 0;
+ 3923 : value32f_tmp = 0;
+ 3924 : value32f_tmp_int32i = 0;
+ 3925 : value32f_tmp_int32i_swaped = 0;
+ 3926 7 : DLT_MSG_READ_VALUE(value32f_tmp, *ptr, *datalength, float32_t);
+ 3927 :
+ 3928 7 : if ((*datalength) < 0)
+ 3929 : return DLT_RETURN_ERROR;
+ 3930 :
+ 3931 : memcpy(&value32f_tmp_int32i, &value32f_tmp, sizeof(float32_t));
+ 3932 : value32f_tmp_int32i_swaped =
+ 3933 7 : (int32_t) DLT_ENDIAN_GET_32(msg->standardheader->htyp, (uint32_t)value32f_tmp_int32i);
+ 3934 : memcpy(&value32f, &value32f_tmp_int32i_swaped, sizeof(float32_t));
+ 3935 7 : snprintf(value_text, textlength, "%g", value32f);
+ 3936 : }
+ 3937 : else {
+ 3938 : dlt_log(LOG_ERR, "Invalid size of float32_t\n");
+ 3939 : return DLT_RETURN_ERROR;
+ 3940 : }
+ 3941 :
+ 3942 : break;
+ 3943 : }
+ 3944 : case DLT_TYLE_64BIT:
+ 3945 : {
+ 3946 : if (sizeof(float64_t) == 8) {
+ 3947 : value64f = 0;
+ 3948 : value64f_tmp = 0;
+ 3949 : value64f_tmp_int64i = 0;
+ 3950 : value64f_tmp_int64i_swaped = 0;
+ 3951 7 : DLT_MSG_READ_VALUE(value64f_tmp, *ptr, *datalength, float64_t);
+ 3952 :
+ 3953 7 : if ((*datalength) < 0)
+ 3954 : return DLT_RETURN_ERROR;
+ 3955 :
+ 3956 : memcpy(&value64f_tmp_int64i, &value64f_tmp, sizeof(float64_t));
+ 3957 : value64f_tmp_int64i_swaped =
+ 3958 7 : (int64_t) DLT_ENDIAN_GET_64(msg->standardheader->htyp, (uint64_t)value64f_tmp_int64i);
+ 3959 : memcpy(&value64f, &value64f_tmp_int64i_swaped, sizeof(float64_t));
+ 3960 : #ifdef __arm__
+ 3961 : snprintf(value_text, textlength, "ILLEGAL");
+ 3962 : #else
+ 3963 : snprintf(value_text, textlength, "%g", value64f);
+ 3964 : #endif
+ 3965 : }
+ 3966 : else {
+ 3967 : dlt_log(LOG_ERR, "Invalid size of float64_t\n");
+ 3968 : return DLT_RETURN_ERROR;
+ 3969 : }
+ 3970 :
+ 3971 : break;
+ 3972 : }
+ 3973 0 : case DLT_TYLE_128BIT:
+ 3974 : {
+ 3975 0 : if (*datalength >= 16)
+ 3976 0 : dlt_print_hex_string(value_text, textlength, *ptr, 16);
+ 3977 :
+ 3978 0 : if ((*datalength) < 16)
+ 3979 : return DLT_RETURN_ERROR;
+ 3980 :
+ 3981 0 : *ptr += 16;
+ 3982 0 : *datalength -= 16;
+ 3983 0 : break;
+ 3984 : }
+ 3985 : default:
+ 3986 : {
+ 3987 : return DLT_RETURN_ERROR;
+ 3988 : }
+ 3989 : }
+ 3990 : }
+ 3991 113 : else if (type_info & DLT_TYPE_INFO_RAWD)
+ 3992 : {
+ 3993 : /* raw data argument */
+ 3994 112 : DLT_MSG_READ_VALUE(value16u_tmp, *ptr, *datalength, uint16_t);
+ 3995 :
+ 3996 112 : if ((*datalength) < 0)
+ 3997 : return DLT_RETURN_ERROR;
+ 3998 :
+ 3999 110 : length = DLT_ENDIAN_GET_16(msg->standardheader->htyp, value16u_tmp);
+ 4000 :
+ 4001 110 : if (type_info & DLT_TYPE_INFO_VARI) {
+ 4002 0 : DLT_MSG_READ_VALUE(value16u_tmp, *ptr, *datalength, uint16_t);
+ 4003 :
+ 4004 0 : if ((*datalength) < 0)
+ 4005 : return DLT_RETURN_ERROR;
+ 4006 :
+ 4007 0 : length2 = DLT_ENDIAN_GET_16(msg->standardheader->htyp, value16u_tmp);
+ 4008 :
+ 4009 0 : if ((*datalength) < length2)
+ 4010 : return DLT_RETURN_ERROR;
+ 4011 :
+ 4012 0 : if (print_with_attributes) {
+ 4013 : // Print "name" attribute, if we have one with non-zero size.
+ 4014 0 : if (length2 > 1) {
+ 4015 0 : snprintf(text, textlength, "%s:", *ptr);
+ 4016 0 : value_text += length2+1-1; // +1 for ":" and -1 for NUL
+ 4017 0 : textlength -= length2+1-1;
+ 4018 : }
+ 4019 : }
+ 4020 :
+ 4021 0 : *ptr += length2;
+ 4022 0 : *datalength -= length2;
+ 4023 : }
+ 4024 :
+ 4025 110 : if ((*datalength) < length)
+ 4026 : return DLT_RETURN_ERROR;
+ 4027 :
+ 4028 9 : if (dlt_print_hex_string_delim(value_text, (int) textlength, *ptr, length, '\'') < DLT_RETURN_OK)
+ 4029 : return DLT_RETURN_ERROR;
+ 4030 9 : *ptr += length;
+ 4031 9 : *datalength -= length;
+ 4032 : }
+ 4033 1 : else if (type_info & DLT_TYPE_INFO_TRAI)
+ 4034 : {
+ 4035 : /* trace info argument */
+ 4036 0 : DLT_MSG_READ_VALUE(value16u_tmp, *ptr, *datalength, uint16_t);
+ 4037 :
+ 4038 0 : if ((*datalength) < 0)
+ 4039 : return DLT_RETURN_ERROR;
+ 4040 :
+ 4041 0 : length = DLT_ENDIAN_GET_16(msg->standardheader->htyp, value16u_tmp);
+ 4042 :
+ 4043 0 : DLT_MSG_READ_STRING(value_text, *ptr, *datalength, textlength, length);
+ 4044 :
+ 4045 0 : if ((*datalength) < 0)
+ 4046 : return DLT_RETURN_ERROR;
+ 4047 : }
+ 4048 : else {
+ 4049 : return DLT_RETURN_ERROR;
+ 4050 : }
+ 4051 :
+ 4052 630 : if (*datalength < 0) {
+ 4053 0 : dlt_log(LOG_ERR, "Payload of DLT message corrupted\n");
+ 4054 0 : return DLT_RETURN_ERROR;
+ 4055 : }
+ 4056 :
+ 4057 : // Now write "unit" attribute, but only if it has more than only a nul-termination char.
+ 4058 630 : if (print_with_attributes) {
+ 4059 0 : if (unit_text_len > 1) {
+ 4060 : // 'value_text' still points to the +start+ of the value text
+ 4061 0 : size_t currLen = strlen(value_text);
+ 4062 :
+ 4063 0 : char* unitText = value_text + currLen;
+ 4064 0 : textlength -= currLen;
+ 4065 : snprintf(unitText, textlength, ":%s", unit_text_src);
+ 4066 : }
+ 4067 : }
+ 4068 :
+ 4069 : return DLT_RETURN_OK;
+ 4070 : }
+ 4071 :
+ 4072 6687 : void dlt_check_envvar()
+ 4073 : {
+ 4074 6687 : char *env_log_filename = getenv("DLT_LOG_FILENAME");
+ 4075 :
+ 4076 6687 : if (env_log_filename != NULL)
+ 4077 0 : dlt_log_set_filename(env_log_filename);
+ 4078 :
+ 4079 6687 : char *env_log_level_str = getenv("DLT_LOG_LEVEL");
+ 4080 :
+ 4081 6687 : if (env_log_level_str != NULL) {
+ 4082 0 : int level = 0;
+ 4083 :
+ 4084 0 : if (sscanf(env_log_level_str, "%d", &level))
+ 4085 0 : dlt_log_set_level(level);
+ 4086 : }
+ 4087 :
+ 4088 6687 : char *env_log_mode = getenv("DLT_LOG_MODE");
+ 4089 :
+ 4090 6687 : if (env_log_mode != NULL) {
+ 4091 0 : int mode = 0;
+ 4092 :
+ 4093 0 : if (sscanf(env_log_mode, "%d", &mode))
+ 4094 0 : dlt_log_init(mode);
+ 4095 : }
+ 4096 :
+ 4097 : #if defined DLT_DAEMON_USE_FIFO_IPC || defined DLT_LIB_USE_FIFO_IPC
+ 4098 6687 : char *env_pipe_dir = getenv("DLT_PIPE_DIR");
+ 4099 :
+ 4100 6687 : if (env_pipe_dir != NULL)
+ 4101 0 : dlt_log_set_fifo_basedir(env_pipe_dir);
+ 4102 : else
+ 4103 6687 : dlt_log_set_fifo_basedir(DLT_USER_IPC_PATH);
+ 4104 :
+ 4105 : #endif
+ 4106 :
+ 4107 : #ifdef DLT_SHM_ENABLE
+ 4108 : char *env_shm_name = getenv("DLT_SHM_NAME");
+ 4109 :
+ 4110 : if (env_shm_name != NULL)
+ 4111 : dlt_log_set_shm_name(env_shm_name);
+ 4112 :
+ 4113 : #endif
+ 4114 6687 : }
+ 4115 :
+ 4116 2 : int dlt_set_loginfo_parse_service_id(char *resp_text,
+ 4117 : uint32_t *service_id,
+ 4118 : uint8_t *service_opt)
+ 4119 : {
+ 4120 : int ret = -1;
+ 4121 : char get_log_info_tag[GET_LOG_INFO_LENGTH];
+ 4122 : char service_opt_str[SERVICE_OPT_LENGTH];
+ 4123 :
+ 4124 2 : if ((resp_text == NULL) || (service_id == NULL) || (service_opt == NULL))
+ 4125 : return DLT_RETURN_ERROR;
+ 4126 :
+ 4127 : /* ascii type, syntax is 'get_log_info, ..' */
+ 4128 : /* check target id */
+ 4129 : strncpy(get_log_info_tag, "get_log_info", strlen("get_log_info") + 1);
+ 4130 2 : ret = memcmp((void *)resp_text, (void *)get_log_info_tag, sizeof(get_log_info_tag) - 1);
+ 4131 :
+ 4132 2 : if (ret == 0) {
+ 4133 2 : *service_id = DLT_SERVICE_ID_GET_LOG_INFO;
+ 4134 : /* reading the response mode from the resp_text. eg. option 7*/
+ 4135 2 : service_opt_str[0] = *(resp_text + GET_LOG_INFO_LENGTH + 1);
+ 4136 2 : service_opt_str[1] = *(resp_text + GET_LOG_INFO_LENGTH + 2);
+ 4137 2 : service_opt_str[2] = 0;
+ 4138 2 : *service_opt = (uint8_t) atoi(service_opt_str);
+ 4139 : }
+ 4140 :
+ 4141 : return ret;
+ 4142 : }
+ 4143 :
+ 4144 14 : int16_t dlt_getloginfo_conv_ascii_to_uint16_t(char *rp, int *rp_count)
+ 4145 : {
+ 4146 14 : char num_work[5] = { 0 };
+ 4147 : char *endptr;
+ 4148 :
+ 4149 14 : if ((rp == NULL) || (rp_count == NULL))
+ 4150 : return -1;
+ 4151 :
+ 4152 : /* ------------------------------------------------------
+ 4153 : * from: [89 13 ] -> to: ['+0x'1389\0] -> to num
+ 4154 : * ------------------------------------------------------ */
+ 4155 14 : num_work[0] = *(rp + *rp_count + 3);
+ 4156 14 : num_work[1] = *(rp + *rp_count + 4);
+ 4157 14 : num_work[2] = *(rp + *rp_count + 0);
+ 4158 14 : num_work[3] = *(rp + *rp_count + 1);
+ 4159 : num_work[4] = 0;
+ 4160 14 : *rp_count += 6;
+ 4161 :
+ 4162 14 : return (uint16_t)strtol(num_work, &endptr, 16);
+ 4163 : }
+ 4164 :
+ 4165 12 : int16_t dlt_getloginfo_conv_ascii_to_int16_t(char *rp, int *rp_count)
+ 4166 : {
+ 4167 12 : char num_work[3] = { 0 };
+ 4168 : char *endptr;
+ 4169 :
+ 4170 12 : if ((rp == NULL) || (rp_count == NULL))
+ 4171 : return -1;
+ 4172 :
+ 4173 : /* ------------------------------------------------------
+ 4174 : * from: [89 ] -> to: ['0x'89\0] -> to num
+ 4175 : * ------------------------------------------------------ */
+ 4176 12 : num_work[0] = *(rp + *rp_count + 0);
+ 4177 12 : num_work[1] = *(rp + *rp_count + 1);
+ 4178 : num_work[2] = 0;
+ 4179 12 : *rp_count += 3;
+ 4180 :
+ 4181 12 : return (signed char)strtol(num_work, &endptr, 16);
+ 4182 : }
+ 4183 :
+ 4184 11 : void dlt_getloginfo_conv_ascii_to_string(char *rp, int *rp_count, char *wp, int len)
+ 4185 : {
+ 4186 11 : if ((rp == NULL ) || (rp_count == NULL ) || (wp == NULL ))
+ 4187 : return;
+ 4188 : /* ------------------------------------------------------
+ 4189 : * from: [72 65 6d 6f ] -> to: [0x72,0x65,0x6d,0x6f,0x00]
+ 4190 : * ------------------------------------------------------ */
+ 4191 :
+ 4192 11 : int count = dlt_getloginfo_conv_ascii_to_id(rp, rp_count, wp, len);
+ 4193 11 : *(wp + count) = '\0';
+ 4194 :
+ 4195 11 : return;
+ 4196 : }
+ 4197 :
+ 4198 20 : int dlt_getloginfo_conv_ascii_to_id(char *rp, int *rp_count, char *wp, int len)
+ 4199 : {
+ 4200 20 : char number16[3] = { 0 };
+ 4201 : char *endptr;
+ 4202 : int count;
+ 4203 :
+ 4204 20 : if ((rp == NULL) || (rp_count == NULL) || (wp == NULL))
+ 4205 : return 0;
+ 4206 :
+ 4207 : /* ------------------------------------------------------
+ 4208 : * from: [72 65 6d 6f ] -> to: [0x72,0x65,0x6d,0x6f]
+ 4209 : * ------------------------------------------------------ */
+ 4210 289 : for (count = 0; count < len; count++) {
+ 4211 269 : number16[0] = *(rp + *rp_count + 0);
+ 4212 269 : number16[1] = *(rp + *rp_count + 1);
+ 4213 269 : *(wp + count) = (char) strtol(number16, &endptr, 16);
+ 4214 269 : *rp_count += 3;
+ 4215 : }
+ 4216 :
+ 4217 : return count;
+ 4218 : }
+ 4219 :
+ 4220 0 : void dlt_hex_ascii_to_binary(const char *ptr, uint8_t *binary, int *size)
+ 4221 : {
+ 4222 0 : char ch = *ptr;
+ 4223 : int pos = 0;
+ 4224 0 : binary[pos] = 0;
+ 4225 : int first = 1;
+ 4226 : int found;
+ 4227 :
+ 4228 : for (;;) {
+ 4229 0 : if (ch == 0) {
+ 4230 0 : *size = pos;
+ 4231 0 : return;
+ 4232 : }
+ 4233 :
+ 4234 : found = 0;
+ 4235 :
+ 4236 0 : if ((ch >= '0') && (ch <= '9')) {
+ 4237 0 : binary[pos] = (uint8_t) ((binary[pos] << 4) + (ch - '0'));
+ 4238 : found = 1;
+ 4239 : }
+ 4240 0 : else if ((ch >= 'A') && (ch <= 'F'))
+ 4241 : {
+ 4242 0 : binary[pos] = (uint8_t) ((binary[pos] << 4) + (ch - 'A' + 10));
+ 4243 : found = 1;
+ 4244 : }
+ 4245 0 : else if ((ch >= 'a') && (ch <= 'f'))
+ 4246 : {
+ 4247 0 : binary[pos] = (uint8_t) ((binary[pos] << 4) + (ch - 'a' + 10));
+ 4248 : found = 1;
+ 4249 : }
+ 4250 :
+ 4251 : if (found) {
+ 4252 0 : if (first) {
+ 4253 : first = 0;
+ 4254 : }
+ 4255 : else {
+ 4256 : first = 1;
+ 4257 0 : pos++;
+ 4258 :
+ 4259 0 : if (pos >= *size)
+ 4260 : return;
+ 4261 :
+ 4262 0 : binary[pos] = 0;
+ 4263 : }
+ 4264 : }
+ 4265 :
+ 4266 0 : ch = *(++ptr);
+ 4267 : }
+ 4268 : }
+ 4269 :
+ 4270 3 : DltReturnValue dlt_file_quick_parsing(DltFile *file, const char *filename,
+ 4271 : int type, int verbose)
+ 4272 : {
+ 4273 3 : PRINT_FUNCTION_VERBOSE(verbose);
+ 4274 : int ret = DLT_RETURN_OK;
+ 4275 3 : char text[DLT_CONVERT_TEXTBUFSIZE] = { 0 };
+ 4276 :
+ 4277 3 : if ((file == NULL) || (filename == NULL))
+ 4278 : return DLT_RETURN_WRONG_PARAMETER;
+ 4279 :
+ 4280 1 : FILE *output = fopen(filename, "w+");
+ 4281 :
+ 4282 1 : if (output == NULL) {
+ 4283 0 : dlt_vlog(LOG_ERR, "Cannot open output file %s for parsing\n", filename);
+ 4284 0 : return DLT_RETURN_ERROR;
+ 4285 : }
+ 4286 :
+ 4287 106 : while (ret >= DLT_RETURN_OK && file->file_position < file->file_length) {
+ 4288 : /* get file position at start of DLT message */
+ 4289 105 : if (verbose)
+ 4290 0 : dlt_vlog(LOG_DEBUG, "Position in file: %" PRIu64 "\n", file->file_position);
+ 4291 :
+ 4292 : /* read all header and payload */
+ 4293 105 : ret = dlt_file_read_header(file, verbose);
+ 4294 :
+ 4295 105 : if (ret < DLT_RETURN_OK)
+ 4296 : break;
+ 4297 :
+ 4298 105 : ret = dlt_file_read_header_extended(file, verbose);
+ 4299 :
+ 4300 105 : if (ret < DLT_RETURN_OK)
+ 4301 : break;
+ 4302 :
+ 4303 105 : ret = dlt_file_read_data(file, verbose);
+ 4304 :
+ 4305 105 : if (ret < DLT_RETURN_OK)
+ 4306 : break;
+ 4307 :
+ 4308 105 : if (file->filter) {
+ 4309 : /* check the filters if message is used */
+ 4310 0 : ret = dlt_message_filter_check(&(file->msg), file->filter, verbose);
+ 4311 :
+ 4312 0 : if (ret != DLT_RETURN_TRUE)
+ 4313 0 : continue;
+ 4314 : }
+ 4315 :
+ 4316 105 : ret = dlt_message_header(&(file->msg), text,
+ 4317 : DLT_CONVERT_TEXTBUFSIZE, verbose);
+ 4318 :
+ 4319 105 : if (ret < DLT_RETURN_OK)
+ 4320 : break;
+ 4321 :
+ 4322 : fprintf(output, "%s", text);
+ 4323 :
+ 4324 105 : ret = dlt_message_payload(&(file->msg), text,
+ 4325 : DLT_CONVERT_TEXTBUFSIZE, type, verbose);
+ 4326 :
+ 4327 105 : if (ret < DLT_RETURN_OK)
+ 4328 : break;
+ 4329 :
+ 4330 : fprintf(output, "[%s]\n", text);
+ 4331 :
+ 4332 : /* store index pointer to message position in DLT file */
+ 4333 105 : file->counter++;
+ 4334 105 : file->position = file->counter_total - 1;
+ 4335 : /* increase total message counter */
+ 4336 105 : file->counter_total++;
+ 4337 : /* store position to next message */
+ 4338 105 : file->file_position = ftell(file->handle);
+ 4339 : } /* while() */
+ 4340 :
+ 4341 1 : fclose(output);
+ 4342 1 : return ret;
+ 4343 : }
+ 4344 :
+ 4345 :
+ 4346 0 : int dlt_execute_command(char *filename, char *command, ...)
+ 4347 : {
+ 4348 : va_list val;
+ 4349 : int argc;
+ 4350 : char **args = NULL;
+ 4351 0 : int ret = 0;
+ 4352 :
+ 4353 0 : if (command == NULL)
+ 4354 : return -1;
+ 4355 :
+ 4356 : /* Determine number of variadic arguments */
+ 4357 0 : va_start(val, command);
+ 4358 :
+ 4359 0 : for (argc = 2; va_arg(val, char *) != NULL; argc++);
+ 4360 :
+ 4361 0 : va_end(val);
+ 4362 :
+ 4363 : /* Allocate args, put references to command */
+ 4364 0 : args = (char **) malloc( (uint32_t) argc * sizeof(char*));
+ 4365 0 : args[0] = command;
+ 4366 :
+ 4367 0 : va_start(val, command);
+ 4368 :
+ 4369 0 : for (int i = 0; args[i] != NULL; i++)
+ 4370 0 : args[i + 1] = va_arg(val, char *);
+ 4371 :
+ 4372 0 : va_end(val);
+ 4373 :
+ 4374 : /* Run command in child process */
+ 4375 0 : pid_t pid = fork();
+ 4376 :
+ 4377 0 : if (pid == 0) { /* child process */
+ 4378 :
+ 4379 : /* Redirect output if required */
+ 4380 0 : if (filename != NULL) {
+ 4381 : int fd = open(filename, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+ 4382 :
+ 4383 0 : if (fd < 0)
+ 4384 0 : err(-1, "%s failed on open()", __func__);
+ 4385 :
+ 4386 0 : if (dup2(fd, STDOUT_FILENO) == -1) {
+ 4387 0 : close(fd);
+ 4388 0 : err(-1, "%s failed on dup2()", __func__);
+ 4389 : }
+ 4390 :
+ 4391 0 : close(fd);
+ 4392 : }
+ 4393 :
+ 4394 : /* Run command */
+ 4395 0 : execvp(command, (char **)args);
+ 4396 : }
+ 4397 0 : else if (pid == -1) /* error in fork */
+ 4398 : {
+ 4399 0 : ret = -1;
+ 4400 : }
+ 4401 : else { /* parent */
+ 4402 0 : wait(&ret);
+ 4403 : }
+ 4404 :
+ 4405 0 : free(args);
+ 4406 0 : return ret;
+ 4407 : }
+ 4408 :
+ 4409 5 : char *get_filename_ext(const char *filename)
+ 4410 : {
+ 4411 5 : if (filename == NULL) {
+ 4412 0 : fprintf(stderr, "ERROR: %s: invalid arguments\n", __FUNCTION__);
+ 4413 0 : return NULL;
+ 4414 : }
+ 4415 :
+ 4416 5 : char *dot = strrchr(filename, '.');
+ 4417 5 : return (!dot || dot == filename) ? NULL : dot;
+ 4418 : }
+ 4419 :
+ 4420 6 : bool dlt_extract_base_name_without_ext(const char* const abs_file_name, char* base_name, long base_name_len) {
+ 4421 6 : if (abs_file_name == NULL || base_name == NULL) return false;
+ 4422 :
+ 4423 6 : const char* last_separator = strrchr(abs_file_name, '.');
+ 4424 6 : if (!last_separator) return false;
+ 4425 5 : long length = last_separator - abs_file_name;
+ 4426 5 : length = length > base_name_len ? base_name_len : length;
+ 4427 :
+ 4428 5 : strncpy(base_name, abs_file_name, length);
+ 4429 5 : base_name[length] = '\0';
+ 4430 5 : return true;
+ 4431 : }
+ 4432 :
+ 4433 12 : void dlt_log_multiple_files_write(const char* format, ...)
+ 4434 : {
+ 4435 12 : char output_string[2048] = { 0 };
+ 4436 : va_list args;
+ 4437 12 : va_start (args, format);
+ 4438 : vsnprintf(output_string, 2047, format, args);
+ 4439 12 : va_end (args);
+ 4440 12 : multiple_files_buffer_write(&multiple_files_ring_buffer, (unsigned char*)output_string, strlen(output_string));
+ 4441 12 : }
+ 4442 :
+ 4443 37 : bool dlt_is_log_in_multiple_files_active()
+ 4444 : {
+ 4445 37 : return multiple_files_ring_buffer.ohandle > -1;
+ 4446 : }
+
+ |
+
+