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