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