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