Line data Source code
1 : /*
2 : * SPDX license identifier: MPL-2.0
3 : *
4 : * Copyright (C) 2011-2015, BMW AG
5 : *
6 : * This file is part of COVESA Project DLT - Diagnostic Log and Trace.
7 : *
8 : * This Source Code Form is subject to the terms of the
9 : * Mozilla Public License (MPL), v. 2.0.
10 : * If a copy of the MPL was not distributed with this file,
11 : * You can obtain one at http://mozilla.org/MPL/2.0/.
12 : *
13 : * For further information see http://www.covesa.org/.
14 : */
15 :
16 : /*!
17 : * \author
18 : * Alexander Wenzel <alexander.aw.wenzel@bmw.de>
19 : * Markus Klein <Markus.Klein@esk.fraunhofer.de>
20 : * Mikko Rapeli <mikko.rapeli@bmw.de>
21 : *
22 : * \copyright Copyright © 2011-2015 BMW AG. \n
23 : * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/.
24 : *
25 : * \file dlt_common.c
26 : */
27 :
28 : #include <stdio.h>
29 : #include <stdlib.h> /* for malloc(), free() */
30 : #include <string.h> /* for strlen(), memcmp(), memmove() */
31 : #include <time.h> /* for localtime_r(), strftime() */
32 : #include <limits.h> /* for NAME_MAX */
33 : #include <inttypes.h> /* for PRI formatting macro */
34 : #include <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_MONOTONIC
55 : # define CLOCK_MONOTONIC 1
56 : # endif
57 : #endif
58 :
59 : #if defined (_MSC_VER)
60 : # include <io.h>
61 : #else
62 : # include <unistd.h> /* for read(), close() */
63 : # include <fcntl.h>
64 : # include <sys/time.h> /* for gettimeofday() */
65 : #endif
66 :
67 : #if defined (__MSDOS__) || defined (_MSC_VER)
68 : # pragma warning(disable : 4996) /* Switch off C4996 warnings */
69 : # include <windows.h>
70 : # include <winbase.h>
71 : #endif
72 :
73 : const char dltSerialHeader[DLT_ID_SIZE] = { 'D', 'L', 'S', 1 };
74 : char dltSerialHeaderChar[DLT_ID_SIZE] = { 'D', 'L', 'S', 1 };
75 :
76 : #if defined DLT_DAEMON_USE_FIFO_IPC || defined DLT_LIB_USE_FIFO_IPC
77 : char dltFifoBaseDir[DLT_PATH_MAX] = "/tmp";
78 : #endif
79 :
80 : #ifdef DLT_SHM_ENABLE
81 : char dltShmName[NAME_MAX + 1] = "/dlt-shm";
82 : #endif
83 :
84 : static bool print_with_attributes = false;
85 :
86 : char *message_type[] = { "log", "app_trace", "nw_trace", "control", "", "", "", "" };
87 : char *log_info[] = { "", "fatal", "error", "warn", "info", "debug", "verbose", "", "", "", "", "", "", "", "", "" };
88 : char *trace_type[] = { "", "variable", "func_in", "func_out", "state", "vfb", "", "", "", "", "", "", "", "", "", "" };
89 : char *nw_trace_type[] = { "", "ipc", "can", "flexray", "most", "vfb", "", "", "", "", "", "", "", "", "", "" };
90 : char *control_type[] = { "", "request", "response", "time", "", "", "", "", "", "", "", "", "", "", "", "" };
91 : static char *service_id_name[] =
92 : { "", "set_log_level", "set_trace_status", "get_log_info", "get_default_log_level", "store_config",
93 : "reset_to_factory_default",
94 : "set_com_interface_status", "set_com_interface_max_bandwidth", "set_verbose_mode",
95 : "set_message_filtering", "set_timing_packets",
96 : "get_local_time", "use_ecu_id", "use_session_id", "use_timestamp", "use_extended_header",
97 : "set_default_log_level", "set_default_trace_status",
98 : "get_software_version", "message_buffer_overflow" };
99 : static char *return_type[] =
100 : { "ok", "not_supported", "error", "perm_denied", "warning", "", "", "", "no_matching_context_id" };
101 :
102 : /* internal function definitions */
103 : int dlt_buffer_get(DltBuffer *buf, unsigned char *data, int max_size, int delete);
104 : int dlt_buffer_reset(DltBuffer *buf);
105 : int dlt_buffer_increase_size(DltBuffer *buf);
106 : int dlt_buffer_minimize_size(DltBuffer *buf);
107 : void dlt_buffer_write_block(DltBuffer *buf, int *write, const unsigned char *data, unsigned int size);
108 : void dlt_buffer_read_block(DltBuffer *buf, int *read, unsigned char *data, unsigned int size);
109 :
110 : #ifdef DLT_TRACE_LOAD_CTRL_ENABLE
111 : static int32_t dlt_output_soft_limit_over_warning(
112 : DltTraceLoadSettings* tl_settings,
113 : DltLogInternal log_internal,
114 : void *log_params);
115 :
116 : static int32_t dlt_output_hard_limit_warning(
117 : DltTraceLoadSettings* tl_settings,
118 : DltLogInternal log_internal,
119 : void *log_params);
120 :
121 : static bool dlt_user_cleanup_window(DltTraceLoadStat *tl_stat);
122 :
123 : static int32_t dlt_switch_slot_if_needed(
124 : DltTraceLoadSettings* tl_settings,
125 : DltLogInternal log_internal,
126 : void *log_internal_params,
127 : uint32_t timestamp);
128 :
129 : static void dlt_record_trace_load(DltTraceLoadStat *const tl_stat, int32_t size);
130 : static inline bool dlt_is_over_trace_load_soft_limit(DltTraceLoadSettings* tl_settings);
131 : static inline bool dlt_is_over_trace_load_hard_limit(DltTraceLoadSettings* tl_settings, int size);
132 : #endif
133 :
134 0 : void dlt_print_hex(uint8_t *ptr, int size)
135 : {
136 : int num;
137 :
138 0 : if (ptr == NULL)
139 : return;
140 :
141 0 : for (num = 0; num < size; num++) {
142 0 : if (num > 0)
143 0 : dlt_user_printf(" ");
144 :
145 0 : dlt_user_printf("%.2x", ((uint8_t *)ptr)[num]);
146 : }
147 : }
148 :
149 2743 : static DltReturnValue dlt_print_hex_string_delim(char *text, int textlength, uint8_t *ptr, int size, char delim)
150 : {
151 : int num;
152 :
153 2743 : if ((ptr == NULL) || (text == NULL) || (textlength <= 0) || (size < 0) || (delim == '\0'))
154 : return DLT_RETURN_WRONG_PARAMETER;
155 :
156 : /* Length 3: AB_ , A is first digit of hex number, B is second digit of hex number, _ is space */
157 2740 : if (textlength < (size * 3)) {
158 0 : dlt_vlog(LOG_WARNING,
159 : "String does not fit hex data (available=%d, required=%d) !\n",
160 : textlength, size * 3);
161 0 : return DLT_RETURN_ERROR;
162 : }
163 :
164 36599 : for (num = 0; num < size; num++) {
165 33859 : if (num > 0) {
166 31147 : snprintf(text, 2, "%c", delim);
167 31147 : text++;
168 : }
169 :
170 33859 : snprintf(text, 3, "%.2x", ((uint8_t *)ptr)[num]);
171 33859 : text += 2; /* 2 chars */
172 : }
173 :
174 : return DLT_RETURN_OK;
175 : }
176 :
177 2734 : DltReturnValue dlt_print_hex_string(char *text, int textlength, uint8_t *ptr, int size)
178 : {
179 2734 : return dlt_print_hex_string_delim(text, textlength, ptr, size, ' ');
180 : }
181 :
182 1066 : DltReturnValue dlt_print_mixed_string(char *text, int textlength, uint8_t *ptr, int size, int html)
183 : {
184 : int required_size = 0;
185 : int lines, rest, i;
186 :
187 1066 : if ((ptr == NULL) || (text == NULL) || (textlength <= 0) || (size < 0))
188 : return DLT_RETURN_WRONG_PARAMETER;
189 :
190 : /* Check maximum required size and do a length check */
191 1060 : if (html == 0)
192 530 : required_size =
193 : (DLT_COMMON_HEX_LINELEN + (2 * DLT_COMMON_HEX_CHARS + (DLT_COMMON_HEX_CHARS - 1)) + DLT_COMMON_CHARLEN +
194 : DLT_COMMON_HEX_CHARS + DLT_COMMON_CHARLEN) *
195 530 : ((size / DLT_COMMON_HEX_CHARS) + 1);
196 : /* Example: (8 chars line number + (2*16 chars + 15 spaces) + space + 16 ascii chars + CR) *
197 : * ((size/16) lines + extra line for the rest) */
198 : else
199 530 : required_size =
200 : (DLT_COMMON_HEX_LINELEN + (2 * DLT_COMMON_HEX_CHARS + (DLT_COMMON_HEX_CHARS - 1)) + DLT_COMMON_CHARLEN +
201 : DLT_COMMON_HEX_CHARS + 4 * DLT_COMMON_CHARLEN) *
202 530 : ((size / DLT_COMMON_HEX_CHARS) + 1);
203 :
204 : /* Example: (8 chars line number + (2*16 chars + 15 spaces) + space + 16 ascii chars + 4 [HTML CR: <BR>]) *
205 : * ((size/16) lines + extra line for the rest) */
206 :
207 1060 : if (textlength < required_size) {
208 0 : dlt_vlog(LOG_WARNING,
209 : "String does not fit mixed data (available=%d, required=%d) !\n",
210 : textlength, required_size);
211 0 : return DLT_RETURN_ERROR;
212 : }
213 :
214 : /* print full lines */
215 1740 : for (lines = 0; lines < (size / DLT_COMMON_HEX_CHARS); lines++) {
216 : int ret = 0;
217 : /* Line number */
218 680 : ret = snprintf(text, DLT_COMMON_HEX_LINELEN + 1, "%.6x: ", (uint32_t)lines * DLT_COMMON_HEX_CHARS);
219 :
220 680 : if ((ret < 0) || (ret >= (DLT_COMMON_HEX_LINELEN + 1)))
221 0 : dlt_log(LOG_WARNING, "line was truncated\n");
222 :
223 680 : text += DLT_COMMON_HEX_LINELEN; /* 'XXXXXX: ' */
224 :
225 : /* Hex-Output */
226 : /* It is not required to decrement textlength, as it was already checked, that
227 : * there is enough space for the complete output */
228 680 : if (dlt_print_hex_string(text, textlength,
229 680 : (uint8_t *)(ptr + (lines * DLT_COMMON_HEX_CHARS)),
230 : DLT_COMMON_HEX_CHARS) < DLT_RETURN_OK)
231 : return DLT_RETURN_ERROR;
232 680 : text += ((2 * DLT_COMMON_HEX_CHARS) + (DLT_COMMON_HEX_CHARS - 1)); /* 32 characters + 15 spaces */
233 :
234 : snprintf(text, 2, " ");
235 680 : text += DLT_COMMON_CHARLEN;
236 :
237 : /* Char-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_char_string(&text, textlength,
241 : (uint8_t *)(ptr + (lines * DLT_COMMON_HEX_CHARS)),
242 : DLT_COMMON_HEX_CHARS) < DLT_RETURN_OK)
243 : return DLT_RETURN_ERROR;
244 :
245 680 : if (html == 0) {
246 340 : snprintf(text, 2, "\n");
247 340 : text += DLT_COMMON_CHARLEN;
248 : }
249 : else {
250 340 : snprintf(text, 5, "<BR>");
251 340 : text += (4 * DLT_COMMON_CHARLEN);
252 : }
253 : }
254 :
255 : /* print partial line */
256 1060 : rest = size % DLT_COMMON_HEX_CHARS;
257 :
258 1060 : if (rest > 0) {
259 : /* Line number */
260 : int ret = 0;
261 986 : ret = snprintf(text, 9, "%.6x: ", (uint32_t)(size / DLT_COMMON_HEX_CHARS) * DLT_COMMON_HEX_CHARS);
262 :
263 986 : if ((ret < 0) || (ret >= 9))
264 0 : dlt_log(LOG_WARNING, "line number was truncated");
265 :
266 986 : text += DLT_COMMON_HEX_LINELEN; /* 'XXXXXX: ' */
267 :
268 : /* Hex-Output */
269 : /* It is not required to decrement textlength, as it was already checked, that
270 : * there is enough space for the complete output */
271 986 : if (dlt_print_hex_string(text,
272 : textlength,
273 986 : (uint8_t *)(ptr + ((size / DLT_COMMON_HEX_CHARS) * DLT_COMMON_HEX_CHARS)),
274 : rest) < DLT_RETURN_OK)
275 : return DLT_RETURN_ERROR;
276 986 : text += 2 * rest + (rest - 1);
277 :
278 9472 : for (i = 0; i < (DLT_COMMON_HEX_CHARS - rest); i++) {
279 8486 : snprintf(text, 4, " xx");
280 8486 : text += (3 * DLT_COMMON_CHARLEN);
281 : }
282 :
283 986 : snprintf(text, 2, " ");
284 986 : text += DLT_COMMON_CHARLEN;
285 :
286 : /* Char-Output */
287 : /* It is not required to decrement textlength, as it was already checked, that
288 : * there is enough space for the complete output */
289 986 : if (dlt_print_char_string(&text, textlength,
290 : (uint8_t *)(ptr + ((size / DLT_COMMON_HEX_CHARS) * DLT_COMMON_HEX_CHARS)),
291 : rest) < DLT_RETURN_OK)
292 : return DLT_RETURN_ERROR;
293 : }
294 :
295 : return DLT_RETURN_OK;
296 : }
297 :
298 1671 : DltReturnValue dlt_print_char_string(char **text, int textlength, uint8_t *ptr, int size)
299 : {
300 : int num;
301 :
302 1671 : if ((text == NULL) || (ptr == NULL) || (*text == NULL) || (textlength <= 0) || (size < 0))
303 : return DLT_RETURN_WRONG_PARAMETER;
304 :
305 1668 : if (textlength < size) {
306 0 : dlt_vlog(LOG_WARNING,
307 : "String does not fit character data (available=%d, required=%d) !\n",
308 : textlength, size);
309 0 : return DLT_RETURN_WRONG_PARAMETER;
310 : }
311 :
312 19879 : for (num = 0; num < size; num++) {
313 18211 : if ((((char *)ptr)[num] < DLT_COMMON_ASCII_CHAR_SPACE) || (((char *)ptr)[num] > DLT_COMMON_ASCII_CHAR_TILDE)) {
314 10314 : snprintf(*text, 2, ".");
315 : }
316 : else {
317 : /* replace < with . */
318 7897 : if (((char *)ptr)[num] != DLT_COMMON_ASCII_CHAR_LT)
319 7895 : snprintf(*text, 2, "%c", ((char *)ptr)[num]);
320 : else
321 2 : snprintf(*text, 2, ".");
322 : }
323 :
324 18211 : (*text)++;
325 : }
326 :
327 : return DLT_RETURN_OK;
328 : }
329 :
330 5622 : size_t dlt_strnlen_s(const char* str, size_t maxsize)
331 : {
332 5622 : if (str == NULL)
333 : return 0;
334 :
335 24796 : for (size_t i = 0; i < maxsize; ++i) {
336 22517 : if (str[i] == '\0')
337 3342 : return i;
338 : }
339 : return maxsize;
340 : }
341 :
342 5620 : void dlt_print_id(char *text, const char *id)
343 : {
344 : /* check nullpointer */
345 5620 : if ((text == NULL) || (id == NULL))
346 : return;
347 :
348 : /* Initialize text */
349 : memset(text, '-', DLT_ID_SIZE);
350 :
351 5617 : text[DLT_ID_SIZE] = 0;
352 :
353 5617 : size_t len = dlt_strnlen_s(id, DLT_ID_SIZE);
354 :
355 : memcpy(text, id, len);
356 : }
357 :
358 92232 : void dlt_set_id(char *id, const char *text)
359 : {
360 : /* check nullpointer */
361 92232 : if ((id == NULL) || (text == NULL))
362 : return;
363 :
364 92229 : id[0] = 0;
365 92229 : id[1] = 0;
366 92229 : id[2] = 0;
367 85690 : id[3] = 0;
368 :
369 92229 : if (text[0] != 0)
370 57241 : id[0] = text[0];
371 : else
372 : return;
373 :
374 57241 : if (text[1] != 0)
375 57235 : id[1] = text[1];
376 : else
377 : return;
378 :
379 57235 : if (text[2] != 0)
380 57227 : id[2] = text[2];
381 : else
382 : return;
383 :
384 57227 : if (text[3] != 0)
385 57050 : id[3] = text[3];
386 : else
387 : return;
388 : }
389 :
390 1159 : void dlt_clean_string(char *text, int length)
391 : {
392 : int num;
393 :
394 1159 : if (text == NULL)
395 : return;
396 :
397 10286 : for (num = 0; num < length; num++)
398 9127 : if ((text[num] == '\r') || (text[num] == '\n'))
399 0 : text[num] = ' ';
400 : }
401 :
402 7 : DltReturnValue dlt_filter_init(DltFilter *filter, int verbose)
403 : {
404 7 : PRINT_FUNCTION_VERBOSE(verbose);
405 :
406 7 : if (filter == NULL)
407 : return DLT_RETURN_WRONG_PARAMETER;
408 :
409 7 : filter->counter = 0;
410 :
411 7 : return DLT_RETURN_OK;
412 : }
413 :
414 1 : DltReturnValue dlt_filter_free(DltFilter *filter, int verbose)
415 : {
416 1 : PRINT_FUNCTION_VERBOSE(verbose);
417 :
418 1 : if (filter == NULL)
419 0 : return DLT_RETURN_WRONG_PARAMETER;
420 :
421 : return DLT_RETURN_OK;
422 : }
423 :
424 6 : DltReturnValue dlt_filter_load(DltFilter *filter, const char *filename, int verbose)
425 : {
426 6 : if ((filter == NULL) || (filename == NULL))
427 : return DLT_RETURN_WRONG_PARAMETER;
428 :
429 : FILE *handle;
430 : char str1[DLT_COMMON_BUFFER_LENGTH + 1];
431 : char apid[DLT_ID_SIZE], ctid[DLT_ID_SIZE];
432 :
433 6 : PRINT_FUNCTION_VERBOSE(verbose);
434 :
435 6 : handle = fopen(filename, "r");
436 :
437 6 : if (handle == NULL) {
438 0 : dlt_vlog(LOG_WARNING, "Filter file %s cannot be opened!\n", filename);
439 0 : return DLT_RETURN_ERROR;
440 : }
441 :
442 : #define FORMAT_STRING_(x) "%" #x "s"
443 : #define FORMAT_STRING(x) FORMAT_STRING_(x)
444 :
445 : /* Reset filters */
446 6 : filter->counter = 0;
447 :
448 18 : while (!feof(handle)) {
449 18 : str1[0] = 0;
450 :
451 18 : if (fscanf(handle, FORMAT_STRING(DLT_COMMON_BUFFER_LENGTH), str1) != 1)
452 : break;
453 :
454 12 : if (str1[0] == 0)
455 : break;
456 :
457 : printf(" %s", str1);
458 :
459 12 : if (strcmp(str1, "----") == 0 || strcmp(str1, "*") == 0)
460 0 : dlt_set_id(apid, "");
461 : else
462 12 : dlt_set_id(apid, str1);
463 :
464 12 : str1[0] = 0;
465 :
466 12 : if (fscanf(handle, FORMAT_STRING(DLT_COMMON_BUFFER_LENGTH), str1) != 1)
467 : break;
468 :
469 12 : if (str1[0] == 0)
470 : break;
471 :
472 : printf(" %s\r\n", str1);
473 :
474 12 : if (strcmp(str1, "----") == 0)
475 0 : dlt_set_id(ctid, "");
476 : else
477 12 : dlt_set_id(ctid, str1);
478 :
479 12 : if (filter->counter < DLT_FILTER_MAX)
480 12 : dlt_filter_add(filter, apid, ctid, 0, 0, INT32_MAX, verbose);
481 : else
482 0 : dlt_vlog(LOG_WARNING,
483 : "Maximum number (%d) of allowed filters reached, ignoring rest of filters!\n",
484 : DLT_FILTER_MAX);
485 : }
486 :
487 6 : fclose(handle);
488 :
489 6 : return DLT_RETURN_OK;
490 : }
491 :
492 0 : DltReturnValue dlt_filter_save(DltFilter *filter, const char *filename, int verbose)
493 : {
494 0 : if ((filter == NULL) || (filename == NULL))
495 : return DLT_RETURN_WRONG_PARAMETER;
496 :
497 : FILE *handle;
498 : int num;
499 : char buf[DLT_COMMON_BUFFER_LENGTH];
500 :
501 0 : PRINT_FUNCTION_VERBOSE(verbose);
502 :
503 0 : handle = fopen(filename, "w");
504 :
505 0 : if (handle == NULL) {
506 0 : dlt_vlog(LOG_WARNING, "Filter file %s cannot be opened!\n", filename);
507 0 : return DLT_RETURN_ERROR;
508 : }
509 :
510 0 : for (num = 0; num < filter->counter; num++) {
511 0 : if (filter->apid[num][0] == 0) {
512 : fprintf(handle, "---- ");
513 : }
514 : else {
515 0 : dlt_print_id(buf, filter->apid[num]);
516 : fprintf(handle, "%s ", buf);
517 : }
518 :
519 0 : if (filter->ctid[num][0] == 0) {
520 : fprintf(handle, "---- ");
521 : }
522 : else {
523 0 : dlt_print_id(buf, filter->ctid[num]);
524 : fprintf(handle, "%s ", buf);
525 : }
526 : }
527 :
528 0 : fclose(handle);
529 :
530 0 : return DLT_RETURN_OK;
531 : }
532 :
533 12 : int dlt_filter_find(DltFilter *filter, const char *apid, const char *ctid, const int log_level,
534 : const int32_t payload_min, const int32_t payload_max, int verbose)
535 : {
536 : int num;
537 :
538 12 : PRINT_FUNCTION_VERBOSE(verbose);
539 :
540 12 : if ((filter == NULL) || (apid == NULL))
541 : return -1;
542 :
543 18 : for (num = 0; num < filter->counter; num++)
544 6 : if (memcmp(filter->apid[num], apid, DLT_ID_SIZE) == 0) {
545 : /* apid matches, now check for ctid */
546 0 : if (ctid == NULL) {
547 : /* check if empty ctid matches */
548 : /*if (memcmp(filter->ctid[num],"",DLT_ID_SIZE)==0)//coverity complains here about Out-of-bounds access. */
549 0 : char empty_ctid[DLT_ID_SIZE] = "";
550 :
551 0 : if (memcmp(filter->ctid[num], empty_ctid, DLT_ID_SIZE) == 0)
552 0 : if ((filter->log_level[num] == log_level) || (filter->log_level[num] == 0))
553 0 : if (filter->payload_min[num] <= payload_min)
554 0 : if (filter->payload_max[num] >= payload_max)
555 0 : return num;
556 : }
557 0 : else if (memcmp(filter->ctid[num], ctid, DLT_ID_SIZE) == 0)
558 : {
559 0 : if ((filter->log_level[num] == log_level) || (filter->log_level[num] == 0))
560 0 : if (filter->payload_min[num] <= payload_min)
561 0 : if (filter->payload_max[num] >= payload_max)
562 0 : return num;
563 : }
564 : }
565 :
566 : return -1; /* Not found */
567 : }
568 :
569 12 : DltReturnValue dlt_filter_add(DltFilter *filter, const char *apid, const char *ctid, const int log_level,
570 : const int32_t payload_min, const int32_t payload_max, int verbose)
571 : {
572 12 : PRINT_FUNCTION_VERBOSE(verbose);
573 :
574 12 : if ((filter == NULL) || (apid == NULL))
575 : return DLT_RETURN_WRONG_PARAMETER;
576 :
577 12 : if (filter->counter >= DLT_FILTER_MAX) {
578 0 : dlt_vlog(LOG_WARNING,
579 : "Maximum number (%d) of allowed filters reached, ignoring filter!\n",
580 : DLT_FILTER_MAX);
581 0 : return DLT_RETURN_ERROR;
582 : }
583 :
584 : /* add each filter (apid, ctid, log_level, payload_min, payload_max) only once to filter array */
585 12 : if (dlt_filter_find(filter, apid, ctid, log_level, payload_min, payload_max, verbose) < 0) {
586 : /* filter not found, so add it to filter array */
587 12 : dlt_set_id(filter->apid[filter->counter], apid);
588 12 : dlt_set_id(filter->ctid[filter->counter], (ctid ? ctid : ""));
589 12 : filter->log_level[filter->counter] = log_level;
590 12 : filter->payload_min[filter->counter] = payload_min;
591 12 : filter->payload_max[filter->counter] = payload_max;
592 :
593 12 : filter->counter++;
594 :
595 12 : return DLT_RETURN_OK;
596 : }
597 :
598 : return DLT_RETURN_ERROR;
599 : }
600 :
601 0 : DltReturnValue dlt_filter_delete(DltFilter *filter, const char *apid, const char *ctid, const int log_level,
602 : const int32_t payload_min, const int32_t payload_max, int verbose)
603 : {
604 : int j, k;
605 : int found = 0;
606 :
607 0 : PRINT_FUNCTION_VERBOSE(verbose);
608 :
609 0 : if ((filter == NULL) || (apid == NULL) || (ctid == NULL))
610 : return DLT_RETURN_WRONG_PARAMETER;
611 :
612 0 : if (filter->counter > 0) {
613 : /* Get first occurence of apid and ctid in filter array */
614 0 : for (j = 0; j < filter->counter; j++)
615 0 : if ((memcmp(filter->apid[j], apid, DLT_ID_SIZE) == 0) &&
616 0 : (memcmp(filter->ctid[j], ctid, DLT_ID_SIZE) == 0) &&
617 0 : ((filter->log_level[j] == log_level) || (filter->log_level[j] == 0)) &&
618 0 : (filter->payload_min[j] == payload_min) &&
619 0 : (filter->payload_max[j] == payload_max)
620 : ) {
621 : found = 1;
622 : break;
623 : }
624 :
625 0 : if (found) {
626 : /* j is index */
627 : /* Copy from j+1 til end to j til end-1 */
628 :
629 0 : dlt_set_id(filter->apid[j], "");
630 0 : dlt_set_id(filter->ctid[j], "");
631 0 : filter->log_level[j] = 0;
632 0 : filter->payload_min[j] = 0;
633 0 : filter->payload_max[j] = INT32_MAX;
634 :
635 0 : for (k = j; k < (filter->counter - 1); k++) {
636 0 : dlt_set_id(filter->apid[k], filter->apid[k + 1]);
637 0 : dlt_set_id(filter->ctid[k], filter->ctid[k + 1]);
638 0 : filter->log_level[k] = filter->log_level[k + 1];
639 0 : filter->payload_min[k] = filter->payload_min[k + 1];
640 0 : filter->payload_max[k] = filter->payload_max[k + 1];
641 : }
642 :
643 0 : filter->counter--;
644 0 : return DLT_RETURN_OK;
645 : }
646 : }
647 :
648 : return DLT_RETURN_ERROR;
649 : }
650 :
651 6117 : DltReturnValue dlt_message_init(DltMessage *msg, int verbose)
652 : {
653 6117 : PRINT_FUNCTION_VERBOSE(verbose);
654 :
655 6117 : if (msg == NULL)
656 : return DLT_RETURN_WRONG_PARAMETER;
657 :
658 : /* initalise structure parameters */
659 6115 : msg->headersize = 0;
660 6115 : msg->datasize = 0;
661 :
662 6115 : msg->databuffer = NULL;
663 6115 : msg->databuffersize = 0;
664 :
665 6115 : msg->storageheader = NULL;
666 6115 : msg->standardheader = NULL;
667 6115 : msg->extendedheader = NULL;
668 :
669 6115 : msg->found_serialheader = 0;
670 :
671 6115 : return DLT_RETURN_OK;
672 : }
673 :
674 115 : DltReturnValue dlt_message_free(DltMessage *msg, int verbose)
675 : {
676 115 : PRINT_FUNCTION_VERBOSE(verbose);
677 :
678 115 : if (msg == NULL)
679 : return DLT_RETURN_WRONG_PARAMETER;
680 :
681 : /* delete databuffer if exists */
682 113 : if (msg->databuffer) {
683 87 : free(msg->databuffer);
684 87 : msg->databuffer = NULL;
685 87 : msg->databuffersize = 0;
686 : }
687 :
688 : return DLT_RETURN_OK;
689 : }
690 :
691 2420 : DltReturnValue dlt_message_header(DltMessage *msg, char *text, size_t textlength, int verbose)
692 : {
693 2420 : return dlt_message_header_flags(msg, text, textlength, DLT_HEADER_SHOW_ALL, verbose);
694 : }
695 :
696 5122 : DltReturnValue dlt_message_header_flags(DltMessage *msg, char *text, size_t textlength, int flags, int verbose)
697 : {
698 : struct tm timeinfo;
699 : char buffer [DLT_COMMON_BUFFER_LENGTH];
700 :
701 5122 : PRINT_FUNCTION_VERBOSE(verbose);
702 :
703 5122 : if ((msg == NULL) || (text == NULL) || (textlength <= 0))
704 : return DLT_RETURN_WRONG_PARAMETER;
705 :
706 4926 : if ((DLT_IS_HTYP_UEH(msg->standardheader->htyp)) && (msg->extendedheader == NULL))
707 : return DLT_RETURN_WRONG_PARAMETER;
708 :
709 4926 : if ((flags < DLT_HEADER_SHOW_NONE) || (flags > DLT_HEADER_SHOW_ALL))
710 : return DLT_RETURN_WRONG_PARAMETER;
711 :
712 4926 : text[0] = 0;
713 :
714 4926 : if ((flags & DLT_HEADER_SHOW_TIME) == DLT_HEADER_SHOW_TIME) {
715 : /* print received time */
716 2826 : time_t tt = msg->storageheader->seconds;
717 2826 : tzset();
718 2826 : localtime_r(&tt, &timeinfo);
719 2826 : strftime (buffer, sizeof(buffer), "%Y/%m/%d %H:%M:%S", &timeinfo);
720 2826 : snprintf(text, textlength, "%s.%.6d ", buffer, msg->storageheader->microseconds);
721 : }
722 :
723 4926 : if ((flags & DLT_HEADER_SHOW_TMSTP) == DLT_HEADER_SHOW_TMSTP) {
724 : /* print timestamp if available */
725 2826 : if (DLT_IS_HTYP_WTMS(msg->standardheader->htyp))
726 647 : snprintf(text + strlen(text), textlength - strlen(text), "%10u ", msg->headerextra.tmsp);
727 : else
728 2179 : snprintf(text + strlen(text), textlength - strlen(text), "---------- ");
729 : }
730 :
731 4926 : if ((flags & DLT_HEADER_SHOW_MSGCNT) == DLT_HEADER_SHOW_MSGCNT)
732 : /* print message counter */
733 2826 : snprintf(text + strlen(text), textlength - strlen(text), "%.3d ", msg->standardheader->mcnt);
734 :
735 4926 : if ((flags & DLT_HEADER_SHOW_ECUID) == DLT_HEADER_SHOW_ECUID) {
736 : /* print ecu id, use header extra if available, else storage header value */
737 2826 : if (DLT_IS_HTYP_WEID(msg->standardheader->htyp))
738 647 : dlt_print_id(text + strlen(text), msg->headerextra.ecu);
739 : else
740 2179 : dlt_print_id(text + strlen(text), msg->storageheader->ecu);
741 : }
742 :
743 : /* print app id and context id if extended header available, else '----' */ #
744 :
745 4926 : if ((flags & DLT_HEADER_SHOW_APID) == DLT_HEADER_SHOW_APID) {
746 2826 : snprintf(text + strlen(text), textlength - strlen(text), " ");
747 :
748 2826 : if ((DLT_IS_HTYP_UEH(msg->standardheader->htyp)) && (msg->extendedheader->apid[0] != 0))
749 1395 : dlt_print_id(text + strlen(text), msg->extendedheader->apid);
750 : else
751 1431 : snprintf(text + strlen(text), textlength - strlen(text), "----");
752 :
753 2826 : snprintf(text + strlen(text), textlength - strlen(text), " ");
754 : }
755 :
756 4926 : if ((flags & DLT_HEADER_SHOW_CTID) == DLT_HEADER_SHOW_CTID) {
757 2826 : if ((DLT_IS_HTYP_UEH(msg->standardheader->htyp)) && (msg->extendedheader->ctid[0] != 0))
758 1395 : dlt_print_id(text + strlen(text), msg->extendedheader->ctid);
759 : else
760 1431 : snprintf(text + strlen(text), textlength - strlen(text), "----");
761 :
762 2826 : snprintf(text + strlen(text), textlength - strlen(text), " ");
763 : }
764 :
765 : /* print info about message type and length */
766 4926 : if (DLT_IS_HTYP_UEH(msg->standardheader->htyp)) {
767 2435 : if ((flags & DLT_HEADER_SHOW_MSGTYPE) == DLT_HEADER_SHOW_MSGTYPE) {
768 1395 : snprintf(text + strlen(text), textlength - strlen(text), "%s",
769 1395 : message_type[DLT_GET_MSIN_MSTP(msg->extendedheader->msin)]);
770 1395 : snprintf(text + strlen(text), textlength - strlen(text), " ");
771 : }
772 :
773 2435 : if ((flags & DLT_HEADER_SHOW_MSGSUBTYPE) == DLT_HEADER_SHOW_MSGSUBTYPE) {
774 1395 : if ((DLT_GET_MSIN_MSTP(msg->extendedheader->msin)) == DLT_TYPE_LOG)
775 1256 : snprintf(text + strlen(text), textlength - strlen(text), "%s",
776 1256 : log_info[DLT_GET_MSIN_MTIN(msg->extendedheader->msin)]);
777 :
778 1395 : if ((DLT_GET_MSIN_MSTP(msg->extendedheader->msin)) == DLT_TYPE_APP_TRACE)
779 0 : snprintf(text + strlen(text), textlength - strlen(text), "%s",
780 0 : trace_type[DLT_GET_MSIN_MTIN(msg->extendedheader->msin)]);
781 :
782 1395 : if ((DLT_GET_MSIN_MSTP(msg->extendedheader->msin)) == DLT_TYPE_NW_TRACE)
783 0 : snprintf(text + strlen(text), textlength - strlen(text), "%s",
784 0 : nw_trace_type[DLT_GET_MSIN_MTIN(msg->extendedheader->msin)]);
785 :
786 1395 : if ((DLT_GET_MSIN_MSTP(msg->extendedheader->msin)) == DLT_TYPE_CONTROL)
787 139 : snprintf(text + strlen(text), textlength - strlen(text), "%s",
788 139 : control_type[DLT_GET_MSIN_MTIN(msg->extendedheader->msin)]);
789 :
790 1395 : snprintf(text + strlen(text), textlength - strlen(text), " ");
791 : }
792 :
793 2435 : if ((flags & DLT_HEADER_SHOW_VNVSTATUS) == DLT_HEADER_SHOW_VNVSTATUS) {
794 : /* print verbose status pf message */
795 1395 : if (DLT_IS_MSIN_VERB(msg->extendedheader->msin))
796 1256 : snprintf(text + strlen(text), textlength - strlen(text), "V");
797 : else
798 139 : snprintf(text + strlen(text), textlength - strlen(text), "N");
799 :
800 1395 : snprintf(text + strlen(text), textlength - strlen(text), " ");
801 : }
802 :
803 2435 : if ((flags & DLT_HEADER_SHOW_NOARG) == DLT_HEADER_SHOW_NOARG)
804 : /* print number of arguments */
805 1395 : snprintf(text + strlen(text), textlength - strlen(text), "%d", msg->extendedheader->noar);
806 : }
807 : else {
808 2491 : if ((flags & DLT_HEADER_SHOW_MSGTYPE) == DLT_HEADER_SHOW_MSGTYPE)
809 1431 : snprintf(text + strlen(text), textlength - strlen(text), "--- ");
810 :
811 2491 : if ((flags & DLT_HEADER_SHOW_MSGSUBTYPE) == DLT_HEADER_SHOW_MSGSUBTYPE)
812 1431 : snprintf(text + strlen(text), textlength - strlen(text), "--- ");
813 :
814 2491 : if ((flags & DLT_HEADER_SHOW_VNVSTATUS) == DLT_HEADER_SHOW_VNVSTATUS)
815 1431 : snprintf(text + strlen(text), textlength - strlen(text), "N ");
816 :
817 2491 : if ((flags & DLT_HEADER_SHOW_NOARG) == DLT_HEADER_SHOW_NOARG)
818 1431 : snprintf(text + strlen(text), textlength - strlen(text), "-");
819 : }
820 :
821 : return DLT_RETURN_OK;
822 : }
823 :
824 3131 : DltReturnValue dlt_message_payload(DltMessage *msg, char *text, size_t textlength, int type, int verbose)
825 : {
826 : uint32_t id = 0, id_tmp = 0;
827 : uint8_t retval = 0;
828 :
829 : uint8_t *ptr;
830 : int32_t datalength;
831 :
832 : /* Pointer to ptr and datalength */
833 : uint8_t **pptr;
834 : int32_t *pdatalength;
835 :
836 : int ret = 0;
837 :
838 : int num;
839 : uint32_t type_info = 0, type_info_tmp = 0;
840 : int text_offset = 0;
841 :
842 3131 : PRINT_FUNCTION_VERBOSE(verbose);
843 :
844 3131 : if ((msg == NULL) || (msg->databuffer == NULL) || (text == NULL) ||
845 3072 : (type < DLT_OUTPUT_HEX) || (type > DLT_OUTPUT_ASCII_LIMITED))
846 : return DLT_RETURN_WRONG_PARAMETER;
847 :
848 2941 : if (textlength <= 0) {
849 10 : dlt_log(LOG_WARNING, "String does not fit binary data!\n");
850 10 : return DLT_RETURN_WRONG_PARAMETER;
851 : }
852 :
853 : /* start with empty string */
854 2931 : text[0] = 0;
855 :
856 : /* print payload only as hex */
857 2931 : if (type == DLT_OUTPUT_HEX)
858 526 : return dlt_print_hex_string(text, (int)textlength, msg->databuffer, (int)msg->datasize);
859 :
860 : /* print payload as mixed */
861 2405 : if (type == DLT_OUTPUT_MIXED_FOR_PLAIN)
862 526 : return dlt_print_mixed_string(text, (int)textlength, msg->databuffer, (int)msg->datasize, 0);
863 :
864 1879 : if (type == DLT_OUTPUT_MIXED_FOR_HTML)
865 526 : return dlt_print_mixed_string(text, (int)textlength, msg->databuffer, (int)msg->datasize, 1);
866 :
867 1353 : ptr = msg->databuffer;
868 1353 : datalength = (int32_t)msg->datasize;
869 :
870 : /* Pointer to ptr and datalength */
871 : pptr = &ptr;
872 : pdatalength = &datalength;
873 :
874 : /* non-verbose mode */
875 :
876 : /* print payload as hex */
877 1353 : if (DLT_MSG_IS_NONVERBOSE(msg)) {
878 :
879 537 : DLT_MSG_READ_VALUE(id_tmp, ptr, datalength, uint32_t);
880 537 : id = DLT_ENDIAN_GET_32(msg->standardheader->htyp, id_tmp);
881 :
882 537 : if ((datalength < 0) || (textlength < (((unsigned int)datalength * 3) + 20))) {
883 0 : dlt_vlog(LOG_WARNING,
884 : "String does not fit binary data (available=%zu, required=%zu) !\n",
885 0 : (size_t)textlength, ((size_t)datalength * 3U) + 20U);
886 0 : return DLT_RETURN_ERROR;
887 : }
888 :
889 : /* process message id / service id */
890 537 : if (DLT_MSG_IS_CONTROL(msg)) {
891 60 : if ((id > 0) && (id < DLT_SERVICE_ID_LAST_ENTRY))
892 57 : snprintf(text + strlen(text), textlength - strlen(text), "%s",
893 : service_id_name[id]); /* service id */
894 3 : else if (!(DLT_MSG_IS_CONTROL_TIME(msg)))
895 3 : snprintf(text + strlen(text), textlength - strlen(text), "service(%u)", id); /* service id */
896 :
897 60 : if (datalength > 0)
898 60 : snprintf(text + strlen(text), textlength - strlen(text), ", ");
899 : }
900 : else {
901 477 : snprintf(text + strlen(text), textlength - strlen(text), "%u, ", id); /* message id */
902 : }
903 :
904 : /* process return value */
905 537 : if (DLT_MSG_IS_CONTROL_RESPONSE(msg)) {
906 4 : if (datalength > 0) {
907 4 : DLT_MSG_READ_VALUE(retval, ptr, datalength, uint8_t); /* No endian conversion necessary */
908 :
909 4 : if ((retval < DLT_SERVICE_RESPONSE_LAST) || (retval == 8))
910 3 : snprintf(text + strlen(text), textlength - strlen(text), "%s", return_type[retval]);
911 : else
912 1 : snprintf(text + strlen(text), textlength - strlen(text), "%.2x", retval);
913 :
914 4 : if (datalength >= 1)
915 2 : snprintf(text + strlen(text), textlength - strlen(text), ", ");
916 : }
917 : }
918 :
919 537 : if (type == DLT_OUTPUT_ASCII_LIMITED) {
920 122 : ret = dlt_print_hex_string(text + strlen(text),
921 122 : (int)((size_t)textlength - strlen(text)),
922 : ptr,
923 122 : (datalength > DLT_COMMON_ASCII_LIMIT_MAX_CHARS ? DLT_COMMON_ASCII_LIMIT_MAX_CHARS : datalength));
924 :
925 122 : if ((datalength > DLT_COMMON_ASCII_LIMIT_MAX_CHARS) &&
926 6 : ((textlength - strlen(text)) > 4))
927 6 : snprintf(text + strlen(text), textlength - strlen(text), " ...");
928 : }
929 : else {
930 415 : ret = dlt_print_hex_string(text + strlen(text), (int)((size_t)textlength - strlen(text)), ptr, datalength);
931 : }
932 :
933 537 : return ret;
934 : }
935 :
936 : /* At this point, it is ensured that a extended header is available */
937 :
938 : /* verbose mode */
939 : type_info = 0;
940 : type_info_tmp = 0;
941 :
942 3361 : for (num = 0; num < (int)(msg->extendedheader->noar); num++) {
943 2545 : if (num != 0) {
944 1743 : text_offset = (int)strlen(text);
945 1743 : snprintf(text + text_offset, textlength - (size_t)text_offset, " ");
946 : }
947 :
948 : /* first read the type info of the argument */
949 2545 : DLT_MSG_READ_VALUE(type_info_tmp, ptr, datalength, uint32_t);
950 2545 : type_info = DLT_ENDIAN_GET_32(msg->standardheader->htyp, type_info_tmp);
951 :
952 : /* print out argument */
953 2545 : text_offset = (int)strlen(text);
954 :
955 2545 : if (dlt_message_argument_print(msg, type_info, pptr, pdatalength,
956 2545 : (text + text_offset), (textlength - (size_t)text_offset), -1,
957 : 0) == DLT_RETURN_ERROR)
958 : return DLT_RETURN_ERROR;
959 : }
960 :
961 : return DLT_RETURN_OK;
962 : }
963 :
964 742 : DltReturnValue dlt_message_filter_check(DltMessage *msg, DltFilter *filter, int verbose)
965 : {
966 : /* check the filters if message is used */
967 : int num;
968 : DltReturnValue found = DLT_RETURN_OK;
969 :
970 742 : PRINT_FUNCTION_VERBOSE(verbose);
971 :
972 742 : if ((msg == NULL) || (filter == NULL))
973 : return DLT_RETURN_WRONG_PARAMETER;
974 :
975 736 : if ((filter->counter == 0) || (!(DLT_IS_HTYP_UEH(msg->standardheader->htyp))))
976 : /* no filter is set, or no extended header is available, so do as filter is matching */
977 : return DLT_RETURN_TRUE;
978 :
979 936 : for (num = 0; num < filter->counter; num++)
980 : /* check each filter if it matches */
981 624 : if ((DLT_IS_HTYP_UEH(msg->standardheader->htyp)) &&
982 624 : ((filter->apid[num][0] == 0) || (memcmp(filter->apid[num], msg->extendedheader->apid, DLT_ID_SIZE) == 0)) &&
983 0 : ((filter->ctid[num][0] == 0) || (memcmp(filter->ctid[num], msg->extendedheader->ctid, DLT_ID_SIZE) == 0)) &&
984 0 : ((filter->log_level[num] == 0) ||
985 0 : (filter->log_level[num] == DLT_GET_MSIN_MTIN(msg->extendedheader->msin))) &&
986 0 : ((filter->payload_min[num] == 0) || (filter->payload_min[num] <= msg->datasize)) &&
987 0 : ((filter->payload_max[num] == 0) || (filter->payload_max[num] >= msg->datasize))) {
988 : found = DLT_RETURN_TRUE;
989 : break;
990 : }
991 :
992 : return found;
993 : }
994 :
995 6686 : int dlt_message_read(DltMessage *msg, uint8_t *buffer, unsigned int length, int resync, int verbose)
996 : {
997 : uint32_t extra_size = 0;
998 :
999 6686 : PRINT_FUNCTION_VERBOSE(verbose);
1000 :
1001 6686 : if ((msg == NULL) || (buffer == NULL) || (length <= 0))
1002 : return DLT_MESSAGE_ERROR_UNKNOWN;
1003 :
1004 : /* initialize resync_offset */
1005 6250 : msg->resync_offset = 0;
1006 :
1007 : /* check if message contains serial header, smaller than standard header */
1008 6250 : if (length < sizeof(dltSerialHeader))
1009 : /* dlt_log(LOG_ERR, "Length smaller than serial header!\n"); */
1010 : return DLT_MESSAGE_ERROR_SIZE;
1011 :
1012 6250 : if (memcmp(buffer, dltSerialHeader, sizeof(dltSerialHeader)) == 0) {
1013 : /* serial header found */
1014 0 : msg->found_serialheader = 1;
1015 0 : buffer += sizeof(dltSerialHeader);
1016 0 : length -= (unsigned int)sizeof(dltSerialHeader);
1017 : }
1018 : else {
1019 : /* serial header not found */
1020 6250 : msg->found_serialheader = 0;
1021 :
1022 6250 : if (resync) {
1023 : /* resync if necessary */
1024 : msg->resync_offset = 0;
1025 :
1026 : do {
1027 0 : if (memcmp(buffer + msg->resync_offset, dltSerialHeader, sizeof(dltSerialHeader)) == 0) {
1028 : /* serial header found */
1029 0 : msg->found_serialheader = 1;
1030 0 : buffer += sizeof(dltSerialHeader);
1031 0 : length -= (unsigned int)sizeof(dltSerialHeader);
1032 0 : break;
1033 : }
1034 :
1035 0 : msg->resync_offset++;
1036 0 : } while ((sizeof(dltSerialHeader) + (size_t)msg->resync_offset) <= length);
1037 :
1038 : /* Set new start offset */
1039 0 : if (msg->resync_offset > 0) {
1040 : /* Resyncing connection */
1041 0 : buffer += msg->resync_offset;
1042 0 : length -= (unsigned int)msg->resync_offset;
1043 : }
1044 : }
1045 : }
1046 :
1047 : /* check that standard header fits buffer */
1048 6250 : if (length < sizeof(DltStandardHeader))
1049 : /* dlt_log(LOG_ERR, "Length smaller than standard header!\n"); */
1050 : return DLT_MESSAGE_ERROR_SIZE;
1051 :
1052 6250 : memcpy(msg->headerbuffer + sizeof(DltStorageHeader), buffer, sizeof(DltStandardHeader));
1053 :
1054 : /* set ptrs to structures */
1055 6250 : msg->storageheader = (DltStorageHeader *)msg->headerbuffer;
1056 6250 : msg->standardheader = (DltStandardHeader *)(msg->headerbuffer + sizeof(DltStorageHeader));
1057 :
1058 : /* calculate complete size of headers */
1059 6250 : extra_size = (uint32_t) (DLT_STANDARD_HEADER_EXTRA_SIZE(msg->standardheader->htyp) +
1060 : (DLT_IS_HTYP_UEH(msg->standardheader->htyp) ? sizeof(DltExtendedHeader) : 0));
1061 6250 : msg->headersize = (int32_t) (sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + extra_size);
1062 6250 : msg->datasize = (int32_t) ((uint32_t)DLT_BETOH_16(msg->standardheader->len) - (uint32_t)msg->headersize + (uint32_t) sizeof(DltStorageHeader));
1063 :
1064 : /* calculate complete size of payload */
1065 : int32_t temp_datasize;
1066 6250 : temp_datasize = DLT_BETOH_16(msg->standardheader->len) - (int32_t) msg->headersize + (int32_t) sizeof(DltStorageHeader);
1067 :
1068 : /* check data size */
1069 6250 : if (temp_datasize < 0) {
1070 0 : dlt_vlog(LOG_WARNING,
1071 : "Plausibility check failed. Complete message size too short (%d)!\n",
1072 : temp_datasize);
1073 0 : return DLT_MESSAGE_ERROR_CONTENT;
1074 : }
1075 : else {
1076 6250 : msg->datasize = (int32_t) temp_datasize;
1077 : }
1078 :
1079 : /* check if verbose mode is on*/
1080 6250 : if (verbose) {
1081 0 : dlt_vlog(LOG_DEBUG, "BufferLength=%u, HeaderSize=%u, DataSize=%u\n",
1082 : length, msg->headersize, msg->datasize);
1083 : }
1084 :
1085 : /* load standard header extra parameters and Extended header if used */
1086 6250 : if (extra_size > 0) {
1087 6250 : if (length < (size_t)((int32_t)msg->headersize - (int32_t)sizeof(DltStorageHeader)))
1088 : return DLT_MESSAGE_ERROR_SIZE;
1089 :
1090 6250 : memcpy(msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader),
1091 6250 : buffer + sizeof(DltStandardHeader), (size_t)extra_size);
1092 :
1093 : /* set extended header ptr and get standard header extra parameters */
1094 6250 : if (DLT_IS_HTYP_UEH(msg->standardheader->htyp))
1095 6250 : msg->extendedheader =
1096 6250 : (DltExtendedHeader *)(msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) +
1097 6250 : DLT_STANDARD_HEADER_EXTRA_SIZE(msg->standardheader->htyp));
1098 : else
1099 0 : msg->extendedheader = NULL;
1100 :
1101 6250 : dlt_message_get_extraparameters(msg, verbose);
1102 : }
1103 :
1104 : /* check if payload fits length */
1105 6250 : if (length < (size_t)((int32_t)msg->headersize - (int32_t)sizeof(DltStorageHeader) + msg->datasize))
1106 : /* dlt_log(LOG_ERR,"length does not fit!\n"); */
1107 : return DLT_MESSAGE_ERROR_SIZE;
1108 :
1109 : /* free last used memory for buffer */
1110 6040 : if (msg->databuffer) {
1111 6023 : if (msg->datasize > msg->databuffersize) {
1112 9 : free(msg->databuffer);
1113 9 : msg->databuffer = (uint8_t *)malloc((size_t)msg->datasize);
1114 9 : msg->databuffersize = msg->datasize;
1115 : }
1116 : }
1117 : else {
1118 : /* get new memory for buffer */
1119 17 : msg->databuffer = (uint8_t *)malloc((size_t)msg->datasize);
1120 17 : msg->databuffersize = msg->datasize;
1121 : }
1122 :
1123 6040 : if (msg->databuffer == NULL) {
1124 0 : dlt_vlog(LOG_WARNING,
1125 : "Cannot allocate memory for payload buffer of size %u!\n",
1126 : msg->datasize);
1127 0 : return DLT_MESSAGE_ERROR_UNKNOWN;
1128 : }
1129 :
1130 : /* load payload data from buffer */
1131 6040 : memcpy(msg->databuffer, buffer + (size_t)((int32_t)msg->headersize - (int32_t)sizeof(DltStorageHeader)), (size_t)msg->datasize);
1132 :
1133 6040 : return DLT_MESSAGE_ERROR_OK;
1134 : }
1135 :
1136 7227 : DltReturnValue dlt_message_get_extraparameters(DltMessage *msg, int verbose)
1137 : {
1138 7227 : PRINT_FUNCTION_VERBOSE(verbose);
1139 :
1140 7227 : if (msg == NULL)
1141 : return DLT_RETURN_WRONG_PARAMETER;
1142 :
1143 7225 : if (DLT_IS_HTYP_WEID(msg->standardheader->htyp))
1144 7031 : memcpy(msg->headerextra.ecu,
1145 : msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader),
1146 : DLT_ID_SIZE);
1147 :
1148 7225 : if (DLT_IS_HTYP_WSID(msg->standardheader->htyp)) {
1149 6733 : memcpy(&(msg->headerextra.seid), msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader)
1150 6733 : + (DLT_IS_HTYP_WEID(msg->standardheader->htyp) ? DLT_SIZE_WEID : 0), DLT_SIZE_WSID);
1151 6733 : msg->headerextra.seid = DLT_BETOH_32(msg->headerextra.seid);
1152 : }
1153 :
1154 7225 : if (DLT_IS_HTYP_WTMS(msg->standardheader->htyp)) {
1155 14062 : memcpy(&(msg->headerextra.tmsp), msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader)
1156 7031 : + (DLT_IS_HTYP_WEID(msg->standardheader->htyp) ? DLT_SIZE_WEID : 0)
1157 7031 : + (DLT_IS_HTYP_WSID(msg->standardheader->htyp) ? DLT_SIZE_WSID : 0), DLT_SIZE_WTMS);
1158 7031 : msg->headerextra.tmsp = DLT_BETOH_32(msg->headerextra.tmsp);
1159 : }
1160 :
1161 : return DLT_RETURN_OK;
1162 : }
1163 :
1164 6247 : DltReturnValue dlt_message_set_extraparameters(DltMessage *msg, int verbose)
1165 : {
1166 6247 : PRINT_FUNCTION_VERBOSE(verbose);
1167 :
1168 6247 : if (msg == NULL)
1169 : return DLT_RETURN_WRONG_PARAMETER;
1170 :
1171 6245 : if (DLT_IS_HTYP_WEID(msg->standardheader->htyp))
1172 6049 : memcpy(msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader),
1173 6049 : msg->headerextra.ecu,
1174 : DLT_ID_SIZE);
1175 :
1176 6245 : if (DLT_IS_HTYP_WSID(msg->standardheader->htyp)) {
1177 5999 : msg->headerextra.seid = DLT_HTOBE_32(msg->headerextra.seid);
1178 5999 : memcpy(msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader)
1179 5999 : + (DLT_IS_HTYP_WEID(msg->standardheader->htyp) ? DLT_SIZE_WEID : 0),
1180 5999 : &(msg->headerextra.seid),
1181 : DLT_SIZE_WSID);
1182 : }
1183 :
1184 6245 : if (DLT_IS_HTYP_WTMS(msg->standardheader->htyp)) {
1185 6049 : msg->headerextra.tmsp = DLT_HTOBE_32(msg->headerextra.tmsp);
1186 12098 : memcpy(msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader)
1187 6049 : + (DLT_IS_HTYP_WEID(msg->standardheader->htyp) ? DLT_SIZE_WEID : 0)
1188 6049 : + (DLT_IS_HTYP_WSID(msg->standardheader->htyp) ? DLT_SIZE_WSID : 0),
1189 6049 : &(msg->headerextra.tmsp),
1190 : DLT_SIZE_WTMS);
1191 : }
1192 :
1193 : return DLT_RETURN_OK;
1194 : }
1195 :
1196 54 : DltReturnValue dlt_file_init(DltFile *file, int verbose)
1197 : {
1198 54 : PRINT_FUNCTION_VERBOSE(verbose);
1199 :
1200 54 : if (file == NULL)
1201 : return DLT_RETURN_WRONG_PARAMETER;
1202 :
1203 : /* initalise structure parameters */
1204 54 : file->handle = NULL;
1205 54 : file->counter = 0;
1206 54 : file->counter_total = 0;
1207 54 : file->index = NULL;
1208 :
1209 54 : file->filter = NULL;
1210 54 : file->filter_counter = 0;
1211 54 : file->file_position = 0;
1212 :
1213 54 : file->position = 0;
1214 :
1215 54 : file->error_messages = 0;
1216 :
1217 54 : return dlt_message_init(&(file->msg), verbose);
1218 : }
1219 :
1220 6 : DltReturnValue dlt_file_set_filter(DltFile *file, DltFilter *filter, int verbose)
1221 : {
1222 6 : PRINT_FUNCTION_VERBOSE(verbose);
1223 :
1224 6 : if (file == NULL)
1225 : return DLT_RETURN_WRONG_PARAMETER;
1226 :
1227 : /* set filter */
1228 6 : file->filter = filter;
1229 :
1230 6 : return DLT_RETURN_OK;
1231 : }
1232 :
1233 6627 : DltReturnValue dlt_file_read_header(DltFile *file, int verbose)
1234 : {
1235 6627 : PRINT_FUNCTION_VERBOSE(verbose);
1236 :
1237 6627 : if (file == NULL)
1238 : return DLT_RETURN_WRONG_PARAMETER;
1239 :
1240 : /* Loop until storage header is found */
1241 : while (1) {
1242 : /* load header from file */
1243 13254 : if (fread(file->msg.headerbuffer,
1244 : sizeof(DltStorageHeader) + sizeof(DltStandardHeader), 1,
1245 : file->handle) != 1) {
1246 38 : if (!feof(file->handle))
1247 0 : dlt_log(LOG_WARNING, "Cannot read header from file!\n");
1248 : else
1249 38 : dlt_log(LOG_DEBUG, "Reached end of file\n");
1250 :
1251 38 : return DLT_RETURN_ERROR;
1252 : }
1253 :
1254 : /* set ptrs to structures */
1255 6589 : file->msg.storageheader = (DltStorageHeader *)file->msg.headerbuffer;
1256 6589 : file->msg.standardheader = (DltStandardHeader *)(file->msg.headerbuffer +
1257 : sizeof(DltStorageHeader));
1258 :
1259 : /* check id of storage header */
1260 6589 : if (dlt_check_storageheader(file->msg.storageheader) != DLT_RETURN_TRUE) {
1261 : /* Shift the position back to the place where it stared to read + 1 */
1262 0 : if (fseek(file->handle,
1263 : (long) (1 - (sizeof(DltStorageHeader) + sizeof(DltStandardHeader))),
1264 : SEEK_CUR) < 0) {
1265 0 : dlt_log(LOG_WARNING, "DLT storage header pattern not found!\n");
1266 0 : return DLT_RETURN_ERROR;
1267 : }
1268 : }
1269 : else {
1270 : /* storage header is found */
1271 : break;
1272 : }
1273 : }
1274 :
1275 : /* calculate complete size of headers */
1276 6589 : file->msg.headersize = (int32_t) (sizeof(DltStorageHeader) + sizeof(DltStandardHeader) +
1277 6589 : DLT_STANDARD_HEADER_EXTRA_SIZE(file->msg.standardheader->htyp) +
1278 : (DLT_IS_HTYP_UEH(file->msg.standardheader->htyp) ? (uint32_t)sizeof(DltExtendedHeader) : 0U));
1279 :
1280 : /* calculate complete size of payload */
1281 : int32_t temp_datasize;
1282 6589 : temp_datasize = DLT_BETOH_16(file->msg.standardheader->len) + (int32_t) sizeof(DltStorageHeader) - (int32_t) file->msg.headersize;
1283 :
1284 : /* check data size */
1285 6589 : if (temp_datasize < 0) {
1286 0 : dlt_vlog(LOG_WARNING,
1287 : "Plausibility check failed. Complete message size too short! (%d)\n",
1288 : temp_datasize);
1289 0 : return DLT_RETURN_ERROR;
1290 : } else {
1291 6589 : file->msg.datasize = temp_datasize;
1292 : }
1293 :
1294 : /* check if verbose mode is on */
1295 6589 : if (verbose) {
1296 0 : dlt_vlog(LOG_DEBUG, "HeaderSize=%u, DataSize=%u\n",
1297 : file->msg.headersize, file->msg.datasize);
1298 : }
1299 :
1300 : return DLT_RETURN_OK;
1301 : }
1302 :
1303 0 : DltReturnValue dlt_file_read_header_raw(DltFile *file, int resync, int verbose)
1304 : {
1305 : char dltSerialHeaderBuffer[DLT_ID_SIZE];
1306 :
1307 0 : PRINT_FUNCTION_VERBOSE(verbose);
1308 :
1309 0 : if (file == NULL)
1310 : return DLT_RETURN_WRONG_PARAMETER;
1311 :
1312 : /* check if serial header exists, ignore if found */
1313 0 : if (fread(dltSerialHeaderBuffer, sizeof(dltSerialHeaderBuffer), 1, file->handle) != 1) {
1314 : /* cannot read serial header, not enough data available in file */
1315 0 : if (!feof(file->handle))
1316 0 : dlt_log(LOG_WARNING, "Cannot read header from file!\n");
1317 :
1318 0 : return DLT_RETURN_ERROR;
1319 : }
1320 :
1321 0 : if (memcmp(dltSerialHeaderBuffer, dltSerialHeader, sizeof(dltSerialHeader)) == 0) {
1322 : /* serial header found */
1323 : /* nothing to do continue reading */
1324 :
1325 : }
1326 : else {
1327 : /* serial header not found */
1328 0 : if (resync) {
1329 : /* increase error counter */
1330 0 : file->error_messages++;
1331 :
1332 : /* resync to serial header */
1333 : do {
1334 : memmove(dltSerialHeaderBuffer, dltSerialHeaderBuffer + 1, sizeof(dltSerialHeader) - 1);
1335 :
1336 0 : if (fread(dltSerialHeaderBuffer + 3, 1, 1, file->handle) != 1)
1337 : /* cannot read any data, perhaps end of file reached */
1338 : return DLT_RETURN_ERROR;
1339 :
1340 0 : if (memcmp(dltSerialHeaderBuffer, dltSerialHeader, sizeof(dltSerialHeader)) == 0)
1341 : /* serial header synchronised */
1342 : break;
1343 : } while (1);
1344 : }
1345 : else
1346 : /* go back to last file position */
1347 0 : if (0 != fseek(file->handle, (long)file->file_position, SEEK_SET))
1348 : {
1349 : return DLT_RETURN_ERROR;
1350 : }
1351 : }
1352 :
1353 : /* load header from file */
1354 0 : if (fread(file->msg.headerbuffer + sizeof(DltStorageHeader), sizeof(DltStandardHeader), 1, file->handle) != 1) {
1355 0 : if (!feof(file->handle))
1356 0 : dlt_log(LOG_WARNING, "Cannot read header from file!\n");
1357 :
1358 0 : return DLT_RETURN_ERROR;
1359 : }
1360 :
1361 : /* set ptrs to structures */
1362 0 : file->msg.storageheader = (DltStorageHeader *)file->msg.headerbuffer; /* this points now to a empty storage header (filled with '0') */
1363 0 : file->msg.standardheader = (DltStandardHeader *)(file->msg.headerbuffer + sizeof(DltStorageHeader));
1364 :
1365 : /* Skip storage header field, fill this field with '0' */
1366 : memset(file->msg.storageheader, 0, sizeof(DltStorageHeader));
1367 :
1368 : /* Set storage header */
1369 0 : dlt_set_storageheader(file->msg.storageheader, DLT_COMMON_DUMMY_ECUID);
1370 :
1371 : /* no check for storage header id*/
1372 :
1373 : /* calculate complete size of headers */
1374 0 : file->msg.headersize = (int32_t) (sizeof(DltStorageHeader) + sizeof(DltStandardHeader) +
1375 0 : DLT_STANDARD_HEADER_EXTRA_SIZE(file->msg.standardheader->htyp) +
1376 : (DLT_IS_HTYP_UEH(file->msg.standardheader->htyp) ? (uint32_t)sizeof(DltExtendedHeader) : 0U));
1377 :
1378 : /* calculate complete size of payload */
1379 : int32_t temp_datasize;
1380 0 : temp_datasize = DLT_BETOH_16(file->msg.standardheader->len) + (int32_t) sizeof(DltStorageHeader) - (int32_t) file->msg.headersize;
1381 :
1382 : /* check data size */
1383 0 : if (temp_datasize < 0) {
1384 0 : dlt_vlog(LOG_WARNING,
1385 : "Plausibility check failed. Complete message size too short! (%d)\n",
1386 : temp_datasize);
1387 0 : return DLT_RETURN_ERROR;
1388 : }
1389 : else {
1390 0 : file->msg.datasize = temp_datasize;
1391 : }
1392 :
1393 : /* check if verbose mode is on */
1394 0 : if (verbose) {
1395 0 : dlt_vlog(LOG_DEBUG, "HeaderSize=%u, DataSize=%u\n",
1396 : file->msg.headersize, file->msg.datasize);
1397 : }
1398 :
1399 : return DLT_RETURN_OK;
1400 : }
1401 :
1402 4505 : DltReturnValue dlt_file_read_header_extended(DltFile *file, int verbose)
1403 : {
1404 4505 : PRINT_FUNCTION_VERBOSE(verbose);
1405 :
1406 4505 : if (file == NULL)
1407 : return DLT_RETURN_WRONG_PARAMETER;
1408 :
1409 : /* load standard header extra parameters if used */
1410 4505 : if (DLT_STANDARD_HEADER_EXTRA_SIZE(file->msg.standardheader->htyp)) {
1411 1530 : if (fread(file->msg.headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader),
1412 : DLT_STANDARD_HEADER_EXTRA_SIZE(file->msg.standardheader->htyp),
1413 : 1, file->handle) != 1) {
1414 0 : dlt_log(LOG_WARNING, "Cannot read standard header extra parameters from file!\n");
1415 0 : return DLT_RETURN_ERROR;
1416 : }
1417 :
1418 765 : dlt_message_get_extraparameters(&(file->msg), verbose);
1419 : }
1420 :
1421 : /* load Extended header if used */
1422 4505 : if (DLT_IS_HTYP_UEH(file->msg.standardheader->htyp) == 0)
1423 : /* there is nothing to be loaded */
1424 : return DLT_RETURN_OK;
1425 :
1426 2173 : if (fread(file->msg.headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) +
1427 2173 : DLT_STANDARD_HEADER_EXTRA_SIZE(file->msg.standardheader->htyp),
1428 : (DLT_IS_HTYP_UEH(file->msg.standardheader->htyp) ? sizeof(DltExtendedHeader) : 0),
1429 : 1, file->handle) != 1) {
1430 0 : dlt_log(LOG_WARNING, "Cannot read extended header from file!\n");
1431 0 : return DLT_RETURN_ERROR;
1432 : }
1433 :
1434 : /* set extended header ptr */
1435 2173 : if (DLT_IS_HTYP_UEH(file->msg.standardheader->htyp))
1436 2173 : file->msg.extendedheader =
1437 2173 : (DltExtendedHeader *)(file->msg.headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) +
1438 2173 : DLT_STANDARD_HEADER_EXTRA_SIZE(file->msg.standardheader->htyp));
1439 : else
1440 0 : file->msg.extendedheader = NULL;
1441 :
1442 : return DLT_RETURN_OK;
1443 : }
1444 :
1445 3875 : DltReturnValue dlt_file_read_data(DltFile *file, int verbose)
1446 : {
1447 3875 : PRINT_FUNCTION_VERBOSE(verbose);
1448 :
1449 3875 : if (file == NULL)
1450 : return DLT_RETURN_WRONG_PARAMETER;
1451 :
1452 : /* free last used memory for buffer */
1453 3875 : if (file->msg.databuffer && (file->msg.databuffersize < file->msg.datasize)) {
1454 129 : free(file->msg.databuffer);
1455 129 : file->msg.databuffer = NULL;
1456 : }
1457 :
1458 3875 : if (file->msg.databuffer == NULL) {
1459 : /* get new memory for buffer */
1460 168 : file->msg.databuffer = (uint8_t *)malloc((size_t)file->msg.datasize);
1461 168 : file->msg.databuffersize = file->msg.datasize;
1462 : }
1463 :
1464 3875 : if (file->msg.databuffer == NULL) {
1465 0 : dlt_vlog(LOG_WARNING,
1466 : "Cannot allocate memory for payload buffer of size %u!\n",
1467 : file->msg.datasize);
1468 0 : return DLT_RETURN_ERROR;
1469 : }
1470 :
1471 : /* load payload data from file */
1472 7750 : if (fread(file->msg.databuffer, (size_t)file->msg.datasize, 1, file->handle) != 1) {
1473 52 : if (file->msg.datasize != 0) {
1474 0 : dlt_vlog(LOG_WARNING,
1475 : "Cannot read payload data from file of size %u!\n",
1476 : file->msg.datasize);
1477 0 : return DLT_RETURN_ERROR;
1478 : }
1479 : }
1480 :
1481 : return DLT_RETURN_OK;
1482 : }
1483 :
1484 50 : DltReturnValue dlt_file_open(DltFile *file, const char *filename, int verbose)
1485 : {
1486 50 : PRINT_FUNCTION_VERBOSE(verbose);
1487 :
1488 50 : if ((file == NULL) || (filename == NULL))
1489 : return DLT_RETURN_WRONG_PARAMETER;
1490 :
1491 : /* reset counters */
1492 44 : file->counter = 0;
1493 44 : file->counter_total = 0;
1494 44 : file->position = 0;
1495 44 : file->file_position = 0;
1496 44 : file->file_length = 0;
1497 44 : file->error_messages = 0;
1498 :
1499 44 : if (file->handle)
1500 0 : fclose(file->handle);
1501 :
1502 : /* open dlt file */
1503 44 : file->handle = fopen(filename, "rb");
1504 :
1505 44 : if (file->handle == NULL) {
1506 1 : dlt_vlog(LOG_WARNING, "File %s cannot be opened!\n", filename);
1507 1 : return DLT_RETURN_ERROR;
1508 : }
1509 :
1510 43 : if (0 != fseek(file->handle, 0, SEEK_END)) {
1511 0 : dlt_vlog(LOG_WARNING, "dlt_file_open: Seek failed to 0,SEEK_END");
1512 0 : return DLT_RETURN_ERROR;
1513 : }
1514 :
1515 43 : file->file_length = (uint64_t)ftell(file->handle);
1516 :
1517 43 : if (0 != fseek(file->handle, 0, SEEK_SET)) {
1518 0 : dlt_vlog(LOG_WARNING, "dlt_file_open: Seek failed to 0,SEEK_SET");
1519 0 : return DLT_RETURN_ERROR;
1520 : }
1521 :
1522 43 : if (verbose)
1523 : /* print file length */
1524 1 : dlt_vlog(LOG_DEBUG, "File is %" PRIu64 "bytes long\n", file->file_length);
1525 :
1526 : return DLT_RETURN_OK;
1527 : }
1528 :
1529 2752 : DltReturnValue dlt_file_read(DltFile *file, int verbose)
1530 : {
1531 : long *ptr;
1532 : int found = DLT_RETURN_OK;
1533 :
1534 2752 : if (file == NULL)
1535 : return DLT_RETURN_WRONG_PARAMETER;
1536 :
1537 2752 : if (verbose)
1538 0 : dlt_vlog(LOG_DEBUG, "%s: Message %d:\n", __func__, file->counter_total);
1539 :
1540 : /* allocate new memory for index if number of messages exceeds a multiple of DLT_COMMON_INDEX_ALLOC (e.g.: 1000) */
1541 2752 : if (file->counter % DLT_COMMON_INDEX_ALLOC == 0) {
1542 350 : ptr = (long *)malloc((size_t)((file->counter / DLT_COMMON_INDEX_ALLOC) + 1) * (size_t)DLT_COMMON_INDEX_ALLOC * sizeof(long));
1543 :
1544 350 : if (ptr == NULL)
1545 : return DLT_RETURN_ERROR;
1546 :
1547 350 : if (file->index) {
1548 312 : memcpy(ptr, file->index, (size_t)(file->counter) * sizeof(long));
1549 312 : free(file->index);
1550 : }
1551 :
1552 350 : file->index = ptr;
1553 : }
1554 :
1555 : /* set to end of last succesful read message, because of conflicting calls to dlt_file_read and dlt_file_message */
1556 2752 : if (0 != fseek(file->handle, (long)file->file_position, SEEK_SET)) {
1557 0 : dlt_vlog(LOG_WARNING, "Seek failed to file_position %" PRIu64 "\n",
1558 : file->file_position);
1559 0 : return DLT_RETURN_ERROR;
1560 : }
1561 :
1562 : /* get file position at start of DLT message */
1563 2752 : if (verbose)
1564 0 : dlt_vlog(LOG_INFO, "Position in file: %" PRIu64 "\n", file->file_position);
1565 :
1566 : /* read header */
1567 2752 : if (dlt_file_read_header(file, verbose) < DLT_RETURN_OK) {
1568 : /* go back to last position in file */
1569 38 : if (0 != fseek(file->handle, (long)file->file_position, SEEK_SET)) {
1570 0 : dlt_vlog(LOG_WARNING, "Seek failed to file_position %" PRIu64 " \n",
1571 : file->file_position);
1572 : }
1573 38 : return DLT_RETURN_ERROR;
1574 : }
1575 :
1576 2714 : if (file->filter) {
1577 : /* read the extended header if filter is enabled and extended header exists */
1578 630 : if (dlt_file_read_header_extended(file, verbose) < DLT_RETURN_OK) {
1579 : /* go back to last position in file */
1580 0 : if (0 != fseek(file->handle, (long)file->file_position, SEEK_SET))
1581 0 : dlt_vlog(LOG_WARNING, "Seek to last file pos failed!\n");
1582 :
1583 0 : return DLT_RETURN_ERROR;
1584 : }
1585 :
1586 : /* check the filters if message is used */
1587 630 : if (dlt_message_filter_check(&(file->msg), file->filter, verbose) == DLT_RETURN_TRUE) {
1588 : /* filter matched, consequently store current message */
1589 : /* store index pointer to message position in DLT file */
1590 318 : file->index[file->counter] = (long)file->file_position;
1591 318 : file->counter++;
1592 318 : file->position = file->counter - 1;
1593 :
1594 : found = DLT_RETURN_TRUE;
1595 : }
1596 :
1597 : /* skip payload data */
1598 630 : if (fseek(file->handle, (long)file->msg.datasize, SEEK_CUR) != 0) {
1599 : /* go back to last position in file */
1600 0 : dlt_vlog(LOG_WARNING,
1601 : "Seek failed to skip payload data of size %u!\n",
1602 : file->msg.datasize);
1603 :
1604 0 : if (0 != fseek(file->handle, (long)file->file_position, SEEK_SET))
1605 0 : dlt_log(LOG_WARNING, "Seek back also failed!\n");
1606 :
1607 0 : return DLT_RETURN_ERROR;
1608 : }
1609 : }
1610 : else {
1611 : /* filter is disabled */
1612 : /* skip additional header parameters and payload data */
1613 2084 : if (fseek(file->handle,
1614 2084 : (long)((int32_t)file->msg.headersize - (int32_t)sizeof(DltStorageHeader) - (int32_t)sizeof(DltStandardHeader) + (long)file->msg.datasize),
1615 : SEEK_CUR)) {
1616 :
1617 0 : dlt_vlog(LOG_WARNING,
1618 : "Seek failed to skip extra header and payload data from file of size %u!\n",
1619 0 : file->msg.headersize - (int32_t)sizeof(DltStorageHeader) -
1620 0 : (int32_t)sizeof(DltStandardHeader) + file->msg.datasize);
1621 :
1622 : /* go back to last position in file */
1623 0 : if (fseek(file->handle, (long)file->file_position, SEEK_SET))
1624 0 : dlt_log(LOG_WARNING, "Seek back also failed!\n");
1625 :
1626 0 : return DLT_RETURN_ERROR;
1627 : }
1628 :
1629 : /* store index pointer to message position in DLT file */
1630 2084 : file->index[file->counter] = (long)file->file_position;
1631 2084 : file->counter++;
1632 2084 : file->position = file->counter - 1;
1633 :
1634 : found = DLT_RETURN_TRUE;
1635 : }
1636 :
1637 : /* increase total message counter */
1638 2714 : file->counter_total++;
1639 :
1640 : /* store position to next message */
1641 2714 : file->file_position = (uint64_t)ftell(file->handle);
1642 :
1643 2714 : return found;
1644 : }
1645 :
1646 0 : DltReturnValue dlt_file_read_raw(DltFile *file, int resync, int verbose)
1647 : {
1648 : int found = DLT_RETURN_OK;
1649 : long *ptr;
1650 :
1651 0 : if (verbose)
1652 0 : dlt_vlog(LOG_DEBUG, "%s: Message %d:\n", __func__, file->counter_total);
1653 :
1654 0 : if (file == NULL)
1655 : return DLT_RETURN_WRONG_PARAMETER;
1656 :
1657 : /* allocate new memory for index if number of messages exceeds a multiple of DLT_COMMON_INDEX_ALLOC (e.g.: 1000) */
1658 0 : if (file->counter % DLT_COMMON_INDEX_ALLOC == 0) {
1659 0 : ptr = (long *)malloc((size_t)((file->counter / DLT_COMMON_INDEX_ALLOC) + 1) * (size_t)DLT_COMMON_INDEX_ALLOC * sizeof(long));
1660 :
1661 0 : if (ptr == NULL)
1662 : return DLT_RETURN_ERROR;
1663 :
1664 0 : if (file->index) {
1665 0 : memcpy(ptr, file->index, (size_t)(file->counter) * sizeof(long));
1666 0 : free(file->index);
1667 : }
1668 :
1669 0 : file->index = ptr;
1670 : }
1671 :
1672 : /* set to end of last successful read message, because of conflicting calls to dlt_file_read and dlt_file_message */
1673 0 : if (0 != fseek(file->handle, (long)file->file_position, SEEK_SET))
1674 : return DLT_RETURN_ERROR;
1675 :
1676 : /* get file position at start of DLT message */
1677 0 : if (verbose)
1678 0 : dlt_vlog(LOG_DEBUG, "Position in file: %" PRIu64 "\n", file->file_position);
1679 :
1680 : /* read header */
1681 0 : if (dlt_file_read_header_raw(file, resync, verbose) < DLT_RETURN_OK) {
1682 : /* go back to last position in file */
1683 0 : if (0 != fseek(file->handle, (long)file->file_position, SEEK_SET))
1684 0 : dlt_log(LOG_WARNING, "dlt_file_read_raw, fseek failed 1\n");
1685 :
1686 0 : return DLT_RETURN_ERROR;
1687 : }
1688 :
1689 : /* read the extended header if filter is enabled and extended header exists */
1690 0 : if (dlt_file_read_header_extended(file, verbose) < DLT_RETURN_OK) {
1691 : /* go back to last position in file */
1692 0 : if (0 != fseek(file->handle, (long)file->file_position, SEEK_SET))
1693 0 : dlt_log(LOG_WARNING, "dlt_file_read_raw, fseek failed 2\n");
1694 :
1695 0 : return DLT_RETURN_ERROR;
1696 : }
1697 :
1698 0 : if (dlt_file_read_data(file, verbose) < DLT_RETURN_OK) {
1699 : /* go back to last position in file */
1700 0 : if (0 != fseek(file->handle, (long)file->file_position, SEEK_SET))
1701 0 : dlt_log(LOG_WARNING, "dlt_file_read_raw, fseek failed 3\n");
1702 :
1703 0 : return DLT_RETURN_ERROR;
1704 : }
1705 :
1706 : /* store index pointer to message position in DLT file */
1707 0 : file->index[file->counter] = (long)file->file_position;
1708 0 : file->counter++;
1709 0 : file->position = file->counter - 1;
1710 :
1711 : found = DLT_RETURN_TRUE;
1712 :
1713 : /* increase total message counter */
1714 0 : file->counter_total++;
1715 :
1716 : /* store position to next message */
1717 0 : file->file_position = (uint64_t)ftell(file->handle);
1718 :
1719 0 : return found;
1720 : }
1721 :
1722 0 : DltReturnValue dlt_file_close(DltFile *file, int verbose)
1723 : {
1724 0 : PRINT_FUNCTION_VERBOSE(verbose);
1725 :
1726 0 : if (file == NULL)
1727 : return DLT_RETURN_WRONG_PARAMETER;
1728 :
1729 0 : if (file->handle)
1730 0 : fclose(file->handle);
1731 :
1732 0 : file->handle = NULL;
1733 :
1734 0 : return DLT_RETURN_OK;
1735 : }
1736 :
1737 3770 : DltReturnValue dlt_file_message(DltFile *file, int index, int verbose)
1738 : {
1739 3770 : PRINT_FUNCTION_VERBOSE(verbose);
1740 :
1741 3770 : if (file == NULL)
1742 : return DLT_RETURN_WRONG_PARAMETER;
1743 :
1744 : /* check if message is in range */
1745 3770 : if (index < 0 || index >= file->counter) {
1746 0 : dlt_vlog(LOG_WARNING, "Message %d out of range!\r\n", index);
1747 0 : return DLT_RETURN_WRONG_PARAMETER;
1748 : }
1749 :
1750 : /* seek to position in file */
1751 3770 : if (fseek(file->handle, file->index[index], SEEK_SET) != 0) {
1752 0 : dlt_vlog(LOG_WARNING, "Seek to message %d to position %ld failed!\r\n",
1753 0 : index, file->index[index]);
1754 0 : return DLT_RETURN_ERROR;
1755 : }
1756 :
1757 : /* read all header and payload */
1758 3770 : if (dlt_file_read_header(file, verbose) < DLT_RETURN_OK)
1759 : return DLT_RETURN_ERROR;
1760 :
1761 3770 : if (dlt_file_read_header_extended(file, verbose) < DLT_RETURN_OK)
1762 : return DLT_RETURN_ERROR;
1763 :
1764 3770 : if (dlt_file_read_data(file, verbose) < DLT_RETURN_OK)
1765 : return DLT_RETURN_ERROR;
1766 :
1767 : /* set current position in file */
1768 3770 : file->position = index;
1769 :
1770 3770 : return DLT_RETURN_OK;
1771 : }
1772 :
1773 51 : DltReturnValue dlt_file_free(DltFile *file, int verbose)
1774 : {
1775 51 : PRINT_FUNCTION_VERBOSE(verbose);
1776 :
1777 51 : if (file == NULL)
1778 : return DLT_RETURN_WRONG_PARAMETER;
1779 :
1780 : /* delete index lost if exists */
1781 51 : if (file->index)
1782 36 : free(file->index);
1783 :
1784 51 : file->index = NULL;
1785 :
1786 : /* close file */
1787 51 : if (file->handle)
1788 41 : fclose(file->handle);
1789 :
1790 51 : file->handle = NULL;
1791 :
1792 51 : return dlt_message_free(&(file->msg), verbose);
1793 : }
1794 :
1795 : #if defined DLT_DAEMON_USE_FIFO_IPC || defined DLT_LIB_USE_FIFO_IPC
1796 24523 : void dlt_log_set_fifo_basedir(const char *pipe_dir)
1797 : {
1798 : strncpy(dltFifoBaseDir, pipe_dir, DLT_PATH_MAX);
1799 24523 : dltFifoBaseDir[DLT_PATH_MAX - 1] = 0;
1800 24514 : }
1801 : #endif
1802 :
1803 : #ifdef DLT_SHM_ENABLE
1804 : void dlt_log_set_shm_name(const char *env_shm_name)
1805 : {
1806 : strncpy(dltShmName, env_shm_name, NAME_MAX);
1807 : dltShmName[NAME_MAX] = 0;
1808 : }
1809 : #endif
1810 :
1811 0 : void dlt_print_with_attributes(bool state)
1812 : {
1813 0 : print_with_attributes = state;
1814 0 : }
1815 :
1816 24556 : DltReturnValue dlt_receiver_init(DltReceiver *receiver, int fd, DltReceiverType type, int buffersize)
1817 : {
1818 24556 : if (NULL == receiver)
1819 : return DLT_RETURN_WRONG_PARAMETER;
1820 :
1821 24556 : receiver->fd = fd;
1822 24556 : receiver->type = type;
1823 :
1824 : /** Reuse the receiver buffer if it exists and the buffer size
1825 : * is not changed. If not, free the old one and allocate a new buffer.
1826 : */
1827 24556 : if ((NULL != receiver->buffer) && ( buffersize != receiver->buffersize)) {
1828 0 : free(receiver->buffer);
1829 0 : receiver->buffer = NULL;
1830 : }
1831 :
1832 24556 : if (NULL == receiver->buffer) {
1833 24556 : receiver->lastBytesRcvd = 0;
1834 24556 : receiver->bytesRcvd = 0;
1835 24556 : receiver->totalBytesRcvd = 0;
1836 24556 : receiver->buf = NULL;
1837 24556 : receiver->backup_buf = NULL;
1838 24556 : receiver->buffer = (char *)calloc(1, (size_t)buffersize);
1839 24556 : receiver->buffersize = (int32_t)buffersize;
1840 : }
1841 :
1842 24556 : if (NULL == receiver->buffer) {
1843 0 : dlt_log(LOG_ERR, "allocate memory for receiver buffer failed.\n");
1844 0 : return DLT_RETURN_ERROR;
1845 : }
1846 : else {
1847 24556 : receiver->buf = receiver->buffer;
1848 : }
1849 :
1850 24556 : return DLT_RETURN_OK;
1851 : }
1852 :
1853 9 : DltReturnValue dlt_receiver_init_global_buffer(DltReceiver *receiver, int fd, DltReceiverType type, char **buffer)
1854 : {
1855 9 : if (receiver == NULL)
1856 : return DLT_RETURN_WRONG_PARAMETER;
1857 :
1858 9 : if (*buffer == NULL) {
1859 : /* allocating the buffer once and using it for all application receivers
1860 : * by keeping allocated buffer in app_recv_buffer global handle
1861 : */
1862 9 : *buffer = (char *)malloc(DLT_RECEIVE_BUFSIZE);
1863 :
1864 9 : if (*buffer == NULL)
1865 : return DLT_RETURN_ERROR;
1866 : }
1867 :
1868 9 : receiver->lastBytesRcvd = 0;
1869 9 : receiver->bytesRcvd = 0;
1870 9 : receiver->totalBytesRcvd = 0;
1871 9 : receiver->buffersize = DLT_RECEIVE_BUFSIZE;
1872 9 : receiver->fd = fd;
1873 9 : receiver->type = type;
1874 9 : receiver->buffer = *buffer;
1875 9 : receiver->backup_buf = NULL;
1876 9 : receiver->buf = receiver->buffer;
1877 :
1878 9 : return DLT_RETURN_OK;
1879 : }
1880 :
1881 24555 : DltReturnValue dlt_receiver_free(DltReceiver *receiver)
1882 : {
1883 :
1884 24555 : if (receiver == NULL)
1885 : return DLT_RETURN_WRONG_PARAMETER;
1886 :
1887 24555 : if (receiver->buffer)
1888 24553 : free(receiver->buffer);
1889 :
1890 24555 : if (receiver->backup_buf)
1891 0 : free(receiver->backup_buf);
1892 :
1893 24555 : receiver->buffer = NULL;
1894 24555 : receiver->buf = NULL;
1895 24555 : receiver->backup_buf = NULL;
1896 :
1897 24555 : return DLT_RETURN_OK;
1898 : }
1899 :
1900 9 : DltReturnValue dlt_receiver_free_global_buffer(DltReceiver *receiver)
1901 : {
1902 :
1903 9 : if (receiver == NULL)
1904 : return DLT_RETURN_WRONG_PARAMETER;
1905 :
1906 9 : if (receiver->backup_buf)
1907 0 : free(receiver->backup_buf);
1908 :
1909 9 : receiver->buffer = NULL;
1910 9 : receiver->buf = NULL;
1911 9 : receiver->backup_buf = NULL;
1912 :
1913 9 : return DLT_RETURN_OK;
1914 : }
1915 :
1916 1692 : int dlt_receiver_receive(DltReceiver *receiver)
1917 : {
1918 : socklen_t addrlen;
1919 :
1920 1692 : if (receiver == NULL)
1921 : return -1;
1922 :
1923 1692 : if (receiver->buffer == NULL)
1924 : return -1;
1925 :
1926 1691 : receiver->buf = (char *)receiver->buffer;
1927 1691 : receiver->lastBytesRcvd = receiver->bytesRcvd;
1928 :
1929 1691 : if ((receiver->lastBytesRcvd) && (receiver->backup_buf != NULL)) {
1930 1 : memcpy(receiver->buf, receiver->backup_buf, (size_t)receiver->lastBytesRcvd);
1931 1 : free(receiver->backup_buf);
1932 1 : receiver->backup_buf = NULL;
1933 : }
1934 :
1935 1691 : if (receiver->type == DLT_RECEIVE_SOCKET) {
1936 : /* wait for data from socket */
1937 437 : ssize_t bytes = recv(receiver->fd,
1938 437 : receiver->buf + receiver->lastBytesRcvd,
1939 437 : (size_t)(receiver->buffersize - receiver->lastBytesRcvd),
1940 : 0);
1941 873 : receiver->bytesRcvd = (bytes >= 0 && bytes <= INT32_MAX) ? (int32_t)bytes : 0;
1942 : }
1943 1254 : else if (receiver->type == DLT_RECEIVE_FD) {
1944 : /* wait for data from fd */
1945 1254 : ssize_t bytes = read(receiver->fd,
1946 1254 : receiver->buf + receiver->lastBytesRcvd,
1947 1254 : (size_t)(receiver->buffersize - receiver->lastBytesRcvd));
1948 2508 : receiver->bytesRcvd = (bytes >= 0 && bytes <= INT32_MAX) ? (int32_t)bytes : 0;
1949 : }
1950 : else { /* receiver->type == DLT_RECEIVE_UDP_SOCKET */
1951 : /* wait for data from UDP socket */
1952 0 : addrlen = sizeof(receiver->addr);
1953 0 : ssize_t bytes = recvfrom(receiver->fd,
1954 0 : receiver->buf + receiver->lastBytesRcvd,
1955 0 : (size_t)(receiver->buffersize - receiver->lastBytesRcvd),
1956 : 0,
1957 0 : (struct sockaddr *)&(receiver->addr),
1958 : &addrlen);
1959 0 : receiver->bytesRcvd = (bytes >= 0 && bytes <= INT32_MAX) ? (int32_t)bytes : 0;
1960 : }
1961 :
1962 1691 : if (receiver->bytesRcvd <= 0) {
1963 6 : receiver->bytesRcvd = 0;
1964 6 : return receiver->bytesRcvd;
1965 : } /* if */
1966 :
1967 1685 : receiver->totalBytesRcvd += receiver->bytesRcvd;
1968 1685 : receiver->bytesRcvd += receiver->lastBytesRcvd;
1969 :
1970 1685 : return receiver->bytesRcvd;
1971 : }
1972 :
1973 6096 : DltReturnValue dlt_receiver_remove(DltReceiver *receiver, int size)
1974 : {
1975 6096 : if (receiver == NULL)
1976 : return DLT_RETURN_WRONG_PARAMETER;
1977 :
1978 6139 : if (receiver->buf == NULL)
1979 : return DLT_RETURN_ERROR;
1980 :
1981 6139 : if ((size > receiver->bytesRcvd) || (size <= 0)) {
1982 0 : receiver->buf = receiver->buf + receiver->bytesRcvd;
1983 0 : receiver->bytesRcvd = 0;
1984 0 : return DLT_RETURN_WRONG_PARAMETER;
1985 : }
1986 :
1987 6139 : receiver->bytesRcvd = receiver->bytesRcvd - size;
1988 262 : receiver->buf = receiver->buf + size;
1989 :
1990 6096 : return DLT_RETURN_OK;
1991 : }
1992 :
1993 1686 : DltReturnValue dlt_receiver_move_to_begin(DltReceiver *receiver)
1994 : {
1995 1686 : if (receiver == NULL)
1996 : return DLT_RETURN_WRONG_PARAMETER;
1997 :
1998 1686 : if ((receiver->buffer == NULL) || (receiver->buf == NULL))
1999 : return DLT_RETURN_ERROR;
2000 :
2001 1686 : if ((receiver->buffer != receiver->buf) && (receiver->bytesRcvd != 0)) {
2002 1 : receiver->backup_buf = calloc((size_t)(receiver->bytesRcvd + 1), sizeof(char));
2003 :
2004 1 : if (receiver->backup_buf == NULL)
2005 0 : dlt_vlog(LOG_WARNING,
2006 : "Can't allocate memory for backup buf, there will be atleast"
2007 : "one corrupted message for fd[%d] \n", receiver->fd);
2008 : else
2009 1 : memcpy(receiver->backup_buf, receiver->buf, (size_t)receiver->bytesRcvd);
2010 : }
2011 :
2012 : return DLT_RETURN_OK;
2013 : }
2014 :
2015 133 : int dlt_receiver_check_and_get(DltReceiver *receiver,
2016 : void *dest,
2017 : unsigned int to_get,
2018 : unsigned int flags)
2019 : {
2020 133 : size_t min_size = (size_t)to_get;
2021 : uint8_t *src = NULL;
2022 :
2023 133 : if (flags & DLT_RCV_SKIP_HEADER)
2024 88 : min_size += sizeof(DltUserHeader);
2025 :
2026 133 : if (!receiver ||
2027 133 : (receiver->bytesRcvd < (int32_t) min_size) ||
2028 133 : !receiver->buf ||
2029 : !dest)
2030 : return DLT_RETURN_WRONG_PARAMETER;
2031 :
2032 : src = (uint8_t *)receiver->buf;
2033 :
2034 133 : if (flags & DLT_RCV_SKIP_HEADER)
2035 88 : src += sizeof(DltUserHeader);
2036 :
2037 : memcpy(dest, src, to_get);
2038 :
2039 133 : if (flags & DLT_RCV_REMOVE) {
2040 0 : if (dlt_receiver_remove(receiver, (int)min_size) != DLT_RETURN_OK) {
2041 0 : dlt_log(LOG_WARNING, "Can't remove bytes from receiver\n");
2042 0 : return DLT_RETURN_ERROR;
2043 : }
2044 : }
2045 :
2046 133 : return (int)to_get;
2047 : }
2048 :
2049 12103 : DltReturnValue dlt_set_storageheader(DltStorageHeader *storageheader, const char *ecu)
2050 : {
2051 :
2052 : #if !defined(_MSC_VER)
2053 : struct timeval tv;
2054 : #endif
2055 :
2056 12103 : if ((storageheader == NULL) || (ecu == NULL))
2057 : return DLT_RETURN_WRONG_PARAMETER;
2058 :
2059 : /* get time of day */
2060 : #if defined(_MSC_VER)
2061 : time(&(storageheader->seconds));
2062 : #else
2063 12103 : gettimeofday(&tv, NULL);
2064 : #endif
2065 :
2066 : /* prepare storage header */
2067 12103 : storageheader->pattern[0] = 'D';
2068 12103 : storageheader->pattern[1] = 'L';
2069 12103 : storageheader->pattern[2] = 'T';
2070 12103 : storageheader->pattern[3] = 0x01;
2071 :
2072 12103 : dlt_set_id(storageheader->ecu, ecu);
2073 :
2074 : /* Set current time */
2075 : #if defined(_MSC_VER)
2076 : storageheader->microseconds = 0;
2077 : #else
2078 12103 : storageheader->seconds = (uint32_t) tv.tv_sec; /* value is long */
2079 12103 : storageheader->microseconds = (int32_t) tv.tv_usec; /* value is long */
2080 : #endif
2081 :
2082 12103 : return DLT_RETURN_OK;
2083 : }
2084 :
2085 9 : DltReturnValue dlt_check_rcv_data_size(int received, int required)
2086 : {
2087 : int _ret = DLT_RETURN_OK;
2088 9 : if (received < required) {
2089 1 : dlt_vlog(LOG_WARNING, "%s: Received data not complete\n", __func__);
2090 : _ret = DLT_RETURN_ERROR;
2091 : }
2092 :
2093 9 : return _ret;
2094 : }
2095 :
2096 6589 : DltReturnValue dlt_check_storageheader(DltStorageHeader *storageheader)
2097 : {
2098 6589 : if (storageheader == NULL)
2099 : return DLT_RETURN_WRONG_PARAMETER;
2100 :
2101 13178 : return ((storageheader->pattern[0] == 'D') &&
2102 6589 : (storageheader->pattern[1] == 'L') &&
2103 6589 : (storageheader->pattern[2] == 'T') &&
2104 6589 : (storageheader->pattern[3] == 1))
2105 13178 : ? DLT_RETURN_TRUE : DLT_RETURN_OK;
2106 : }
2107 :
2108 0 : DltReturnValue dlt_buffer_init_static_server(DltBuffer *buf, const unsigned char *ptr, uint32_t size)
2109 : {
2110 0 : if ((buf == NULL) || (ptr == NULL))
2111 : return DLT_RETURN_WRONG_PARAMETER;
2112 :
2113 : DltBufferHead *head;
2114 :
2115 : /* Init parameters */
2116 : union {
2117 : const unsigned char *cp;
2118 : unsigned char *p;
2119 : } shm_cast;
2120 : shm_cast.cp = ptr;
2121 0 : buf->shm = shm_cast.p;
2122 0 : buf->min_size = size;
2123 0 : buf->max_size = size;
2124 0 : buf->step_size = 0;
2125 :
2126 : /* Init pointers */
2127 : head = (DltBufferHead *)buf->shm;
2128 0 : head->read = 0;
2129 0 : head->write = 0;
2130 0 : head->count = 0;
2131 0 : buf->mem = (unsigned char *)(buf->shm + sizeof(DltBufferHead));
2132 0 : buf->size = (unsigned int) buf->min_size - (unsigned int) sizeof(DltBufferHead);
2133 :
2134 : /* clear memory */
2135 0 : memset(buf->mem, 0, buf->size);
2136 :
2137 0 : dlt_vlog(LOG_DEBUG,
2138 : "%s: Buffer: Size %u, Start address %lX\n",
2139 0 : __func__, buf->size, (unsigned long)buf->mem);
2140 :
2141 0 : return DLT_RETURN_OK; /* OK */
2142 : }
2143 :
2144 0 : DltReturnValue dlt_buffer_init_static_client(DltBuffer *buf, const unsigned char *ptr, uint32_t size)
2145 : {
2146 0 : if ((buf == NULL) || (ptr == NULL))
2147 : return DLT_RETURN_WRONG_PARAMETER;
2148 :
2149 : /* Init parameters */
2150 : union {
2151 : const unsigned char *cp;
2152 : unsigned char *p;
2153 : } shm_cast;
2154 : shm_cast.cp = ptr;
2155 0 : buf->shm = shm_cast.p;
2156 0 : buf->min_size = size;
2157 0 : buf->max_size = size;
2158 0 : buf->step_size = 0;
2159 :
2160 : /* Init pointers */
2161 0 : buf->mem = (unsigned char *)(buf->shm + sizeof(DltBufferHead));
2162 0 : buf->size = (uint32_t)(buf->min_size - sizeof(DltBufferHead));
2163 :
2164 0 : dlt_vlog(LOG_DEBUG,
2165 : "%s: Buffer: Size %u, Start address %lX\n",
2166 : __func__, buf->size, (unsigned long)buf->mem);
2167 :
2168 0 : return DLT_RETURN_OK; /* OK */
2169 : }
2170 :
2171 24651 : DltReturnValue dlt_buffer_init_dynamic(DltBuffer *buf, uint32_t min_size, uint32_t max_size, uint32_t step_size)
2172 : {
2173 : /*Do not dlt_mutex_lock inside here! */
2174 : DltBufferHead *head;
2175 :
2176 : /* catch null pointer */
2177 24651 : if (buf == NULL)
2178 : return DLT_RETURN_WRONG_PARAMETER;
2179 :
2180 : /* catch 0 logical errors */
2181 24643 : if ((min_size == 0) || (max_size == 0) || (step_size == 0))
2182 : return DLT_RETURN_WRONG_PARAMETER;
2183 :
2184 24634 : if (min_size > max_size)
2185 : return DLT_RETURN_WRONG_PARAMETER;
2186 :
2187 24632 : if (step_size > max_size)
2188 : return DLT_RETURN_WRONG_PARAMETER;
2189 :
2190 : /* Init parameters */
2191 24632 : buf->min_size = min_size;
2192 24632 : buf->max_size = max_size;
2193 24632 : buf->step_size = step_size;
2194 :
2195 : /* allocat memory */
2196 24632 : buf->shm = malloc(buf->min_size);
2197 :
2198 24632 : if (buf->shm == NULL) {
2199 0 : dlt_vlog(LOG_EMERG,
2200 : "%s: Buffer: Cannot allocate %u bytes\n",
2201 : __func__, buf->min_size);
2202 0 : return DLT_RETURN_ERROR;
2203 : }
2204 :
2205 : /* Init pointers */
2206 : head = (DltBufferHead *)buf->shm;
2207 24632 : head->read = 0;
2208 24632 : head->write = 0;
2209 24632 : head->count = 0;
2210 24632 : buf->mem = (unsigned char *)(buf->shm + sizeof(DltBufferHead));
2211 :
2212 24632 : if (buf->min_size < (uint32_t)sizeof(DltBufferHead)) {
2213 0 : dlt_vlog(LOG_ERR,
2214 : "%s: min_size is too small [%u]\n",
2215 : __func__, buf->min_size);
2216 0 : return DLT_RETURN_WRONG_PARAMETER;
2217 : }
2218 :
2219 24632 : buf->size = (uint32_t) (buf->min_size - sizeof(DltBufferHead));
2220 :
2221 24632 : dlt_vlog(LOG_DEBUG,
2222 : "%s: Buffer: Size %u, Start address %lX\n",
2223 : __func__, buf->size, (unsigned long)buf->mem);
2224 :
2225 : /* clear memory */
2226 24632 : memset(buf->mem, 0, (size_t)buf->size);
2227 :
2228 24632 : return DLT_RETURN_OK; /* OK */
2229 : }
2230 :
2231 0 : DltReturnValue dlt_buffer_free_static(DltBuffer *buf)
2232 : {
2233 : /* catch null pointer */
2234 0 : if (buf == NULL)
2235 : return DLT_RETURN_WRONG_PARAMETER;
2236 :
2237 0 : if (buf->mem == NULL) {
2238 : /* buffer not initialized */
2239 0 : dlt_vlog(LOG_WARNING, "%s: Buffer: Buffer not initialized\n", __func__);
2240 0 : return DLT_RETURN_ERROR; /* ERROR */
2241 : }
2242 :
2243 : return DLT_RETURN_OK;
2244 : }
2245 :
2246 24622 : DltReturnValue dlt_buffer_free_dynamic(DltBuffer *buf)
2247 : {
2248 : /* catch null pointer */
2249 24622 : if (buf == NULL)
2250 : return DLT_RETURN_WRONG_PARAMETER;
2251 :
2252 24621 : if (buf->shm == NULL) {
2253 : /* buffer not initialized */
2254 0 : dlt_vlog(LOG_WARNING, "%s: Buffer: Buffer not initialized\n", __func__);
2255 0 : return DLT_RETURN_ERROR; /* ERROR */
2256 : }
2257 :
2258 24621 : free(buf->shm);
2259 24621 : buf->shm = NULL;
2260 24621 : buf->mem = NULL;
2261 :
2262 24621 : return DLT_RETURN_OK;
2263 : }
2264 :
2265 53549 : void dlt_buffer_write_block(DltBuffer *buf, int *write, const unsigned char *data, unsigned int size)
2266 : {
2267 : /* catch null pointer */
2268 53549 : if ((buf != NULL) && (write != NULL) && (data != NULL)) {
2269 52530 : if (size <= buf->size){
2270 52530 : if (( (unsigned int) (*write ) + size) <= buf->size) {
2271 : /* write one block */
2272 52529 : memcpy(buf->mem + *write, data, size);
2273 52529 : *write += (int) size;
2274 : }
2275 : else {
2276 : /* when (*write) = buf->size, write only the second block
2277 : * and update write position correspondingly.
2278 : */
2279 1 : if((unsigned int) (*write) <= buf->size) {
2280 : /* write two blocks */
2281 1 : memcpy(buf->mem + *write, data, buf->size - (unsigned int) (*write));
2282 1 : memcpy(buf->mem, data + buf->size - *write, size - buf->size + (unsigned int) (*write));
2283 1 : *write += (int) (size - buf->size);
2284 : }
2285 : }
2286 : }
2287 : else {
2288 0 : dlt_vlog(LOG_WARNING, "%s: Write error: ring buffer to small\n", __func__);
2289 : }
2290 : }
2291 : else {
2292 1019 : dlt_vlog(LOG_WARNING, "%s: Wrong parameter: Null pointer\n", __func__);
2293 : }
2294 53549 : }
2295 :
2296 53 : void dlt_buffer_read_block(DltBuffer *buf, int *read, unsigned char *data, unsigned int size)
2297 : {
2298 : /* catch nullpointer */
2299 53 : if ((buf != NULL) && (read != NULL) && (data != NULL)) {
2300 37 : if (((unsigned int)(*read) + size) <= buf->size) {
2301 : /* read one block */
2302 35 : memcpy(data, buf->mem + *read, size);
2303 35 : *read += (int)size;
2304 : }
2305 : else {
2306 : /* when (*read) = buf->size, read only the second block
2307 : * and update read position correspondingly.
2308 : */
2309 2 : if ((unsigned int)(*read) <= buf->size) {
2310 : /* read two blocks */
2311 1 : memcpy(data, buf->mem + *read, buf->size - (unsigned int)(*read));
2312 1 : memcpy(data + buf->size - *read, buf->mem, size - buf->size + (unsigned int)(*read));
2313 1 : *read += (int) (size - buf->size);
2314 : }
2315 : }
2316 : }
2317 : else {
2318 16 : dlt_vlog(LOG_WARNING, "%s: Wrong parameter: Null pointer\n", __func__);
2319 : }
2320 53 : }
2321 :
2322 859 : DltReturnValue dlt_buffer_check_size(DltBuffer *buf, int needed)
2323 : {
2324 859 : if (buf == NULL)
2325 : return DLT_RETURN_WRONG_PARAMETER;
2326 :
2327 859 : if ((buf->size + sizeof(DltBufferHead) + (size_t) needed) > buf->max_size)
2328 0 : return DLT_RETURN_ERROR;
2329 :
2330 : return DLT_RETURN_OK;
2331 : }
2332 :
2333 11 : int dlt_buffer_increase_size(DltBuffer *buf)
2334 : {
2335 : DltBufferHead *head, *new_head;
2336 : unsigned char *new_ptr;
2337 :
2338 : /* catch null pointer */
2339 11 : if (buf == NULL) {
2340 1 : dlt_vlog(LOG_WARNING, "%s: Wrong parameter: Null pointer\n", __func__);
2341 1 : return DLT_RETURN_WRONG_PARAMETER;
2342 : }
2343 :
2344 : /* check size */
2345 10 : if (buf->step_size == 0)
2346 : /* cannot increase size */
2347 : return DLT_RETURN_ERROR;
2348 :
2349 : /* check size */
2350 9 : if ((buf->size + sizeof(DltBufferHead) + buf->step_size) > buf->max_size)
2351 : /* max size reached, do not increase */
2352 : return DLT_RETURN_ERROR;
2353 :
2354 : /* allocate new buffer */
2355 8 : new_ptr = malloc(buf->size + sizeof(DltBufferHead) + buf->step_size);
2356 :
2357 8 : if (new_ptr == NULL) {
2358 0 : dlt_vlog(LOG_WARNING,
2359 : "%s: Buffer: Cannot increase size because allocate %u bytes failed\n",
2360 : __func__, buf->min_size);
2361 0 : return DLT_RETURN_ERROR;
2362 : }
2363 :
2364 : /* copy data */
2365 8 : head = (DltBufferHead *)buf->shm;
2366 : new_head = (DltBufferHead *)new_ptr;
2367 :
2368 8 : if (head->read < head->write) {
2369 6 : memcpy(new_ptr + sizeof(DltBufferHead), buf->mem + head->read, (size_t)(head->write - head->read));
2370 6 : new_head->read = 0;
2371 6 : new_head->write = head->write - head->read;
2372 6 : new_head->count = head->count;
2373 : }
2374 : else {
2375 2 : memcpy(new_ptr + sizeof(DltBufferHead), buf->mem + head->read, buf->size - (uint32_t)(head->read));
2376 2 : memcpy(new_ptr + sizeof(DltBufferHead) + buf->size - head->read, buf->mem, (size_t)head->write);
2377 2 : new_head->read = 0;
2378 2 : new_head->write = (int)(buf->size) + head->write - head->read;
2379 2 : new_head->count = head->count;
2380 : }
2381 :
2382 : /* free old data */
2383 8 : free(buf->shm);
2384 :
2385 : /* update data */
2386 8 : buf->shm = new_ptr;
2387 8 : buf->mem = new_ptr + sizeof(DltBufferHead);
2388 8 : buf->size += buf->step_size;
2389 :
2390 8 : dlt_vlog(LOG_DEBUG,
2391 : "%s: Buffer: Size increased to %u bytes with start address %lX\n",
2392 : __func__,
2393 : buf->size + (int32_t)sizeof(DltBufferHead),
2394 : (unsigned long)buf->mem);
2395 :
2396 8 : return DLT_RETURN_OK; /* OK */
2397 : }
2398 :
2399 9 : int dlt_buffer_minimize_size(DltBuffer *buf)
2400 : {
2401 : unsigned char *new_ptr;
2402 :
2403 : /* catch null pointer */
2404 9 : if (buf == NULL) {
2405 1 : dlt_vlog(LOG_WARNING, "%s: Wrong parameter: Null pointer\n", __func__);
2406 1 : return DLT_RETURN_WRONG_PARAMETER;
2407 : }
2408 :
2409 8 : if ((buf->size + sizeof(DltBufferHead)) == buf->min_size)
2410 : /* already minimized */
2411 : return DLT_RETURN_OK;
2412 :
2413 : /* allocate new buffer */
2414 0 : new_ptr = malloc(buf->min_size);
2415 :
2416 0 : if (new_ptr == NULL) {
2417 0 : dlt_vlog(LOG_WARNING,
2418 : "%s: Buffer: Cannot set to min size of %u bytes\n",
2419 : __func__, buf->min_size);
2420 0 : return DLT_RETURN_ERROR;
2421 : }
2422 :
2423 : /* free old data */
2424 0 : free(buf->shm);
2425 :
2426 : /* update data */
2427 0 : buf->shm = new_ptr;
2428 0 : buf->mem = new_ptr + sizeof(DltBufferHead);
2429 0 : buf->size = (uint32_t)(buf->min_size - sizeof(DltBufferHead));
2430 :
2431 : /* reset pointers and counters */
2432 0 : ((int *)(buf->shm))[0] = 0; /* pointer to write memory */
2433 0 : ((int *)(buf->shm))[1] = 0; /* pointer to read memory */
2434 0 : ((int *)(buf->shm))[2] = 0; /* number of packets */
2435 :
2436 0 : dlt_vlog(LOG_DEBUG,
2437 : "%s: Buffer: Buffer minimized to Size %u bytes with start address %lX\n",
2438 : __func__, buf->size, (unsigned long)buf->mem);
2439 :
2440 : /* clear memory */
2441 0 : memset(buf->mem, 0, buf->size);
2442 :
2443 0 : return DLT_RETURN_OK; /* OK */
2444 : }
2445 :
2446 9 : int dlt_buffer_reset(DltBuffer *buf)
2447 : {
2448 : /* catch null pointer */
2449 9 : if (buf == NULL) {
2450 1 : dlt_vlog(LOG_WARNING, "%s: Wrong parameter: Null pointer\n", __func__);
2451 1 : return DLT_RETURN_WRONG_PARAMETER;
2452 : }
2453 :
2454 8 : dlt_vlog(LOG_WARNING,
2455 : "%s: Buffer: Buffer reset triggered. Size: %u, Start address: %lX\n",
2456 8 : __func__, buf->size, (unsigned long)buf->mem);
2457 :
2458 : /* reset pointers and counters */
2459 8 : ((int *)(buf->shm))[0] = 0; /* pointer to write memory */
2460 8 : ((int *)(buf->shm))[1] = 0; /* pointer to read memory */
2461 8 : ((int *)(buf->shm))[2] = 0; /* number of packets */
2462 :
2463 : /* clear memory */
2464 8 : memset(buf->mem, 0, buf->size);
2465 :
2466 8 : return DLT_RETURN_OK; /* OK */
2467 : }
2468 :
2469 13775 : DltReturnValue dlt_buffer_push(DltBuffer *buf, const unsigned char *data, unsigned int size)
2470 : {
2471 13775 : return dlt_buffer_push3(buf, data, size, 0, 0, 0, 0);
2472 : }
2473 :
2474 21543 : DltReturnValue dlt_buffer_push3(DltBuffer *buf,
2475 : const unsigned char *data1,
2476 : unsigned int size1,
2477 : const unsigned char *data2,
2478 : unsigned int size2,
2479 : const unsigned char *data3,
2480 : unsigned int size3)
2481 : {
2482 : int free_size;
2483 : int write, read, count;
2484 : DltBufferBlockHead head;
2485 :
2486 : /* catch null pointer */
2487 21543 : if (buf == NULL)
2488 : return DLT_RETURN_WRONG_PARAMETER;
2489 :
2490 21475 : if (buf->shm == NULL) {
2491 : /* buffer not initialised */
2492 0 : dlt_vlog(LOG_ERR, "%s: Buffer: Buffer not initialized\n", __func__);
2493 0 : return DLT_RETURN_ERROR; /* ERROR */
2494 : }
2495 :
2496 : /* get current write pointer */
2497 21475 : write = ((int *)(buf->shm))[0];
2498 21475 : read = ((int *)(buf->shm))[1];
2499 21475 : count = ((int *)(buf->shm))[2];
2500 :
2501 : /* check pointers */
2502 21475 : if (((unsigned int)read > buf->size) || ((unsigned int)write > buf->size)) {
2503 0 : dlt_vlog(LOG_ERR,
2504 : "%s: Buffer: Pointer out of range. Read: %d, Write: %d, Size: %u\n",
2505 : __func__, read, write, buf->size);
2506 0 : dlt_buffer_reset(buf);
2507 0 : return DLT_RETURN_ERROR; /* ERROR */
2508 : }
2509 :
2510 : /* calculate free size */
2511 21475 : if (read > write)
2512 0 : free_size = read - write;
2513 21475 : else if (count && (write == read))
2514 : free_size = 0;
2515 : else
2516 21475 : free_size = (int)buf->size - write + read;
2517 :
2518 : /* check size */
2519 21481 : while (free_size < (int) (sizeof(DltBufferBlockHead) + size1 + size2 + size3)) {
2520 : /* try to increase size if possible */
2521 6 : if (dlt_buffer_increase_size(buf))
2522 : /* increase size is not possible */
2523 : /*dlt_log(LOG_ERR, "Buffer: Buffer is full\n"); */
2524 : return DLT_RETURN_ERROR; /* ERROR */
2525 :
2526 : /* update pointers */
2527 6 : write = ((int *)(buf->shm))[0];
2528 6 : read = ((int *)(buf->shm))[1];
2529 :
2530 : /* update free size */
2531 6 : if (read > write)
2532 0 : free_size = read - write;
2533 6 : else if (count && (write == read))
2534 : free_size = 0;
2535 : else
2536 6 : free_size = (int)((unsigned int)buf->size - (unsigned int)write + (unsigned int)read);
2537 : }
2538 :
2539 : /* set header */
2540 : strncpy(head.head, DLT_BUFFER_HEAD, 4);
2541 : head.head[3] = 0;
2542 21475 : head.status = 2;
2543 21475 : head.size = (int)(size1 + size2 + size3);
2544 :
2545 : /* write data */
2546 21475 : dlt_buffer_write_block(buf, &write, (unsigned char *)&head, sizeof(DltBufferBlockHead));
2547 :
2548 21475 : if (size1)
2549 21475 : dlt_buffer_write_block(buf, &write, data1, size1);
2550 :
2551 21475 : if (size2)
2552 7702 : dlt_buffer_write_block(buf, &write, data2, size2);
2553 :
2554 21475 : if (size3)
2555 1877 : dlt_buffer_write_block(buf, &write, data3, size3);
2556 :
2557 : /* update global shm pointers */
2558 21475 : ((int *)(buf->shm))[0] = write; /* set new write pointer */
2559 21475 : ((int *)(buf->shm))[2] += 1; /* increase counter */
2560 :
2561 21475 : return DLT_RETURN_OK; /* OK */
2562 :
2563 : }
2564 :
2565 64 : int dlt_buffer_get(DltBuffer *buf, unsigned char *data, int max_size, int delete)
2566 : {
2567 : int used_size;
2568 : int write, read, count;
2569 64 : char head_compare[] = DLT_BUFFER_HEAD;
2570 : DltBufferBlockHead head;
2571 :
2572 : /* catch null pointer */
2573 64 : if (buf == NULL)
2574 : return DLT_RETURN_WRONG_PARAMETER;
2575 :
2576 47 : if (buf->shm == NULL) {
2577 : /* shm not initialised */
2578 0 : dlt_vlog(LOG_ERR, "%s: Buffer: SHM not initialized\n", __func__);
2579 0 : return DLT_RETURN_ERROR; /* ERROR */
2580 : }
2581 :
2582 : /* get current write pointer */
2583 47 : write = ((int *)(buf->shm))[0];
2584 47 : read = ((int *)(buf->shm))[1];
2585 47 : count = ((int *)(buf->shm))[2];
2586 :
2587 : /* check pointers */
2588 47 : if (((unsigned int)read > buf->size) || ((unsigned int)write > buf->size) || (count < 0)) {
2589 3 : dlt_vlog(LOG_ERR,
2590 : "%s: Buffer: Pointer out of range. Read: %d, Write: %d, Count: %d, Size: %u\n",
2591 : __func__, read, write, count, buf->size);
2592 3 : dlt_buffer_reset(buf);
2593 3 : return DLT_RETURN_ERROR; /* ERROR */
2594 : }
2595 :
2596 : /* check if data is in there */
2597 44 : if (count == 0) {
2598 22 : if (write != read) {
2599 1 : dlt_vlog(LOG_ERR,
2600 : "%s: Buffer: SHM should be empty, but is not. Read: %d, Write: %d\n",
2601 : __func__, read, write);
2602 1 : dlt_buffer_reset(buf);
2603 : }
2604 :
2605 22 : return DLT_RETURN_ERROR; /* ERROR */
2606 : }
2607 :
2608 : /* calculate used size */
2609 22 : if (write > read)
2610 21 : used_size = write - read;
2611 : else
2612 1 : used_size = (int)buf->size - read + write;
2613 :
2614 : /* first check size */
2615 22 : if (used_size < (int)(sizeof(DltBufferBlockHead))) {
2616 1 : dlt_vlog(LOG_ERR,
2617 : "%s: Buffer: Used size is smaller than buffer block header size. Used size: %d\n",
2618 : __func__, used_size);
2619 1 : dlt_buffer_reset(buf);
2620 1 : return DLT_RETURN_ERROR; /* ERROR */
2621 : }
2622 :
2623 : /* read header */
2624 21 : dlt_buffer_read_block(buf, &read, (unsigned char *)&head, sizeof(DltBufferBlockHead));
2625 :
2626 : /* check header */
2627 21 : if (memcmp((unsigned char *)(head.head), head_compare, sizeof(head_compare)) != 0) {
2628 1 : dlt_vlog(LOG_ERR, "%s: Buffer: Header head check failed\n", __func__);
2629 1 : dlt_buffer_reset(buf);
2630 1 : return DLT_RETURN_ERROR; /* ERROR */
2631 : }
2632 :
2633 20 : if (head.status != 2) {
2634 0 : dlt_vlog(LOG_ERR, "%s: Buffer: Header status check failed\n", __func__);
2635 0 : dlt_buffer_reset(buf);
2636 0 : return DLT_RETURN_ERROR; /* ERROR */
2637 : }
2638 :
2639 : /* second check size */
2640 20 : if (used_size < ((int)sizeof(DltBufferBlockHead) + head.size)) {
2641 1 : dlt_vlog(LOG_ERR,
2642 : "%s: Buffer: Used size is smaller than buffer block header size And read header size. Used size: %d\n",
2643 : __func__, used_size);
2644 1 : dlt_buffer_reset(buf);
2645 1 : return DLT_RETURN_ERROR; /* ERROR */
2646 : }
2647 :
2648 : /* third check size */
2649 19 : if (max_size && (head.size > max_size))
2650 1 : dlt_vlog(LOG_WARNING,
2651 : "%s: Buffer: Max size is smaller than read header size. Max size: %d\n",
2652 : __func__, max_size);
2653 :
2654 : /* nothing to do but data does not fit provided buffer */
2655 :
2656 19 : if ((data != NULL) && max_size) {
2657 : /* read data */
2658 14 : dlt_buffer_read_block(buf, &read, data, (unsigned int)head.size);
2659 :
2660 14 : if (delete)
2661 : /* update buffer pointers */
2662 3 : ((int *)(buf->shm))[1] = read; /* set new read pointer */
2663 :
2664 : }
2665 5 : else if (delete)
2666 : {
2667 5 : if ((unsigned int)(read + head.size) <= buf->size)
2668 5 : ((int *)(buf->shm))[1] = read + head.size; /* set new read pointer */
2669 : else
2670 0 : ((int *)(buf->shm))[1] = read + head.size - (int)buf->size; /* set new read pointer */
2671 :
2672 : }
2673 :
2674 8 : if (delete) {
2675 8 : ((int *)(buf->shm))[2] -= 1; /* decrease counter */
2676 :
2677 8 : if (((int *)(buf->shm))[2] == 0)
2678 : /* try to minimize size */
2679 5 : dlt_buffer_minimize_size(buf);
2680 : }
2681 :
2682 19 : return head.size; /* OK */
2683 : }
2684 :
2685 8 : int dlt_buffer_pull(DltBuffer *buf, unsigned char *data, int max_size)
2686 : {
2687 8 : return dlt_buffer_get(buf, data, max_size, 1);
2688 : }
2689 :
2690 13 : int dlt_buffer_copy(DltBuffer *buf, unsigned char *data, int max_size)
2691 : {
2692 13 : return dlt_buffer_get(buf, data, max_size, 0);
2693 : }
2694 :
2695 7 : int dlt_buffer_remove(DltBuffer *buf)
2696 : {
2697 7 : return dlt_buffer_get(buf, 0, 0, 1);
2698 : }
2699 :
2700 2 : void dlt_buffer_info(DltBuffer *buf)
2701 : {
2702 : /* check nullpointer */
2703 2 : if (buf == NULL) {
2704 1 : dlt_vlog(LOG_WARNING, "%s: Wrong parameter: Null pointer\n", __func__);
2705 1 : return;
2706 : }
2707 :
2708 1 : dlt_vlog(LOG_DEBUG,
2709 : "Buffer: Available size: %u, Buffer: Buffer full start address: %lX, Buffer: Buffer start address: %lX\n",
2710 1 : buf->size, (unsigned long)buf->shm, (unsigned long)buf->mem);
2711 : }
2712 :
2713 2 : void dlt_buffer_status(DltBuffer *buf)
2714 : {
2715 : int write, read, count;
2716 :
2717 : /* check nullpointer */
2718 2 : if (buf == NULL) {
2719 1 : dlt_vlog(LOG_WARNING, "%s: Wrong parameter: Null pointer\n", __func__);
2720 1 : return;
2721 : }
2722 :
2723 : /* check if buffer available */
2724 1 : if (buf->shm == NULL)
2725 : return;
2726 :
2727 1 : write = ((int *)(buf->shm))[0];
2728 1 : read = ((int *)(buf->shm))[1];
2729 1 : count = ((int *)(buf->shm))[2];
2730 :
2731 1 : dlt_vlog(LOG_DEBUG,
2732 : "Buffer: Write: %d, Read: %d, Count: %d\n",
2733 : write, read, count);
2734 : }
2735 :
2736 3 : uint32_t dlt_buffer_get_total_size(DltBuffer *buf)
2737 : {
2738 : /* catch null pointer */
2739 3 : if (buf == NULL)
2740 : return (uint32_t)DLT_RETURN_WRONG_PARAMETER;
2741 :
2742 2 : return buf->max_size;
2743 : }
2744 :
2745 2503 : int dlt_buffer_get_used_size(DltBuffer *buf)
2746 : {
2747 : int write, read, count;
2748 :
2749 : /* catch null pointer */
2750 2503 : if (buf == NULL)
2751 : return DLT_RETURN_WRONG_PARAMETER;
2752 :
2753 : /* check if buffer available */
2754 2502 : if (buf->shm == NULL)
2755 : return DLT_RETURN_OK;
2756 :
2757 2502 : write = ((int *)(buf->shm))[0];
2758 2502 : read = ((int *)(buf->shm))[1];
2759 2502 : count = ((int *)(buf->shm))[2];
2760 :
2761 2502 : if (count == 0)
2762 : return DLT_RETURN_OK;
2763 :
2764 2501 : if (write > read)
2765 2501 : return write - read;
2766 :
2767 0 : return (int)buf->size - read + write;
2768 : }
2769 :
2770 8522 : int dlt_buffer_get_message_count(DltBuffer *buf)
2771 : {
2772 : /* catch null pointer */
2773 8522 : if (buf == NULL)
2774 : return DLT_RETURN_WRONG_PARAMETER;
2775 :
2776 : /* check if buffer available */
2777 8522 : if (buf->shm == NULL)
2778 : return DLT_RETURN_OK;
2779 :
2780 8522 : return ((int *)(buf->shm))[2];
2781 : }
2782 :
2783 : #if !defined (__WIN32__)
2784 :
2785 0 : DltReturnValue dlt_setup_serial(int fd, speed_t speed)
2786 : {
2787 : # if !defined (__WIN32__) && !defined(_MSC_VER)
2788 : struct termios config;
2789 :
2790 0 : if (isatty(fd) == 0)
2791 : return DLT_RETURN_ERROR;
2792 :
2793 0 : if (tcgetattr(fd, &config) < 0)
2794 : return DLT_RETURN_ERROR;
2795 :
2796 : /* Input flags - Turn off input processing
2797 : * convert break to null byte, no CR to NL translation,
2798 : * no NL to CR translation, don't mark parity errors or breaks
2799 : * no input parity check, don't strip high bit off,
2800 : * no XON/XOFF software flow control
2801 : */
2802 0 : config.c_iflag &= (tcflag_t)~(IGNBRK | BRKINT | ICRNL |
2803 : INLCR | PARMRK | INPCK | ISTRIP | IXON);
2804 :
2805 : /* Output flags - Turn off output processing
2806 : * no CR to NL translation, no NL to CR-NL translation,
2807 : * no NL to CR translation, no column 0 CR suppression,
2808 : * no Ctrl-D suppression, no fill characters, no case mapping,
2809 : * no local output processing
2810 : *
2811 : * config.c_oflag &= ~(OCRNL | ONLCR | ONLRET |
2812 : * ONOCR | ONOEOT| OFILL | OLCUC | OPOST);
2813 : */
2814 0 : config.c_oflag = 0;
2815 :
2816 : /* No line processing:
2817 : * echo off, echo newline off, canonical mode off,
2818 : * extended input processing off, signal chars off
2819 : */
2820 0 : config.c_lflag &= (tcflag_t)~(ECHO | ECHONL | ICANON | IEXTEN | ISIG);
2821 :
2822 : /* Turn off character processing
2823 : * clear current char size mask, no parity checking,
2824 : * no output processing, force 8 bit input
2825 : */
2826 0 : config.c_cflag &= (tcflag_t)~(CSIZE | PARENB);
2827 0 : config.c_cflag |= CS8;
2828 :
2829 : /* One input byte is enough to return from read()
2830 : * Inter-character timer off
2831 : */
2832 0 : config.c_cc[VMIN] = 1;
2833 0 : config.c_cc[VTIME] = 0;
2834 :
2835 : /* Communication speed (simple version, using the predefined
2836 : * constants)
2837 : */
2838 0 : if ((cfsetispeed(&config, speed) < 0) || (cfsetospeed(&config, speed) < 0))
2839 0 : return DLT_RETURN_ERROR;
2840 :
2841 : /* Finally, apply the configuration
2842 : */
2843 0 : if (tcsetattr(fd, TCSAFLUSH, &config) < 0)
2844 : return DLT_RETURN_ERROR;
2845 :
2846 : return DLT_RETURN_OK;
2847 : # else
2848 : return DLT_RETURN_ERROR;
2849 : # endif
2850 : }
2851 :
2852 0 : speed_t dlt_convert_serial_speed(int baudrate)
2853 : {
2854 : # if !defined (__WIN32__) && !defined(_MSC_VER) && !defined(__CYGWIN__)
2855 : speed_t ret;
2856 :
2857 0 : switch (baudrate) {
2858 : case 50:
2859 : {
2860 : ret = B50;
2861 : break;
2862 : }
2863 0 : case 75:
2864 : {
2865 : ret = B75;
2866 0 : break;
2867 : }
2868 0 : case 110:
2869 : {
2870 : ret = B110;
2871 0 : break;
2872 : }
2873 0 : case 134:
2874 : {
2875 : ret = B134;
2876 0 : break;
2877 : }
2878 0 : case 150:
2879 : {
2880 : ret = B150;
2881 0 : break;
2882 : }
2883 0 : case 200:
2884 : {
2885 : ret = B200;
2886 0 : break;
2887 : }
2888 0 : case 300:
2889 : {
2890 : ret = B300;
2891 0 : break;
2892 : }
2893 0 : case 600:
2894 : {
2895 : ret = B600;
2896 0 : break;
2897 : }
2898 0 : case 1200:
2899 : {
2900 : ret = B1200;
2901 0 : break;
2902 : }
2903 0 : case 1800:
2904 : {
2905 : ret = B1800;
2906 0 : break;
2907 : }
2908 0 : case 2400:
2909 : {
2910 : ret = B2400;
2911 0 : break;
2912 : }
2913 0 : case 4800:
2914 : {
2915 : ret = B4800;
2916 0 : break;
2917 : }
2918 0 : case 9600:
2919 : {
2920 : ret = B9600;
2921 0 : break;
2922 : }
2923 0 : case 19200:
2924 : {
2925 : ret = B19200;
2926 0 : break;
2927 : }
2928 0 : case 38400:
2929 : {
2930 : ret = B38400;
2931 0 : break;
2932 : }
2933 0 : case 57600:
2934 : {
2935 : ret = B57600;
2936 0 : break;
2937 : }
2938 : case 115200:
2939 : {
2940 : ret = B115200;
2941 : break;
2942 : }
2943 : # ifdef __linux__
2944 0 : case 230400:
2945 : {
2946 : ret = B230400;
2947 0 : break;
2948 : }
2949 0 : case 460800:
2950 : {
2951 : ret = B460800;
2952 0 : break;
2953 : }
2954 0 : case 500000:
2955 : {
2956 : ret = B500000;
2957 0 : break;
2958 : }
2959 0 : case 576000:
2960 : {
2961 : ret = B576000;
2962 0 : break;
2963 : }
2964 0 : case 921600:
2965 : {
2966 : ret = B921600;
2967 0 : break;
2968 : }
2969 0 : case 1000000:
2970 : {
2971 : ret = B1000000;
2972 0 : break;
2973 : }
2974 0 : case 1152000:
2975 : {
2976 : ret = B1152000;
2977 0 : break;
2978 : }
2979 0 : case 1500000:
2980 : {
2981 : ret = B1500000;
2982 0 : break;
2983 : }
2984 0 : case 2000000:
2985 : {
2986 : ret = B2000000;
2987 0 : break;
2988 : }
2989 : #ifdef B2500000
2990 0 : case 2500000:
2991 : {
2992 : ret = B2500000;
2993 0 : break;
2994 : }
2995 : #endif
2996 : #ifdef B3000000
2997 0 : case 3000000:
2998 : {
2999 : ret = B3000000;
3000 0 : break;
3001 : }
3002 : #endif
3003 : #ifdef B3500000
3004 0 : case 3500000:
3005 : {
3006 : ret = B3500000;
3007 0 : break;
3008 : }
3009 : #endif
3010 : #ifdef B4000000
3011 0 : case 4000000:
3012 : {
3013 : ret = B4000000;
3014 0 : break;
3015 : }
3016 : #endif
3017 : # endif /* __linux__ */
3018 : default:
3019 : {
3020 : ret = B115200;
3021 : break;
3022 : }
3023 : }
3024 :
3025 0 : return ret;
3026 : # else
3027 : return 0;
3028 : # endif
3029 : }
3030 :
3031 : #endif
3032 :
3033 20 : void dlt_get_version(char *buf, size_t size)
3034 : {
3035 20 : if ((buf == NULL) && (size > 0)) {
3036 0 : dlt_log(LOG_WARNING, "Wrong parameter: Null pointer\n");
3037 0 : return;
3038 : }
3039 :
3040 : /* Clang does not like these macros, because they are not reproducable */
3041 : #pragma GCC diagnostic push
3042 : #pragma GCC diagnostic ignored "-Wdate-time"
3043 : snprintf(buf,
3044 : size,
3045 : "DLT Package Version: %s %s, Package Revision: %s, build on %s %s\n%s %s %s %s\n",
3046 : _DLT_PACKAGE_VERSION,
3047 : _DLT_PACKAGE_VERSION_STATE,
3048 : _DLT_PACKAGE_REVISION,
3049 : __DATE__,
3050 : __TIME__,
3051 : _DLT_SYSTEMD_ENABLE,
3052 : _DLT_SYSTEMD_WATCHDOG_ENABLE,
3053 : _DLT_TEST_ENABLE,
3054 : _DLT_SHM_ENABLE);
3055 : #pragma GCC diagnostic pop
3056 : }
3057 :
3058 8 : void dlt_get_major_version(char *buf, size_t size)
3059 : {
3060 8 : if ((buf == NULL) && (size > 0)) {
3061 0 : dlt_log(LOG_WARNING, "Wrong parameter: Null pointer\n");
3062 0 : return;
3063 : }
3064 :
3065 : snprintf(buf, size, "%s", _DLT_PACKAGE_MAJOR_VERSION);
3066 : }
3067 :
3068 8 : void dlt_get_minor_version(char *buf, size_t size)
3069 : {
3070 8 : if ((buf == NULL) && (size > 0)) {
3071 0 : dlt_log(LOG_WARNING, "Wrong parameter: Null pointer\n");
3072 0 : return;
3073 : }
3074 :
3075 : snprintf(buf, size, "%s", _DLT_PACKAGE_MINOR_VERSION);
3076 : }
3077 :
3078 :
3079 6300 : uint32_t dlt_uptime(void)
3080 : {
3081 :
3082 : #if defined (__WIN32__) || defined(_MSC_VER)
3083 :
3084 : return (uint32_t)(GetTickCount() * 10); /* GetTickCount() return DWORD */
3085 :
3086 : #else
3087 : struct timespec ts;
3088 :
3089 6300 : if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0)
3090 6300 : return (uint32_t)ts.tv_sec * 10000 + (uint32_t)ts.tv_nsec / 100000; /* in 0.1 ms = 100 us */
3091 : else
3092 : return 0;
3093 :
3094 : #endif
3095 :
3096 : }
3097 :
3098 328 : DltReturnValue dlt_message_print_header(DltMessage *message, char *text, uint32_t size, int verbose)
3099 : {
3100 328 : if ((message == NULL) || (text == NULL))
3101 : return DLT_RETURN_WRONG_PARAMETER;
3102 :
3103 316 : if (dlt_message_header(message, text, size, verbose) < DLT_RETURN_OK)
3104 : return DLT_RETURN_ERROR;
3105 316 : dlt_user_printf("%s\n", text);
3106 :
3107 316 : return DLT_RETURN_OK;
3108 : }
3109 :
3110 328 : DltReturnValue dlt_message_print_hex(DltMessage *message, char *text, uint32_t size, int verbose)
3111 : {
3112 328 : if ((message == NULL) || (text == NULL))
3113 : return DLT_RETURN_WRONG_PARAMETER;
3114 :
3115 316 : if (dlt_message_header(message, text, size, verbose) < DLT_RETURN_OK)
3116 : return DLT_RETURN_ERROR;
3117 316 : dlt_user_printf("%s ", text);
3118 :
3119 316 : if (dlt_message_payload(message, text, size, DLT_OUTPUT_HEX, verbose) < DLT_RETURN_OK)
3120 : return DLT_RETURN_ERROR;
3121 316 : dlt_user_printf("[%s]\n", text);
3122 :
3123 316 : return DLT_RETURN_OK;
3124 : }
3125 :
3126 328 : DltReturnValue dlt_message_print_ascii(DltMessage *message, char *text, uint32_t size, int verbose)
3127 : {
3128 328 : if ((message == NULL) || (text == NULL))
3129 : return DLT_RETURN_WRONG_PARAMETER;
3130 :
3131 316 : if (dlt_message_header(message, text, size, verbose) < DLT_RETURN_OK)
3132 : return DLT_RETURN_ERROR;
3133 316 : dlt_user_printf("%s ", text);
3134 :
3135 316 : if (dlt_message_payload(message, text, size, DLT_OUTPUT_ASCII, verbose) < DLT_RETURN_OK)
3136 : return DLT_RETURN_ERROR;
3137 316 : dlt_user_printf("[%s]\n", text);
3138 :
3139 316 : return DLT_RETURN_OK;
3140 : }
3141 :
3142 328 : DltReturnValue dlt_message_print_mixed_plain(DltMessage *message, char *text, uint32_t size, int verbose)
3143 : {
3144 328 : if ((message == NULL) || (text == NULL))
3145 : return DLT_RETURN_WRONG_PARAMETER;
3146 :
3147 316 : if (dlt_message_header(message, text, size, verbose) < DLT_RETURN_OK)
3148 : return DLT_RETURN_ERROR;
3149 316 : dlt_user_printf("%s \n", text);
3150 :
3151 316 : if (dlt_message_payload(message, text, size, DLT_OUTPUT_MIXED_FOR_PLAIN, verbose) < DLT_RETURN_OK)
3152 : return DLT_RETURN_ERROR;
3153 316 : dlt_user_printf("[%s]\n", text);
3154 :
3155 316 : return DLT_RETURN_OK;
3156 : }
3157 :
3158 328 : DltReturnValue dlt_message_print_mixed_html(DltMessage *message, char *text, uint32_t size, int verbose)
3159 : {
3160 328 : if ((message == NULL) || (text == NULL))
3161 : return DLT_RETURN_WRONG_PARAMETER;
3162 :
3163 316 : if (dlt_message_header(message, text, size, verbose) < DLT_RETURN_OK)
3164 : return DLT_RETURN_ERROR;
3165 316 : dlt_user_printf("%s \n", text);
3166 :
3167 316 : if (dlt_message_payload(message, text, size, DLT_OUTPUT_MIXED_FOR_HTML, verbose) < DLT_RETURN_OK)
3168 : return DLT_RETURN_ERROR;
3169 :
3170 316 : dlt_user_printf("[%s]\n", text);
3171 :
3172 316 : return DLT_RETURN_OK;
3173 : }
3174 :
3175 2771 : DltReturnValue dlt_message_argument_print(DltMessage *msg,
3176 : uint32_t type_info,
3177 : uint8_t **ptr,
3178 : int32_t *datalength,
3179 : char *text,
3180 : size_t textlength,
3181 : int byteLength,
3182 : int __attribute__((unused)) verbose)
3183 : {
3184 : /* check null pointers */
3185 2771 : if ((msg == NULL) || (ptr == NULL) || (datalength == NULL) || (text == NULL))
3186 : return DLT_RETURN_WRONG_PARAMETER;
3187 :
3188 : uint16_t length = 0, length2 = 0, length3 = 0;
3189 :
3190 : uint8_t value8u = 0;
3191 : uint16_t value16u = 0, value16u_tmp = 0;
3192 : uint32_t value32u = 0, value32u_tmp = 0;
3193 : uint64_t value64u = 0, value64u_tmp = 0;
3194 :
3195 : int8_t value8i = 0;
3196 : int16_t value16i = 0, value16i_tmp = 0;
3197 : int32_t value32i = 0, value32i_tmp = 0;
3198 : int64_t value64i = 0, value64i_tmp = 0;
3199 :
3200 2756 : float32_t value32f = 0, value32f_tmp = 0;
3201 2756 : int32_t value32f_tmp_int32i = 0, value32f_tmp_int32i_swaped = 0;
3202 2756 : float64_t value64f = 0, value64f_tmp = 0;
3203 2756 : int64_t value64f_tmp_int64i = 0, value64f_tmp_int64i_swaped = 0;
3204 :
3205 : uint32_t quantisation_tmp = 0;
3206 :
3207 : // pointer to the value string
3208 : char* value_text = text;
3209 : // pointer to the "unit" attribute string, if there is one (only for *INT and FLOAT*)
3210 : const uint8_t* unit_text_src = NULL;
3211 : // length of the "unit" attribute string, if there is one (only for *INT and FLOAT*)
3212 : size_t unit_text_len = 0;
3213 :
3214 : /* apparently this makes no sense but needs to be done to prevent compiler warning.
3215 : * This variable is only written by DLT_MSG_READ_VALUE macro in if (type_info & DLT_TYPE_INFO_FIXP)
3216 : * case but never read anywhere */
3217 : quantisation_tmp += quantisation_tmp;
3218 :
3219 2756 : if ((type_info & DLT_TYPE_INFO_STRG) &&
3220 1159 : (((type_info & DLT_TYPE_INFO_SCOD) == DLT_SCOD_ASCII) || ((type_info & DLT_TYPE_INFO_SCOD) == DLT_SCOD_UTF8))) {
3221 : /* string type or utf8-encoded string type */
3222 1159 : if (byteLength < 0) {
3223 1159 : DLT_MSG_READ_VALUE(value16u_tmp, *ptr, *datalength, uint16_t);
3224 :
3225 1159 : if ((*datalength) < 0)
3226 : return DLT_RETURN_ERROR;
3227 :
3228 1159 : length = (uint16_t) DLT_ENDIAN_GET_16(msg->standardheader->htyp, value16u_tmp);
3229 : }
3230 : else {
3231 0 : length = (uint16_t)byteLength;
3232 : }
3233 :
3234 1159 : if (type_info & DLT_TYPE_INFO_VARI) {
3235 0 : DLT_MSG_READ_VALUE(value16u_tmp, *ptr, *datalength, uint16_t);
3236 :
3237 0 : if ((*datalength) < 0)
3238 : return DLT_RETURN_ERROR;
3239 :
3240 0 : length2 = (uint16_t) DLT_ENDIAN_GET_16(msg->standardheader->htyp, value16u_tmp);
3241 :
3242 0 : if ((*datalength) < length2)
3243 : return DLT_RETURN_ERROR;
3244 :
3245 0 : if (print_with_attributes) {
3246 : // Print "name" attribute, if we have one with non-zero size.
3247 0 : if (length2 > 1) {
3248 0 : snprintf(text, (size_t)textlength, "%s:", *ptr);
3249 0 : value_text += length2+1-1; // +1 for ":" and -1 for NUL
3250 0 : textlength -= (size_t)(length2+1-1);
3251 : }
3252 : }
3253 :
3254 0 : *ptr += length2;
3255 0 : *datalength -= length2;
3256 : }
3257 :
3258 1159 : DLT_MSG_READ_STRING(value_text, *ptr, *datalength, textlength, length);
3259 :
3260 1159 : if ((*datalength) < 0)
3261 : return DLT_RETURN_ERROR;
3262 : }
3263 1597 : else if (type_info & DLT_TYPE_INFO_BOOL)
3264 : {
3265 : /* Boolean type */
3266 112 : if (type_info & DLT_TYPE_INFO_VARI) {
3267 0 : DLT_MSG_READ_VALUE(value16u_tmp, *ptr, *datalength, uint16_t);
3268 :
3269 0 : if ((*datalength) < 0)
3270 : return DLT_RETURN_ERROR;
3271 :
3272 0 : length2 = (uint16_t) DLT_ENDIAN_GET_16(msg->standardheader->htyp, value16u_tmp);
3273 :
3274 0 : if ((*datalength) < length2)
3275 : return DLT_RETURN_ERROR;
3276 :
3277 0 : if (print_with_attributes) {
3278 : // Print "name" attribute, if we have one with non-zero size.
3279 0 : if (length2 > 1) {
3280 0 : snprintf(text, (size_t)textlength, "%s:", *ptr);
3281 0 : value_text += length2+1-1; // +1 for ":" and -1 for NUL
3282 0 : textlength -= (size_t)(length2+1-2);
3283 : }
3284 : }
3285 :
3286 0 : *ptr += length2;
3287 0 : *datalength -= length2;
3288 : }
3289 :
3290 : value8u = 0;
3291 112 : DLT_MSG_READ_VALUE(value8u, *ptr, *datalength, uint8_t); /* No endian conversion necessary */
3292 :
3293 112 : if ((*datalength) < 0)
3294 : return DLT_RETURN_ERROR;
3295 :
3296 110 : snprintf(value_text, textlength, "%d", value8u);
3297 : }
3298 1485 : else if ((type_info & DLT_TYPE_INFO_UINT) && (DLT_SCOD_BIN == (type_info & DLT_TYPE_INFO_SCOD)))
3299 : {
3300 0 : if (DLT_TYLE_8BIT == (type_info & DLT_TYPE_INFO_TYLE)) {
3301 0 : DLT_MSG_READ_VALUE(value8u, *ptr, *datalength, uint8_t); /* No endian conversion necessary */
3302 :
3303 0 : if ((*datalength) < 0)
3304 0 : return DLT_RETURN_ERROR;
3305 :
3306 0 : char binary[10] = { '\0' }; /* e.g.: "0b1100 0010" */
3307 : int i;
3308 :
3309 0 : for (i = (1 << 7); i > 0; i >>= 1) {
3310 0 : if ((1 << 3) == i)
3311 : strcat(binary, " ");
3312 :
3313 0 : strcat(binary, (i == (value8u & i)) ? "1" : "0");
3314 : }
3315 :
3316 : snprintf(value_text, textlength, "0b%s", binary);
3317 : }
3318 :
3319 0 : if (DLT_TYLE_16BIT == (type_info & DLT_TYPE_INFO_TYLE)) {
3320 0 : DLT_MSG_READ_VALUE(value16u, *ptr, *datalength, uint16_t);
3321 :
3322 0 : if ((*datalength) < 0)
3323 0 : return DLT_RETURN_ERROR;
3324 :
3325 0 : char binary[20] = { '\0' }; /* e.g.: "0b1100 0010 0011 0110" */
3326 : int i;
3327 :
3328 0 : for (i = (1 << 15); i > 0; i >>= 1) {
3329 0 : if (((1 << 3) == i) || ((1 << 7) == i) || ((1 << 11) == i))
3330 : strcat(binary, " ");
3331 :
3332 0 : strcat(binary, (i == (value16u & i)) ? "1" : "0");
3333 : }
3334 :
3335 : snprintf(value_text, textlength, "0b%s", binary);
3336 : }
3337 : }
3338 1485 : else if ((type_info & DLT_TYPE_INFO_UINT) && (DLT_SCOD_HEX == (type_info & DLT_TYPE_INFO_SCOD)))
3339 : {
3340 0 : if (DLT_TYLE_8BIT == (type_info & DLT_TYPE_INFO_TYLE)) {
3341 0 : DLT_MSG_READ_VALUE(value8u, *ptr, *datalength, uint8_t); /* No endian conversion necessary */
3342 :
3343 0 : if ((*datalength) < 0)
3344 : return DLT_RETURN_ERROR;
3345 :
3346 0 : snprintf(value_text, textlength, "0x%02x", value8u);
3347 : }
3348 :
3349 0 : if (DLT_TYLE_16BIT == (type_info & DLT_TYPE_INFO_TYLE)) {
3350 0 : DLT_MSG_READ_VALUE(value16u, *ptr, *datalength, uint16_t);
3351 :
3352 0 : if ((*datalength) < 0)
3353 : return DLT_RETURN_ERROR;
3354 :
3355 0 : snprintf(value_text, textlength, "0x%04x", value16u);
3356 : }
3357 :
3358 0 : if (DLT_TYLE_32BIT == (type_info & DLT_TYPE_INFO_TYLE)) {
3359 0 : DLT_MSG_READ_VALUE(value32u, *ptr, *datalength, uint32_t);
3360 :
3361 0 : if ((*datalength) < 0)
3362 : return DLT_RETURN_ERROR;
3363 :
3364 : snprintf(value_text, textlength, "0x%08x", value32u);
3365 : }
3366 :
3367 0 : if (DLT_TYLE_64BIT == (type_info & DLT_TYPE_INFO_TYLE)) {
3368 0 : *ptr += 4;
3369 0 : DLT_MSG_READ_VALUE(value32u, *ptr, *datalength, uint32_t);
3370 :
3371 0 : if ((*datalength) < 0)
3372 : return DLT_RETURN_ERROR;
3373 :
3374 : snprintf(value_text, textlength, "0x%08x", value32u);
3375 0 : *ptr -= 8;
3376 0 : DLT_MSG_READ_VALUE(value32u, *ptr, *datalength, uint32_t);
3377 :
3378 0 : if ((*datalength) < 0)
3379 : return DLT_RETURN_ERROR;
3380 :
3381 0 : snprintf(value_text + strlen(value_text), textlength - strlen(value_text), "%08x", value32u);
3382 0 : *ptr += 4;
3383 : }
3384 : }
3385 1485 : else if ((type_info & DLT_TYPE_INFO_SINT) || (type_info & DLT_TYPE_INFO_UINT))
3386 : {
3387 : /* signed or unsigned argument received */
3388 1358 : if (type_info & DLT_TYPE_INFO_VARI) {
3389 0 : DLT_MSG_READ_VALUE(value16u_tmp, *ptr, *datalength, uint16_t);
3390 :
3391 0 : if ((*datalength) < 0)
3392 : return DLT_RETURN_ERROR;
3393 :
3394 0 : length2 = (uint16_t) DLT_ENDIAN_GET_16(msg->standardheader->htyp, value16u_tmp);
3395 0 : DLT_MSG_READ_VALUE(value16u_tmp, *ptr, *datalength, uint16_t);
3396 :
3397 0 : if ((*datalength) < 0)
3398 : return DLT_RETURN_ERROR;
3399 :
3400 0 : length3 = (uint16_t) DLT_ENDIAN_GET_16(msg->standardheader->htyp, value16u_tmp);
3401 :
3402 0 : if ((*datalength) < length2)
3403 : return DLT_RETURN_ERROR;
3404 :
3405 0 : if (print_with_attributes) {
3406 : // Print "name" attribute, if we have one with non-zero size.
3407 0 : if (length2 > 1) {
3408 0 : snprintf(text, (size_t)textlength, "%s:", *ptr);
3409 0 : value_text += length2+1-1; // +1 for ":", and -1 for nul
3410 0 : textlength -= (size_t)(length2+1-1);
3411 : }
3412 : }
3413 :
3414 0 : *ptr += length2;
3415 0 : *datalength -= length2;
3416 :
3417 0 : if ((*datalength) < length3)
3418 : return DLT_RETURN_ERROR;
3419 :
3420 : // We want to add the "unit" attribute only after the value, so remember its pointer and length here.
3421 : unit_text_src = *ptr;
3422 0 : unit_text_len = length3;
3423 :
3424 0 : *ptr += length3;
3425 0 : *datalength -= length3;
3426 : }
3427 :
3428 1358 : if (type_info & DLT_TYPE_INFO_FIXP) {
3429 0 : DLT_MSG_READ_VALUE(quantisation_tmp, *ptr, *datalength, uint32_t);
3430 :
3431 0 : if ((*datalength) < 0)
3432 : return DLT_RETURN_ERROR;
3433 :
3434 0 : switch (type_info & DLT_TYPE_INFO_TYLE) {
3435 0 : case DLT_TYLE_8BIT:
3436 : case DLT_TYLE_16BIT:
3437 : case DLT_TYLE_32BIT:
3438 : {
3439 0 : if ((*datalength) < 4)
3440 : return DLT_RETURN_ERROR;
3441 :
3442 0 : *ptr += 4;
3443 0 : *datalength -= 4;
3444 0 : break;
3445 : }
3446 0 : case DLT_TYLE_64BIT:
3447 : {
3448 0 : if ((*datalength) < 8)
3449 : return DLT_RETURN_ERROR;
3450 :
3451 0 : *ptr += 8;
3452 0 : *datalength -= 8;
3453 0 : break;
3454 : }
3455 0 : case DLT_TYLE_128BIT:
3456 : {
3457 0 : if ((*datalength) < 16)
3458 : return DLT_RETURN_ERROR;
3459 :
3460 0 : *ptr += 16;
3461 0 : *datalength -= 16;
3462 0 : break;
3463 : }
3464 : default:
3465 : {
3466 : return DLT_RETURN_ERROR;
3467 : }
3468 : }
3469 : }
3470 :
3471 1358 : switch (type_info & DLT_TYPE_INFO_TYLE) {
3472 14 : case DLT_TYLE_8BIT:
3473 : {
3474 14 : if (type_info & DLT_TYPE_INFO_SINT) {
3475 : value8i = 0;
3476 7 : DLT_MSG_READ_VALUE(value8i, *ptr, *datalength, int8_t); /* No endian conversion necessary */
3477 :
3478 7 : if ((*datalength) < 0)
3479 : return DLT_RETURN_ERROR;
3480 :
3481 7 : snprintf(value_text, (size_t)textlength, "%d", value8i);
3482 : }
3483 : else {
3484 : value8u = 0;
3485 7 : DLT_MSG_READ_VALUE(value8u, *ptr, *datalength, uint8_t); /* No endian conversion necessary */
3486 :
3487 7 : if ((*datalength) < 0)
3488 : return DLT_RETURN_ERROR;
3489 :
3490 7 : snprintf(value_text, (size_t)textlength, "%d", value8u);
3491 : }
3492 :
3493 : break;
3494 : }
3495 21 : case DLT_TYLE_16BIT:
3496 : {
3497 21 : if (type_info & DLT_TYPE_INFO_SINT) {
3498 : value16i = 0;
3499 : value16i_tmp = 0;
3500 7 : DLT_MSG_READ_VALUE(value16i_tmp, *ptr, *datalength, int16_t);
3501 :
3502 7 : if ((*datalength) < 0)
3503 : return DLT_RETURN_ERROR;
3504 :
3505 7 : value16i = (int16_t) DLT_ENDIAN_GET_16(msg->standardheader->htyp, value16i_tmp);
3506 7 : snprintf(value_text, (size_t)textlength, "%hd", value16i);
3507 : }
3508 : else {
3509 : value16u = 0;
3510 : value16u_tmp = 0;
3511 14 : DLT_MSG_READ_VALUE(value16u_tmp, *ptr, *datalength, uint16_t);
3512 :
3513 14 : if ((*datalength) < 0)
3514 : return DLT_RETURN_ERROR;
3515 :
3516 14 : value16u = (uint16_t) DLT_ENDIAN_GET_16(msg->standardheader->htyp, value16u_tmp);
3517 14 : snprintf(value_text, (size_t)textlength, "%hu", value16u);
3518 : }
3519 :
3520 : break;
3521 : }
3522 1309 : case DLT_TYLE_32BIT:
3523 : {
3524 1309 : if (type_info & DLT_TYPE_INFO_SINT) {
3525 : value32i = 0;
3526 : value32i_tmp = 0;
3527 287 : DLT_MSG_READ_VALUE(value32i_tmp, *ptr, *datalength, int32_t);
3528 :
3529 287 : if ((*datalength) < 0)
3530 : return DLT_RETURN_ERROR;
3531 :
3532 287 : value32i = (int32_t) DLT_ENDIAN_GET_32(msg->standardheader->htyp, (uint32_t)value32i_tmp);
3533 : snprintf(value_text, (size_t)textlength, "%d", value32i);
3534 : }
3535 : else {
3536 : value32u = 0;
3537 : value32u_tmp = 0;
3538 1022 : DLT_MSG_READ_VALUE(value32u_tmp, *ptr, *datalength, uint32_t);
3539 :
3540 1022 : if ((*datalength) < 0)
3541 : return DLT_RETURN_ERROR;
3542 :
3543 1022 : value32u = DLT_ENDIAN_GET_32(msg->standardheader->htyp, value32u_tmp);
3544 : snprintf(value_text, (size_t)textlength, "%u", value32u);
3545 : }
3546 :
3547 : break;
3548 : }
3549 14 : case DLT_TYLE_64BIT:
3550 : {
3551 14 : if (type_info & DLT_TYPE_INFO_SINT) {
3552 : value64i = 0;
3553 : value64i_tmp = 0;
3554 7 : DLT_MSG_READ_VALUE(value64i_tmp, *ptr, *datalength, int64_t);
3555 :
3556 7 : if ((*datalength) < 0)
3557 : return DLT_RETURN_ERROR;
3558 :
3559 7 : value64i = (int64_t) DLT_ENDIAN_GET_64(msg->standardheader->htyp, (uint64_t)value64i_tmp);
3560 : #if defined (__WIN32__) && !defined(_MSC_VER)
3561 : snprintf(value_text, (size_t)textlength, "%I64d", value64i);
3562 : #else
3563 : snprintf(value_text, (size_t)textlength, "%" PRId64, value64i);
3564 : #endif
3565 : }
3566 : else {
3567 : value64u = 0;
3568 : value64u_tmp = 0;
3569 7 : DLT_MSG_READ_VALUE(value64u_tmp, *ptr, *datalength, uint64_t);
3570 :
3571 7 : if ((*datalength) < 0)
3572 : return DLT_RETURN_ERROR;
3573 :
3574 7 : value64u = DLT_ENDIAN_GET_64(msg->standardheader->htyp, value64u_tmp);
3575 : #if defined (__WIN32__) && !defined(_MSC_VER)
3576 : snprintf(value_text, textlength, "%I64u", value64u);
3577 : #else
3578 : snprintf(value_text, textlength, "%" PRIu64, value64u);
3579 : #endif
3580 : }
3581 :
3582 : break;
3583 : }
3584 0 : case DLT_TYLE_128BIT:
3585 : {
3586 0 : if (*datalength >= 16)
3587 0 : dlt_print_hex_string(value_text, (int) textlength, *ptr, 16);
3588 :
3589 0 : if ((*datalength) < 16)
3590 : return DLT_RETURN_ERROR;
3591 :
3592 0 : *ptr += 16;
3593 0 : *datalength -= 16;
3594 0 : break;
3595 : }
3596 : default:
3597 : {
3598 : return DLT_RETURN_ERROR;
3599 : }
3600 : }
3601 : }
3602 127 : else if (type_info & DLT_TYPE_INFO_FLOA)
3603 : {
3604 : /* float data argument */
3605 14 : if (type_info & DLT_TYPE_INFO_VARI) {
3606 0 : DLT_MSG_READ_VALUE(value16u_tmp, *ptr, *datalength, uint16_t);
3607 :
3608 0 : if ((*datalength) < 0)
3609 : return DLT_RETURN_ERROR;
3610 :
3611 0 : length2 = DLT_ENDIAN_GET_16(msg->standardheader->htyp, value16u_tmp);
3612 0 : DLT_MSG_READ_VALUE(value16u_tmp, *ptr, *datalength, uint16_t);
3613 :
3614 0 : if ((*datalength) < 0)
3615 : return DLT_RETURN_ERROR;
3616 :
3617 0 : length3 = DLT_ENDIAN_GET_16(msg->standardheader->htyp, value16u_tmp);
3618 :
3619 0 : if ((*datalength) < length2)
3620 : return DLT_RETURN_ERROR;
3621 :
3622 0 : if (print_with_attributes) {
3623 : // Print "name" attribute, if we have one with non-zero size.
3624 0 : if (length2 > 1) {
3625 0 : snprintf(text, textlength, "%s:", *ptr);
3626 0 : value_text += length2+1-1; // +1 for ":" and -1 for NUL
3627 0 : textlength -= (size_t)length2+1-1;
3628 : }
3629 : }
3630 :
3631 0 : *ptr += length2;
3632 0 : *datalength -= length2;
3633 :
3634 0 : if ((*datalength) < length3)
3635 : return DLT_RETURN_ERROR;
3636 :
3637 : // We want to add the "unit" attribute only after the value, so remember its pointer and length here.
3638 : unit_text_src = *ptr;
3639 0 : unit_text_len = length3;
3640 :
3641 0 : *ptr += length3;
3642 0 : *datalength -= length3;
3643 : }
3644 :
3645 14 : switch (type_info & DLT_TYPE_INFO_TYLE) {
3646 0 : case DLT_TYLE_8BIT:
3647 : {
3648 0 : if (*datalength >= 1)
3649 0 : dlt_print_hex_string(value_text, (int) textlength, *ptr, 1);
3650 :
3651 0 : if ((*datalength) < 1)
3652 : return DLT_RETURN_ERROR;
3653 :
3654 0 : *ptr += 1;
3655 0 : *datalength -= 1;
3656 0 : break;
3657 : }
3658 0 : case DLT_TYLE_16BIT:
3659 : {
3660 0 : if (*datalength >= 2)
3661 0 : dlt_print_hex_string(value_text, (int) textlength, *ptr, 2);
3662 :
3663 0 : if ((*datalength) < 2)
3664 : return DLT_RETURN_ERROR;
3665 :
3666 0 : *ptr += 2;
3667 0 : *datalength -= 2;
3668 0 : break;
3669 : }
3670 : case DLT_TYLE_32BIT:
3671 : {
3672 : if (sizeof(float32_t) == 4) {
3673 : value32f = 0;
3674 : value32f_tmp = 0;
3675 : value32f_tmp_int32i = 0;
3676 : value32f_tmp_int32i_swaped = 0;
3677 7 : DLT_MSG_READ_VALUE(value32f_tmp, *ptr, *datalength, float32_t);
3678 :
3679 7 : if ((*datalength) < 0)
3680 : return DLT_RETURN_ERROR;
3681 :
3682 : memcpy(&value32f_tmp_int32i, &value32f_tmp, sizeof(float32_t));
3683 : value32f_tmp_int32i_swaped =
3684 7 : (int32_t) DLT_ENDIAN_GET_32(msg->standardheader->htyp, (uint32_t)value32f_tmp_int32i);
3685 : memcpy(&value32f, &value32f_tmp_int32i_swaped, sizeof(float32_t));
3686 7 : snprintf(value_text, textlength, "%g", value32f);
3687 : }
3688 : else {
3689 : dlt_log(LOG_ERR, "Invalid size of float32_t\n");
3690 : return DLT_RETURN_ERROR;
3691 : }
3692 :
3693 : break;
3694 : }
3695 : case DLT_TYLE_64BIT:
3696 : {
3697 : if (sizeof(float64_t) == 8) {
3698 : value64f = 0;
3699 : value64f_tmp = 0;
3700 : value64f_tmp_int64i = 0;
3701 : value64f_tmp_int64i_swaped = 0;
3702 7 : DLT_MSG_READ_VALUE(value64f_tmp, *ptr, *datalength, float64_t);
3703 :
3704 7 : if ((*datalength) < 0)
3705 : return DLT_RETURN_ERROR;
3706 :
3707 : memcpy(&value64f_tmp_int64i, &value64f_tmp, sizeof(float64_t));
3708 : value64f_tmp_int64i_swaped =
3709 7 : (int64_t) DLT_ENDIAN_GET_64(msg->standardheader->htyp, (uint64_t)value64f_tmp_int64i);
3710 : memcpy(&value64f, &value64f_tmp_int64i_swaped, sizeof(float64_t));
3711 : #ifdef __arm__
3712 : snprintf(value_text, textlength, "ILLEGAL");
3713 : #else
3714 : snprintf(value_text, textlength, "%g", value64f);
3715 : #endif
3716 : }
3717 : else {
3718 : dlt_log(LOG_ERR, "Invalid size of float64_t\n");
3719 : return DLT_RETURN_ERROR;
3720 : }
3721 :
3722 : break;
3723 : }
3724 0 : case DLT_TYLE_128BIT:
3725 : {
3726 0 : if (*datalength >= 16)
3727 0 : dlt_print_hex_string(value_text, (int)textlength, *ptr, 16);
3728 :
3729 0 : if ((*datalength) < 16)
3730 : return DLT_RETURN_ERROR;
3731 :
3732 0 : *ptr += 16;
3733 0 : *datalength -= 16;
3734 0 : break;
3735 : }
3736 : default:
3737 : {
3738 : return DLT_RETURN_ERROR;
3739 : }
3740 : }
3741 : }
3742 113 : else if (type_info & DLT_TYPE_INFO_RAWD)
3743 : {
3744 : /* raw data argument */
3745 112 : DLT_MSG_READ_VALUE(value16u_tmp, *ptr, *datalength, uint16_t);
3746 :
3747 112 : if ((*datalength) < 0)
3748 : return DLT_RETURN_ERROR;
3749 :
3750 110 : length = DLT_ENDIAN_GET_16(msg->standardheader->htyp, value16u_tmp);
3751 :
3752 110 : if (type_info & DLT_TYPE_INFO_VARI) {
3753 0 : DLT_MSG_READ_VALUE(value16u_tmp, *ptr, *datalength, uint16_t);
3754 :
3755 0 : if ((*datalength) < 0)
3756 : return DLT_RETURN_ERROR;
3757 :
3758 0 : length2 = DLT_ENDIAN_GET_16(msg->standardheader->htyp, value16u_tmp);
3759 :
3760 0 : if ((*datalength) < length2)
3761 : return DLT_RETURN_ERROR;
3762 :
3763 0 : if (print_with_attributes) {
3764 : // Print "name" attribute, if we have one with non-zero size.
3765 0 : if (length2 > 1) {
3766 0 : snprintf(text, textlength, "%s:", *ptr);
3767 0 : value_text += length2+1-1; // +1 for ":" and -1 for NUL
3768 0 : textlength -= (size_t)(length2+1-1);
3769 : }
3770 : }
3771 :
3772 0 : *ptr += length2;
3773 0 : *datalength -= length2;
3774 : }
3775 :
3776 110 : if ((*datalength) < length)
3777 : return DLT_RETURN_ERROR;
3778 :
3779 9 : if (dlt_print_hex_string_delim(value_text, (int) textlength, *ptr, length, '\'') < DLT_RETURN_OK)
3780 : return DLT_RETURN_ERROR;
3781 9 : *ptr += length;
3782 9 : *datalength -= length;
3783 : }
3784 1 : else if (type_info & DLT_TYPE_INFO_TRAI)
3785 : {
3786 : /* trace info argument */
3787 0 : DLT_MSG_READ_VALUE(value16u_tmp, *ptr, *datalength, uint16_t);
3788 :
3789 0 : if ((*datalength) < 0)
3790 : return DLT_RETURN_ERROR;
3791 :
3792 0 : length = DLT_ENDIAN_GET_16(msg->standardheader->htyp, value16u_tmp);
3793 :
3794 0 : DLT_MSG_READ_STRING(value_text, *ptr, *datalength, textlength, length);
3795 :
3796 0 : if ((*datalength) < 0)
3797 : return DLT_RETURN_ERROR;
3798 : }
3799 : else {
3800 : return DLT_RETURN_ERROR;
3801 : }
3802 :
3803 2650 : if (*datalength < 0) {
3804 0 : dlt_log(LOG_ERR, "Payload of DLT message corrupted\n");
3805 0 : return DLT_RETURN_ERROR;
3806 : }
3807 :
3808 : // Now write "unit" attribute, but only if it has more than only a nul-termination char.
3809 2650 : if (print_with_attributes) {
3810 0 : if (unit_text_len > 1) {
3811 : // 'value_text' still points to the +start+ of the value text
3812 0 : size_t currLen = strlen(value_text);
3813 :
3814 0 : char* unitText = value_text + currLen;
3815 0 : textlength -= currLen;
3816 : snprintf(unitText, textlength, ":%s", unit_text_src);
3817 : }
3818 : }
3819 :
3820 : return DLT_RETURN_OK;
3821 : }
3822 :
3823 24514 : void dlt_check_envvar()
3824 : {
3825 24514 : char *env_log_filename = getenv("DLT_LOG_FILENAME");
3826 :
3827 24514 : if (env_log_filename != NULL)
3828 0 : dlt_log_set_filename(env_log_filename);
3829 :
3830 24514 : char *env_log_level_str = getenv("DLT_LOG_LEVEL");
3831 :
3832 24514 : if (env_log_level_str != NULL) {
3833 0 : int level = 0;
3834 :
3835 0 : if (sscanf(env_log_level_str, "%d", &level) == 1)
3836 0 : dlt_log_set_level(level);
3837 : }
3838 :
3839 24514 : char *env_log_mode = getenv("DLT_LOG_MODE");
3840 :
3841 24514 : if (env_log_mode != NULL) {
3842 0 : int mode = 0;
3843 :
3844 0 : if (sscanf(env_log_mode, "%d", &mode) == 1)
3845 0 : dlt_log_init(mode);
3846 : }
3847 :
3848 : #if defined DLT_DAEMON_USE_FIFO_IPC || defined DLT_LIB_USE_FIFO_IPC
3849 24514 : char *env_pipe_dir = getenv("DLT_PIPE_DIR");
3850 :
3851 24514 : if (env_pipe_dir != NULL)
3852 0 : dlt_log_set_fifo_basedir(env_pipe_dir);
3853 : else
3854 24514 : dlt_log_set_fifo_basedir(DLT_USER_IPC_PATH);
3855 :
3856 : #endif
3857 :
3858 : #ifdef DLT_SHM_ENABLE
3859 : char *env_shm_name = getenv("DLT_SHM_NAME");
3860 :
3861 : if (env_shm_name != NULL)
3862 : dlt_log_set_shm_name(env_shm_name);
3863 :
3864 : #endif
3865 24514 : }
3866 :
3867 2 : int dlt_set_loginfo_parse_service_id(char *resp_text,
3868 : uint32_t *service_id,
3869 : uint8_t *service_opt)
3870 : {
3871 : int ret = -1;
3872 : char get_log_info_tag[GET_LOG_INFO_LENGTH];
3873 : char service_opt_str[SERVICE_OPT_LENGTH];
3874 :
3875 2 : if ((resp_text == NULL) || (service_id == NULL) || (service_opt == NULL))
3876 : return DLT_RETURN_ERROR;
3877 :
3878 : /* ascii type, syntax is 'get_log_info, ..' */
3879 : /* check target id */
3880 : strncpy(get_log_info_tag, "get_log_info", strlen("get_log_info") + 1);
3881 2 : ret = memcmp((void *)resp_text, (void *)get_log_info_tag, sizeof(get_log_info_tag) - 1);
3882 :
3883 2 : if (ret == 0) {
3884 2 : *service_id = DLT_SERVICE_ID_GET_LOG_INFO;
3885 : /* reading the response mode from the resp_text. eg. option 7*/
3886 2 : service_opt_str[0] = *(resp_text + GET_LOG_INFO_LENGTH + 1);
3887 2 : service_opt_str[1] = *(resp_text + GET_LOG_INFO_LENGTH + 2);
3888 2 : service_opt_str[2] = 0;
3889 2 : *service_opt = (uint8_t) atoi(service_opt_str);
3890 : }
3891 :
3892 : return ret;
3893 : }
3894 :
3895 14 : uint16_t dlt_getloginfo_conv_ascii_to_uint16_t(char *rp, int *rp_count)
3896 : {
3897 14 : char num_work[5] = { 0 };
3898 : char *endptr;
3899 :
3900 14 : if ((rp == NULL) || (rp_count == NULL))
3901 : return (uint16_t)0xFFFF;
3902 :
3903 : /* ------------------------------------------------------
3904 : * from: [89 13 ] -> to: ['+0x'1389\0] -> to num
3905 : * ------------------------------------------------------ */
3906 14 : num_work[0] = *(rp + *rp_count + 3);
3907 14 : num_work[1] = *(rp + *rp_count + 4);
3908 14 : num_work[2] = *(rp + *rp_count + 0);
3909 14 : num_work[3] = *(rp + *rp_count + 1);
3910 : num_work[4] = 0;
3911 14 : *rp_count += 6;
3912 :
3913 14 : return (uint16_t)strtol(num_work, &endptr, 16);
3914 : }
3915 :
3916 12 : int16_t dlt_getloginfo_conv_ascii_to_int16_t(char *rp, int *rp_count)
3917 : {
3918 12 : char num_work[3] = { 0 };
3919 : char *endptr;
3920 :
3921 12 : if ((rp == NULL) || (rp_count == NULL))
3922 : return -1;
3923 :
3924 : /* ------------------------------------------------------
3925 : * from: [89 ] -> to: ['0x'89\0] -> to num
3926 : * ------------------------------------------------------ */
3927 12 : num_work[0] = *(rp + *rp_count + 0);
3928 12 : num_work[1] = *(rp + *rp_count + 1);
3929 : num_work[2] = 0;
3930 12 : *rp_count += 3;
3931 :
3932 12 : return (signed char)strtol(num_work, &endptr, 16);
3933 : }
3934 :
3935 11 : void dlt_getloginfo_conv_ascii_to_string(char *rp, int *rp_count, char *wp, int len)
3936 : {
3937 11 : if ((rp == NULL ) || (rp_count == NULL ) || (wp == NULL ))
3938 : return;
3939 : /* ------------------------------------------------------
3940 : * from: [72 65 6d 6f ] -> to: [0x72,0x65,0x6d,0x6f,0x00]
3941 : * ------------------------------------------------------ */
3942 :
3943 11 : int count = dlt_getloginfo_conv_ascii_to_id(rp, rp_count, wp, len);
3944 11 : *(wp + count) = '\0';
3945 :
3946 11 : return;
3947 : }
3948 :
3949 20 : int dlt_getloginfo_conv_ascii_to_id(char *rp, int *rp_count, char *wp, int len)
3950 : {
3951 20 : char number16[3] = { 0 };
3952 : char *endptr;
3953 : int count;
3954 :
3955 20 : if ((rp == NULL) || (rp_count == NULL) || (wp == NULL))
3956 : return 0;
3957 :
3958 : /* ------------------------------------------------------
3959 : * from: [72 65 6d 6f ] -> to: [0x72,0x65,0x6d,0x6f]
3960 : * ------------------------------------------------------ */
3961 289 : for (count = 0; count < len; count++) {
3962 269 : number16[0] = *(rp + *rp_count + 0);
3963 269 : number16[1] = *(rp + *rp_count + 1);
3964 269 : *(wp + count) = (char) strtol(number16, &endptr, 16);
3965 269 : *rp_count += 3;
3966 : }
3967 :
3968 : return count;
3969 : }
3970 :
3971 0 : void dlt_hex_ascii_to_binary(const char *ptr, uint8_t *binary, int *size)
3972 : {
3973 0 : char ch = *ptr;
3974 : int pos = 0;
3975 0 : binary[pos] = 0;
3976 : int first = 1;
3977 : int found;
3978 :
3979 : for (;;) {
3980 0 : if (ch == 0) {
3981 0 : *size = pos;
3982 0 : return;
3983 : }
3984 :
3985 : found = 0;
3986 :
3987 0 : if ((ch >= '0') && (ch <= '9')) {
3988 0 : binary[pos] = (uint8_t) ((binary[pos] << 4) + (ch - '0'));
3989 : found = 1;
3990 : }
3991 0 : else if ((ch >= 'A') && (ch <= 'F'))
3992 : {
3993 0 : binary[pos] = (uint8_t) ((binary[pos] << 4) + (ch - 'A' + 10));
3994 : found = 1;
3995 : }
3996 0 : else if ((ch >= 'a') && (ch <= 'f'))
3997 : {
3998 0 : binary[pos] = (uint8_t) ((binary[pos] << 4) + (ch - 'a' + 10));
3999 : found = 1;
4000 : }
4001 :
4002 : if (found) {
4003 0 : if (first) {
4004 : first = 0;
4005 : }
4006 : else {
4007 : first = 1;
4008 0 : pos++;
4009 :
4010 0 : if (pos >= *size)
4011 : return;
4012 :
4013 0 : binary[pos] = 0;
4014 : }
4015 : }
4016 :
4017 0 : ch = *(++ptr);
4018 : }
4019 : }
4020 :
4021 3 : DltReturnValue dlt_file_quick_parsing(DltFile *file, const char *filename,
4022 : int type, int verbose)
4023 : {
4024 3 : PRINT_FUNCTION_VERBOSE(verbose);
4025 : int ret = DLT_RETURN_OK;
4026 3 : char text[DLT_CONVERT_TEXTBUFSIZE] = { 0 };
4027 :
4028 3 : if ((file == NULL) || (filename == NULL))
4029 : return DLT_RETURN_WRONG_PARAMETER;
4030 :
4031 1 : FILE *output = fopen(filename, "w+");
4032 :
4033 1 : if (output == NULL) {
4034 0 : dlt_vlog(LOG_ERR, "Cannot open output file %s for parsing\n", filename);
4035 0 : return DLT_RETURN_ERROR;
4036 : }
4037 :
4038 106 : while (ret >= DLT_RETURN_OK && file->file_position < file->file_length) {
4039 : /* get file position at start of DLT message */
4040 105 : if (verbose)
4041 0 : dlt_vlog(LOG_DEBUG, "Position in file: %" PRIu64 "\n", file->file_position);
4042 :
4043 : /* read all header and payload */
4044 105 : ret = dlt_file_read_header(file, verbose);
4045 :
4046 105 : if (ret < DLT_RETURN_OK)
4047 : break;
4048 :
4049 105 : ret = dlt_file_read_header_extended(file, verbose);
4050 :
4051 105 : if (ret < DLT_RETURN_OK)
4052 : break;
4053 :
4054 105 : ret = dlt_file_read_data(file, verbose);
4055 :
4056 105 : if (ret < DLT_RETURN_OK)
4057 : break;
4058 :
4059 105 : if (file->filter) {
4060 : /* check the filters if message is used */
4061 0 : ret = dlt_message_filter_check(&(file->msg), file->filter, verbose);
4062 :
4063 0 : if (ret != DLT_RETURN_TRUE)
4064 0 : continue;
4065 : }
4066 :
4067 105 : ret = dlt_message_header(&(file->msg), text,
4068 : DLT_CONVERT_TEXTBUFSIZE, verbose);
4069 :
4070 105 : if (ret < DLT_RETURN_OK)
4071 : break;
4072 :
4073 : fprintf(output, "%s", text);
4074 :
4075 105 : ret = dlt_message_payload(&(file->msg), text,
4076 : DLT_CONVERT_TEXTBUFSIZE, type, verbose);
4077 :
4078 105 : if (ret < DLT_RETURN_OK)
4079 : break;
4080 :
4081 : fprintf(output, "[%s]\n", text);
4082 :
4083 : /* store index pointer to message position in DLT file */
4084 105 : file->counter++;
4085 105 : file->position = file->counter_total - 1;
4086 : /* increase total message counter */
4087 105 : file->counter_total++;
4088 : /* store position to next message */
4089 105 : file->file_position = (uint64_t)ftell(file->handle);
4090 : } /* while() */
4091 :
4092 1 : fclose(output);
4093 1 : return ret;
4094 : }
4095 :
4096 :
4097 0 : int dlt_execute_command(char *filename, char *command, ...)
4098 : {
4099 : va_list val;
4100 : int argc;
4101 : char **args = NULL;
4102 0 : int ret = 0;
4103 :
4104 0 : if (command == NULL)
4105 : return -1;
4106 :
4107 : /* Determine number of variadic arguments */
4108 0 : va_start(val, command);
4109 :
4110 0 : for (argc = 2; va_arg(val, char *) != NULL; argc++);
4111 :
4112 0 : va_end(val);
4113 :
4114 : /* Allocate args, put references to command */
4115 0 : args = (char **) malloc( (uint32_t) argc * sizeof(char*));
4116 0 : args[0] = command;
4117 :
4118 0 : va_start(val, command);
4119 :
4120 0 : for (int i = 0; args[i] != NULL; i++)
4121 0 : args[i + 1] = va_arg(val, char *);
4122 :
4123 0 : va_end(val);
4124 :
4125 : /* Run command in child process */
4126 0 : pid_t pid = fork();
4127 :
4128 0 : if (pid == 0) { /* child process */
4129 :
4130 : /* Redirect output if required */
4131 0 : if (filename != NULL) {
4132 : int fd = open(filename, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
4133 :
4134 0 : if (fd < 0)
4135 0 : err(-1, "%s failed on open()", __func__);
4136 :
4137 0 : if (dup2(fd, STDOUT_FILENO) == -1) {
4138 0 : close(fd);
4139 0 : err(-1, "%s failed on dup2()", __func__);
4140 : }
4141 :
4142 0 : close(fd);
4143 : }
4144 :
4145 : /* Run command */
4146 0 : execvp(command, (char **)args);
4147 : }
4148 0 : else if (pid == -1) /* error in fork */
4149 : {
4150 0 : ret = -1;
4151 : }
4152 : else /* parent */
4153 : {
4154 0 : if (wait(&ret) == -1) {
4155 0 : err(-1, "%s failed on wait()", __func__);
4156 : }
4157 : }
4158 :
4159 0 : free(args);
4160 0 : return ret;
4161 : }
4162 :
4163 5 : char *get_filename_ext(const char *filename)
4164 : {
4165 5 : if (filename == NULL) {
4166 0 : fprintf(stderr, "ERROR: %s: invalid arguments\n", __func__);
4167 0 : return "";
4168 : }
4169 :
4170 5 : char *dot = strrchr(filename, '.');
4171 5 : return (!dot || dot == filename) ? NULL : dot;
4172 : }
4173 :
4174 6 : bool dlt_extract_base_name_without_ext(const char* const abs_file_name, char* base_name, long base_name_len) {
4175 6 : if (abs_file_name == NULL || base_name == NULL) return false;
4176 :
4177 6 : const char* last_separator = strrchr(abs_file_name, '.');
4178 6 : if (!last_separator) return false;
4179 5 : long length = last_separator - abs_file_name;
4180 : /* Ensure length fits within buffer, leaving room for null terminator */
4181 5 : if (length >= base_name_len)
4182 0 : length = base_name_len - 1;
4183 :
4184 5 : strncpy(base_name, abs_file_name, (size_t)length);
4185 5 : base_name[length] = '\0';
4186 5 : return true;
4187 : }
4188 :
4189 : #ifdef DLT_TRACE_LOAD_CTRL_ENABLE
4190 : static int32_t dlt_output_soft_limit_over_warning(
4191 : DltTraceLoadSettings* const tl_settings,
4192 : DltLogInternal log_internal,
4193 : void *const log_params)
4194 : {
4195 : char local_str[255];
4196 :
4197 : if (!tl_settings || !tl_settings->tl_stat.is_over_soft_limit || tl_settings->tl_stat.slot_left_soft_limit_warn)
4198 : {
4199 : /* No need to output warning message */
4200 : return 0;
4201 : }
4202 :
4203 : /* Calculate extra trace load which was over limit */
4204 : const uint64_t dropped_message_load
4205 : = (tl_settings->tl_stat.hard_limit_over_bytes * DLT_TIMESTAMP_RESOLUTION)
4206 : / TIMESTAMP_BASED_WINDOW_SIZE;
4207 : const uint64_t curr_trace_load = tl_settings->tl_stat.avg_trace_load + dropped_message_load;
4208 : if (curr_trace_load <= tl_settings->soft_limit) {
4209 : /* No need to output warning message */
4210 : return 0;
4211 : }
4212 :
4213 : /* Warning for exceeded soft limit */
4214 : if (tl_settings->ctid[0] == 0) {
4215 : snprintf(local_str, sizeof(local_str),
4216 : "Trace load exceeded trace soft limit on apid %.4s "
4217 : "(soft limit: %u bytes/sec, current: %lu bytes/sec)",
4218 : tl_settings->apid,
4219 : tl_settings->soft_limit,
4220 : curr_trace_load);
4221 : } else {
4222 : snprintf(local_str, sizeof(local_str),
4223 : "Trace load exceeded trace soft limit on apid %.4s, ctid %.4s "
4224 : "(soft limit: %u bytes/sec, current: %lu bytes/sec)",
4225 : tl_settings->apid,
4226 : tl_settings->ctid,
4227 : tl_settings->soft_limit,
4228 : curr_trace_load);
4229 : }
4230 :
4231 : // must be signed int for error return value
4232 : int32_t sent_size = log_internal(DLT_LOG_WARN, local_str, log_params);
4233 : if (sent_size < DLT_RETURN_OK)
4234 : {
4235 : /* Output warning message via other route for safety */
4236 : dlt_log(DLT_LOG_WARN, local_str);
4237 : sent_size = 0;
4238 : }
4239 :
4240 : /* Turn off the flag after sending warning message */
4241 : tl_settings->tl_stat.is_over_soft_limit = false;
4242 : tl_settings->tl_stat.slot_left_soft_limit_warn = DLT_SOFT_LIMIT_WARN_FREQUENCY;
4243 :
4244 : return sent_size;
4245 : }
4246 :
4247 : static int32_t dlt_output_hard_limit_warning(
4248 : DltTraceLoadSettings* const tl_settings,
4249 : DltLogInternal log_internal,
4250 : void *const log_params)
4251 : {
4252 : char local_str[255];
4253 : if (!tl_settings || !tl_settings->tl_stat.is_over_hard_limit || tl_settings->tl_stat.slot_left_hard_limit_warn)
4254 : {
4255 : /* No need to output warning message */
4256 : return 0;
4257 : }
4258 :
4259 : /* Calculate extra trace load which was over limit */
4260 : const uint64_t dropped_message_load
4261 : = (tl_settings->tl_stat.hard_limit_over_bytes * DLT_TIMESTAMP_RESOLUTION)
4262 : / TIMESTAMP_BASED_WINDOW_SIZE;
4263 : const uint64_t curr_trace_load = tl_settings->tl_stat.avg_trace_load + dropped_message_load;
4264 : if (curr_trace_load <= tl_settings->hard_limit) {
4265 : /* No need to output warning message */
4266 : return 0;
4267 : }
4268 :
4269 : if (tl_settings->ctid[0] == 0) {
4270 : snprintf(local_str, sizeof(local_str),
4271 : "Trace load exceeded trace hard limit on apid %.4s "
4272 : "(hard limit: %u bytes/sec, current: %lu bytes/sec) %u messages discarded. ",
4273 : tl_settings->apid,
4274 : tl_settings->hard_limit,
4275 : curr_trace_load,
4276 : tl_settings->tl_stat.hard_limit_over_counter);
4277 : } else {
4278 : snprintf(local_str, sizeof(local_str),
4279 : "Trace load exceeded trace hard limit on apid %.4s, ctid %.4s."
4280 : "(hard limit: %u bytes/sec, current: %lu bytes/sec) %u messages discarded.",
4281 : tl_settings->apid,
4282 : tl_settings->ctid,
4283 : tl_settings->hard_limit,
4284 : curr_trace_load,
4285 : tl_settings->tl_stat.hard_limit_over_counter);
4286 : }
4287 :
4288 : // must be signed int for error return
4289 : int32_t sent_size = log_internal(DLT_LOG_WARN, local_str, log_params);
4290 : if (sent_size < DLT_RETURN_OK)
4291 : {
4292 : /* Output warning message via other route for safety */
4293 : dlt_log(DLT_LOG_WARN, local_str);
4294 : sent_size = 0;
4295 : }
4296 :
4297 : /* Turn off the flag after sending warning message */
4298 : tl_settings->tl_stat.is_over_hard_limit = false;
4299 : tl_settings->tl_stat.hard_limit_over_counter = 0;
4300 : tl_settings->tl_stat.hard_limit_over_bytes = 0;
4301 : tl_settings->tl_stat.slot_left_hard_limit_warn = DLT_HARD_LIMIT_WARN_FREQUENCY;
4302 :
4303 : return sent_size;
4304 : }
4305 :
4306 : static bool dlt_user_cleanup_window(DltTraceLoadStat *const tl_stat)
4307 : {
4308 : if (!tl_stat)
4309 : {
4310 : return false;
4311 : }
4312 :
4313 : uint32_t elapsed_slots = 0;
4314 : /* check if overflow of timestamp happened, after ~119 hours */
4315 : if (tl_stat->curr_abs_slot < tl_stat->last_abs_slot) {
4316 : /* calculate where the next slot starts according to the last slot
4317 : * This works because the value after the uint32 rollover equals is equal to the remainder that did not fit
4318 : * into uint32 before. Therefore, we always have slots that are DLT_TIMESTAMP_RESOLUTION long
4319 : * */
4320 : const uint32_t next_slot_start =
4321 : DLT_TIMESTAMP_RESOLUTION + tl_stat->last_abs_slot;
4322 :
4323 : /* Check if we are already in the next slot */
4324 : if (next_slot_start <= tl_stat->curr_abs_slot) {
4325 : /* Calculate relative amount of elapsed slots */
4326 : elapsed_slots = (tl_stat->curr_abs_slot - next_slot_start) / DLT_TIMESTAMP_RESOLUTION + 1;
4327 : }
4328 : /* else we are not in the next slot yet */
4329 : } else {
4330 : /* no rollover, get difference between slots to get amount of elapsed slots */
4331 : elapsed_slots = (tl_stat->curr_abs_slot - tl_stat->last_abs_slot);
4332 : }
4333 :
4334 : if (!elapsed_slots)
4335 : {
4336 : /* Same slot can be still used. No need to cleanup slot */
4337 : return false;
4338 : }
4339 :
4340 : /* Slot-Based Count down for next warning messages */
4341 : tl_stat->slot_left_soft_limit_warn = (tl_stat->slot_left_soft_limit_warn > elapsed_slots) ?
4342 : (tl_stat->slot_left_soft_limit_warn - elapsed_slots) : 0;
4343 :
4344 : tl_stat->slot_left_hard_limit_warn = (tl_stat->slot_left_hard_limit_warn > elapsed_slots) ?
4345 : (tl_stat->slot_left_hard_limit_warn - elapsed_slots) : 0;
4346 :
4347 : /* Clear whole window when time elapsed longer than window size from last message */
4348 : if (elapsed_slots >= DLT_TRACE_LOAD_WINDOW_SIZE)
4349 : {
4350 : tl_stat->total_bytes_of_window = 0;
4351 : memset(tl_stat->window, 0, sizeof(tl_stat->window));
4352 : return true;
4353 : }
4354 :
4355 : /* Clear skipped no data slots */
4356 : uint32_t temp_slot = tl_stat->last_slot;
4357 : while (temp_slot != tl_stat->curr_slot)
4358 : {
4359 : temp_slot++;
4360 : temp_slot %= DLT_TRACE_LOAD_WINDOW_SIZE;
4361 : tl_stat->total_bytes_of_window -= tl_stat->window[temp_slot];
4362 : tl_stat->window[temp_slot] = 0;
4363 : }
4364 :
4365 : return true;
4366 : }
4367 :
4368 : static int32_t dlt_switch_slot_if_needed(
4369 : DltTraceLoadSettings* const tl_settings,
4370 : DltLogInternal log_internal,
4371 : void* const log_internal_params,
4372 : const uint32_t timestamp)
4373 : {
4374 : if (!tl_settings)
4375 : {
4376 : return 0;
4377 : }
4378 :
4379 : /* Get new window slot No. */
4380 : tl_settings->tl_stat.curr_abs_slot = timestamp / DLT_TRACE_LOAD_WINDOW_RESOLUTION;
4381 : tl_settings->tl_stat.curr_slot = tl_settings->tl_stat.curr_abs_slot % DLT_TRACE_LOAD_WINDOW_SIZE;
4382 :
4383 : /* Cleanup window */
4384 : if (!dlt_user_cleanup_window(&tl_settings->tl_stat))
4385 : {
4386 : /* No need to switch slot because same slot can be still used */
4387 : return 0;
4388 : }
4389 :
4390 : /* If slot is switched and trace load has been over soft/hard limit
4391 : * in previous slot, warning messages may be sent.
4392 : * The warning messages will be also counted as trace load.
4393 : */
4394 : const int32_t sent_warn_msg_bytes =
4395 : dlt_output_soft_limit_over_warning(tl_settings, log_internal, log_internal_params) +
4396 : dlt_output_hard_limit_warning(tl_settings, log_internal, log_internal_params);
4397 : return sent_warn_msg_bytes;
4398 : }
4399 :
4400 : static void dlt_record_trace_load(DltTraceLoadStat *const tl_stat, const int32_t size)
4401 : {
4402 : if (!tl_stat)
4403 : {
4404 : return;
4405 : }
4406 :
4407 : /* Record trace load to current slot by message size of
4408 : * original message and warning message if it was sent
4409 : */
4410 : tl_stat->window[tl_stat->curr_slot] += size;
4411 : tl_stat->total_bytes_of_window += size;
4412 :
4413 : /* Keep the latest time information */
4414 : tl_stat->last_abs_slot = tl_stat->curr_abs_slot;
4415 : tl_stat->last_slot = tl_stat->curr_slot;
4416 :
4417 : /* Calculate average trace load [bytes/sec] in window
4418 : * The division is necessary to normalize the average to bytes per second even if
4419 : * the slot size is not equal to 1s
4420 : * */
4421 : tl_stat->avg_trace_load
4422 : = (tl_stat->total_bytes_of_window * DLT_TIMESTAMP_RESOLUTION) / TIMESTAMP_BASED_WINDOW_SIZE;
4423 : }
4424 :
4425 : static inline bool dlt_is_over_trace_load_soft_limit(DltTraceLoadSettings* const tl_settings)
4426 : {
4427 : if (tl_settings
4428 : && (tl_settings->tl_stat.avg_trace_load > tl_settings->soft_limit || tl_settings->soft_limit == 0))
4429 : {
4430 : /* Mark as soft limit over */
4431 : tl_settings->tl_stat.is_over_soft_limit = true;
4432 : return true;
4433 : }
4434 :
4435 : return false;
4436 : }
4437 :
4438 : static inline bool dlt_is_over_trace_load_hard_limit(
4439 : DltTraceLoadSettings* const tl_settings, const int size)
4440 : {
4441 : if (tl_settings
4442 : && (tl_settings->tl_stat.avg_trace_load > tl_settings->hard_limit
4443 : || tl_settings->hard_limit == 0))
4444 : {
4445 : /* Mark as limit over */
4446 : tl_settings->tl_stat.is_over_hard_limit = true;
4447 : tl_settings->tl_stat.hard_limit_over_counter++;
4448 : tl_settings->tl_stat.hard_limit_over_bytes += size;
4449 :
4450 : /* Delete size of limit over message from window */
4451 : tl_settings->tl_stat.window[tl_settings->tl_stat.curr_slot] -= size;
4452 : tl_settings->tl_stat.total_bytes_of_window -= size;
4453 : return true;
4454 : }
4455 :
4456 : return false;
4457 : }
4458 :
4459 : bool dlt_check_trace_load(
4460 : DltTraceLoadSettings * const tl_settings,
4461 : const int32_t log_level,
4462 : const uint32_t timestamp,
4463 : const int32_t size,
4464 : DltLogInternal internal_dlt_log,
4465 : void* const internal_dlt_log_params)
4466 : {
4467 : /* Unconditionally allow message which has log level: Debug/Verbose to be output */
4468 : if (log_level == DLT_LOG_DEBUG || log_level == DLT_LOG_VERBOSE)
4469 : {
4470 : return true;
4471 : }
4472 :
4473 : if (tl_settings == NULL)
4474 : {
4475 : internal_dlt_log(DLT_LOG_ERROR, "tl_settings is NULL", internal_dlt_log_params);
4476 : return false;
4477 : }
4478 :
4479 : if (size < 0)
4480 : {
4481 : dlt_vlog(LOG_ERR, "Invalid size: %d", size);
4482 : return false;
4483 : }
4484 :
4485 : /* Switch window slot according to timestamp
4486 : * If warning messages for hard/soft limit over are sent,
4487 : * the message size will be returned.
4488 : */
4489 : const int32_t sent_warn_msg_bytes = dlt_switch_slot_if_needed(
4490 : tl_settings, internal_dlt_log, internal_dlt_log_params, timestamp);
4491 :
4492 : /* Record trace load */
4493 : dlt_record_trace_load(&tl_settings->tl_stat, size + sent_warn_msg_bytes);
4494 :
4495 : /* Check if trace load is over the soft limit.
4496 : * Even if trace load is over the soft limit, message will not be discarded.
4497 : * Only the warning message will be output
4498 : */
4499 : dlt_is_over_trace_load_soft_limit(tl_settings);
4500 :
4501 : /* Check if trace load is over hard limit.
4502 : * If trace load is over the limit, message will be discarded.
4503 : */
4504 : const bool allow_output = !dlt_is_over_trace_load_hard_limit(tl_settings, size);
4505 :
4506 : return allow_output;
4507 : }
4508 :
4509 : DltTraceLoadSettings*
4510 : dlt_find_runtime_trace_load_settings(DltTraceLoadSettings *settings, uint32_t settings_count, const char* apid, const char* ctid) {
4511 : if ((apid == NULL) || (strnlen(apid, DLT_ID_SIZE) == 0))
4512 : return NULL;
4513 :
4514 : DltTraceLoadSettings* app_level = NULL;
4515 : size_t ctid_len = (ctid != NULL) ? strnlen(ctid, DLT_ID_SIZE) : 0;
4516 :
4517 : for (uint32_t i = 0; i < settings_count; ++i) {
4518 : if (strncmp(apid, settings->apid, DLT_ID_SIZE) != 0) {
4519 : if (app_level == NULL)
4520 : continue;
4521 : // settings are sorted.
4522 : // If we found a configuration entry which matches the app id already
4523 : // we can exit here because no more entries with the app id will follow anymore.
4524 : break;
4525 : }
4526 :
4527 : if (settings[i].ctid[0] == '\0') {
4528 : app_level = &settings[i];
4529 : if (ctid_len == 0)
4530 : return &settings[i];
4531 : continue;
4532 : }
4533 :
4534 : if ((ctid_len > 0) && (strncmp(ctid, settings[i].ctid, DLT_ID_SIZE) == 0)) {
4535 : return &settings[i];
4536 : }
4537 : }
4538 :
4539 : return app_level;
4540 : }
4541 :
4542 : #endif
|