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