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