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 Alexander Wenzel <alexander.aw.wenzel@bmw.de>
18 : *
19 : * \copyright Copyright © 2011-2015 BMW AG. \n
20 : * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/.
21 : *
22 : * \file dlt-receive.c
23 : */
24 :
25 :
26 : /*******************************************************************************
27 : ** **
28 : ** SRC-MODULE: dlt-receive.c **
29 : ** **
30 : ** TARGET : linux **
31 : ** **
32 : ** PROJECT : DLT **
33 : ** **
34 : ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de **
35 : ** Markus Klein **
36 : ** **
37 : ** PURPOSE : **
38 : ** **
39 : ** REMARKS : **
40 : ** **
41 : ** PLATFORM DEPENDANT [yes/no]: yes **
42 : ** **
43 : ** TO BE CHANGED BY USER [yes/no]: no **
44 : ** **
45 : *******************************************************************************/
46 :
47 : /*******************************************************************************
48 : ** Author Identity **
49 : ********************************************************************************
50 : ** **
51 : ** Initials Name Company **
52 : ** -------- ------------------------- ---------------------------------- **
53 : ** aw Alexander Wenzel BMW **
54 : ** mk Markus Klein Fraunhofer ESK **
55 : *******************************************************************************/
56 :
57 : /*******************************************************************************
58 : ** Revision Control History **
59 : *******************************************************************************/
60 :
61 : /*
62 : * $LastChangedRevision: 1670 $
63 : * $LastChangedDate: 2011-04-08 15:12:06 +0200 (Fr, 08. Apr 2011) $
64 : * $LastChangedBy$
65 : * Initials Date Comment
66 : * aw 13.01.2010 initial
67 : */
68 :
69 : #include <ctype.h> /* for isprint() */
70 : #include <stdlib.h> /* for atoi() */
71 : #include <sys/stat.h> /* for S_IRUSR, S_IWUSR, S_IRGRP, S_IROTH */
72 : #include <fcntl.h> /* for open() */
73 : #include <sys/uio.h> /* for writev() */
74 : #include <errno.h>
75 : #include <string.h>
76 : #include <glob.h>
77 : #include <syslog.h>
78 : #include <signal.h>
79 : #include <sys/socket.h>
80 : #ifdef __linux__
81 : #include <linux/limits.h>
82 : #else
83 : #include <limits.h>
84 : #endif
85 : #include <inttypes.h>
86 : #include "dlt_log.h"
87 : #include "dlt_client.h"
88 : #include "dlt-control-common.h"
89 :
90 : #define DLT_RECEIVE_ECU_ID "RECV"
91 :
92 : DltClient dltclient;
93 : static bool sig_close_recv = false;
94 :
95 0 : void signal_handler(int signal)
96 : {
97 0 : switch (signal) {
98 0 : case SIGHUP:
99 : case SIGTERM:
100 : case SIGINT:
101 : case SIGQUIT:
102 : /* stop main loop */
103 0 : sig_close_recv = true;
104 0 : shutdown(dltclient.receiver.fd, SHUT_RD);
105 0 : break;
106 : default:
107 : /* This case should never happen! */
108 : break;
109 : } /* switch */
110 0 : }
111 :
112 : /* Function prototypes */
113 : int dlt_receive_message_callback(DltMessage* message, void* data);
114 :
115 : typedef struct {
116 : int aflag;
117 : int sflag;
118 : int xflag;
119 : int mflag;
120 : int vflag;
121 : int yflag;
122 : int uflag;
123 : int rflag;
124 : char* ovalue;
125 : char* ovaluebase; /* ovalue without ".dlt" */
126 : char* fvalue; /* filename for space separated filter file (<AppID> <ContextID>) */
127 : char* jvalue; /* filename for json filter file */
128 : char* evalue;
129 : int bvalue;
130 : int rvalue;
131 : int sendSerialHeaderFlag;
132 : int resyncSerialHeaderFlag;
133 : int64_t climit;
134 : char ecuid[4];
135 : int ohandle;
136 : int64_t totalbytes; /* bytes written so far into the output file, used to check the file size limit */
137 : int part_num; /* number of current output file if limit was exceeded */
138 : DltFile file;
139 : DltFilter filter;
140 : int port;
141 : char* ifaddr;
142 : } DltReceiveData;
143 :
144 : /**
145 : * Print usage information of tool.
146 : */
147 0 : void usage(void)
148 : {
149 : char version[255];
150 :
151 0 : dlt_get_version(version, 255);
152 :
153 : printf("Usage: dlt-receive [options] hostname/serial_device_name\n");
154 : printf("Receive DLT messages from DLT daemon and print or store the messages.\n");
155 : printf("Use filters to filter received messages.\n");
156 : printf("%s \n", version);
157 : printf("Options:\n");
158 : printf(" -a Print DLT messages; payload as ASCII\n");
159 : printf(" -x Print DLT messages; payload as hex\n");
160 : printf(" -m Print DLT messages; payload as hex and ASCII\n");
161 : printf(" -s Print DLT messages; only headers\n");
162 : printf(" -v Verbose mode\n");
163 : printf(" -h Usage\n");
164 : printf(" -S Send message with serial header (Default: Without serial header)\n");
165 : printf(" -R Enable resync serial header\n");
166 : printf(" -y Serial device mode\n");
167 : printf(" -u UDP multicast mode\n");
168 : printf(" -r msecs Reconnect to server with milli seconds specified\n");
169 : printf(" -i addr Host interface address\n");
170 : printf(" -b baudrate Serial device baudrate (Default: 115200)\n");
171 : printf(" -e ecuid Set ECU ID (Default: RECV)\n");
172 : printf(" -o filename Output messages in new DLT file\n");
173 : printf(" -c limit Restrict file size to <limit> bytes when output to file\n");
174 : printf(" When limit is reached, a new file is opened. Use K,M,G as\n");
175 : printf(" suffix to specify kilo-, mega-, giga-bytes respectively\n");
176 : printf(" -f filename Enable filtering of messages with space separated list (<AppID> <ContextID>)\n");
177 : printf(" -j filename Enable filtering of messages with filter defined in json file\n");
178 : printf(" -p port Use the given port instead the default port\n");
179 : printf(" Cannot be used with serial devices\n");
180 0 : }
181 :
182 :
183 0 : int64_t convert_arg_to_byte_size(char* arg)
184 : {
185 : size_t i;
186 : int64_t factor;
187 : int64_t result;
188 :
189 : /* check if valid input */
190 0 : for (i = 0; i < strlen(arg) - 1; ++i)
191 0 : if (!isdigit(arg[i]))
192 : return -2;
193 :
194 : /* last character */
195 : factor = 1;
196 :
197 0 : if ((arg[strlen(arg) - 1] == 'K') || (arg[strlen(arg) - 1] == 'k'))
198 : factor = 1024;
199 : else if ((arg[strlen(arg) - 1] == 'M') || (arg[strlen(arg) - 1] == 'm'))
200 : factor = 1024 * 1024;
201 : else if ((arg[strlen(arg) - 1] == 'G') || (arg[strlen(arg) - 1] == 'g'))
202 : factor = 1024 * 1024 * 1024;
203 0 : else if (!isdigit(arg[strlen(arg) - 1]))
204 : return -2;
205 :
206 : /* range checking */
207 : int64_t const mult = atoll(arg);
208 :
209 0 : if (((INT64_MAX) / factor) < mult)
210 : /* Would overflow! */
211 : return -2;
212 :
213 0 : result = factor * mult;
214 :
215 : /* The result be at least the size of one message
216 : * One message consists of its header + user data:
217 : */
218 : DltMessage msg;
219 : int64_t min_size = sizeof(msg.headerbuffer);
220 : min_size += 2048 /* DLT_USER_BUF_MAX_SIZE */;
221 :
222 0 : if (min_size > result) {
223 0 : dlt_vlog(
224 : LOG_ERR,
225 : "ERROR: Specified limit: %" PRId64 "is smaller than a the size of a single message: %" PRId64 "!\n", result,
226 : min_size);
227 : result = -2;
228 : }
229 :
230 : return result;
231 : }
232 :
233 :
234 : /*
235 : * open output file
236 : */
237 0 : int dlt_receive_open_output_file(DltReceiveData* dltdata)
238 : {
239 : /* if (file_already_exists) */
240 : glob_t outer;
241 :
242 0 : if (glob(
243 0 : dltdata->ovalue,
244 : #ifndef __ANDROID_API__
245 : GLOB_TILDE |
246 : #endif
247 : GLOB_NOSORT,
248 : NULL, &outer)
249 : == 0) {
250 0 : if (dltdata->vflag)
251 0 : dlt_vlog(LOG_INFO, "File %s already exists, need to rename first\n", dltdata->ovalue);
252 :
253 0 : if (dltdata->part_num < 0) {
254 : char pattern[PATH_MAX + 1];
255 0 : pattern[PATH_MAX] = 0;
256 0 : snprintf(pattern, PATH_MAX, "%s.*.dlt", dltdata->ovaluebase);
257 : glob_t inner;
258 :
259 : /* sort does not help here because we have to traverse the
260 : * full result in any case. Remember, a sorted list would look like:
261 : * foo.1.dlt
262 : * foo.10.dlt
263 : * foo.1000.dlt
264 : * foo.11.dlt
265 : */
266 0 : if (glob(
267 : pattern,
268 : #ifndef __ANDROID_API__
269 : GLOB_TILDE |
270 : #endif
271 : GLOB_NOSORT,
272 : NULL, &inner)
273 : == 0) {
274 : /* search for the highest number used */
275 : size_t i;
276 :
277 0 : for (i = 0; i < inner.gl_pathc; ++i) {
278 : /* convert string that follows the period after the initial portion,
279 : * e.g. gt.gl_pathv[i] = foo.1.dlt -> atoi("1.dlt");
280 : */
281 0 : int cur = atoi(&inner.gl_pathv[i][strlen(dltdata->ovaluebase) + 1]);
282 :
283 0 : if (cur > dltdata->part_num)
284 0 : dltdata->part_num = cur;
285 : }
286 : }
287 :
288 0 : globfree(&inner);
289 :
290 0 : ++dltdata->part_num;
291 : }
292 :
293 : char filename[PATH_MAX + 1];
294 0 : filename[PATH_MAX] = 0;
295 :
296 0 : snprintf(filename, PATH_MAX, "%s.%i.dlt", dltdata->ovaluebase, dltdata->part_num);
297 :
298 0 : if (rename(dltdata->ovalue, filename) != 0)
299 0 : dlt_vlog(
300 0 : LOG_ERR, "ERROR: rename %s to %s failed with error %s\n", dltdata->ovalue, filename, strerror(errno));
301 0 : else if (dltdata->vflag) {
302 0 : dlt_vlog(LOG_INFO, "Renaming existing file from %s to %s\n", dltdata->ovalue, filename);
303 0 : ++dltdata->part_num;
304 : }
305 : } /* if (file_already_exists) */
306 :
307 0 : globfree(&outer);
308 :
309 0 : dltdata->ohandle = open(dltdata->ovalue, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
310 0 : return dltdata->ohandle;
311 : }
312 :
313 :
314 0 : void dlt_receive_close_output_file(DltReceiveData* dltdata)
315 : {
316 0 : if (dltdata->ohandle) {
317 0 : close(dltdata->ohandle);
318 0 : dltdata->ohandle = -1;
319 : }
320 0 : }
321 :
322 :
323 : /**
324 : * Main function of tool.
325 : */
326 1 : int main(int argc, char* argv[])
327 : {
328 : DltReceiveData dltdata;
329 : memset(&dltdata, 0, sizeof(dltdata));
330 : int c;
331 : int index;
332 :
333 : /* Initialize dltdata */
334 1 : dltdata.climit = -1; /* default: -1 = unlimited */
335 1 : dltdata.ohandle = -1;
336 1 : dltdata.part_num = -1;
337 1 : dltdata.port = 3490;
338 :
339 : /* Config signal handler */
340 : struct sigaction act;
341 :
342 : /* Initialize signal handler struct */
343 : memset(&act, 0, sizeof(act));
344 1 : act.sa_handler = signal_handler;
345 1 : sigemptyset(&act.sa_mask);
346 1 : sigaction(SIGHUP, &act, 0);
347 1 : sigaction(SIGTERM, &act, 0);
348 1 : sigaction(SIGINT, &act, 0);
349 1 : sigaction(SIGQUIT, &act, 0);
350 :
351 : /* Fetch command line arguments */
352 1 : opterr = 0;
353 :
354 2 : while ((c = getopt(argc, argv, "vashSRyuxmf:j:o:e:b:c:p:i:r:")) != -1)
355 1 : switch (c) {
356 0 : case 'v': {
357 0 : dltdata.vflag = 1;
358 0 : break;
359 : }
360 0 : case 'a': {
361 0 : dltdata.aflag = 1;
362 0 : break;
363 : }
364 0 : case 's': {
365 0 : dltdata.sflag = 1;
366 0 : break;
367 : }
368 0 : case 'x': {
369 0 : dltdata.xflag = 1;
370 0 : break;
371 : }
372 0 : case 'm': {
373 0 : dltdata.mflag = 1;
374 0 : break;
375 : }
376 0 : case 'h': {
377 0 : usage();
378 0 : return -1;
379 : }
380 0 : case 'S': {
381 0 : dltdata.sendSerialHeaderFlag = 1;
382 0 : break;
383 : }
384 0 : case 'R': {
385 0 : dltdata.resyncSerialHeaderFlag = 1;
386 0 : break;
387 : }
388 0 : case 'y': {
389 0 : dltdata.yflag = 1;
390 0 : break;
391 : }
392 0 : case 'u': {
393 0 : dltdata.uflag = 1;
394 0 : break;
395 : }
396 0 : case 'i': {
397 0 : dltdata.ifaddr = optarg;
398 0 : break;
399 : }
400 0 : case 'f': {
401 0 : dltdata.fvalue = optarg;
402 0 : break;
403 : }
404 0 : case 'j': {
405 : #ifdef EXTENDED_FILTERING
406 : dltdata.jvalue = optarg;
407 : break;
408 : #else
409 0 : fprintf(
410 : stderr,
411 : "Extended filtering is not supported. Please build with the corresponding cmake option to use it.\n");
412 0 : return -1;
413 : #endif
414 : }
415 0 : case 'r': {
416 0 : dltdata.rflag = 1;
417 0 : dltdata.rvalue = atoi(optarg);
418 0 : break;
419 : }
420 1 : case 'o': {
421 1 : dltdata.ovalue = optarg;
422 1 : size_t to_copy = strlen(dltdata.ovalue);
423 :
424 1 : if (strcmp(&dltdata.ovalue[to_copy - 4], ".dlt") == 0)
425 : to_copy = to_copy - 4;
426 :
427 1 : dltdata.ovaluebase = (char*)calloc(1, to_copy + 1);
428 :
429 1 : if (dltdata.ovaluebase == NULL) {
430 0 : fprintf(stderr, "Memory allocation failed.\n");
431 0 : return -1;
432 : }
433 :
434 1 : dltdata.ovaluebase[to_copy] = '\0';
435 1 : memcpy(dltdata.ovaluebase, dltdata.ovalue, to_copy);
436 : break;
437 : }
438 0 : case 'e': {
439 0 : dltdata.evalue = optarg;
440 0 : break;
441 : }
442 0 : case 'b': {
443 0 : dltdata.bvalue = atoi(optarg);
444 0 : break;
445 : }
446 0 : case 'p': {
447 0 : dltdata.port = atoi(optarg);
448 0 : break;
449 : }
450 :
451 0 : case 'c': {
452 0 : dltdata.climit = convert_arg_to_byte_size(optarg);
453 :
454 0 : if (dltdata.climit < -1) {
455 0 : fprintf(stderr, "Invalid argument for option -c.\n");
456 : /* unknown or wrong option used, show usage information and terminate */
457 0 : usage();
458 0 : return -1;
459 : }
460 :
461 : break;
462 : }
463 0 : case '?': {
464 0 : if ((optopt == 'o') || (optopt == 'f') || (optopt == 'c'))
465 0 : fprintf(stderr, "Option -%c requires an argument.\n", optopt);
466 0 : else if (isprint(optopt))
467 0 : fprintf(stderr, "Unknown option `-%c'.\n", optopt);
468 : else
469 0 : fprintf(stderr, "Unknown option character `\\x%x'.\n", optopt);
470 :
471 : /* unknown or wrong option used, show usage information and terminate */
472 0 : usage();
473 0 : return -1;
474 : }
475 0 : default: {
476 0 : abort();
477 : return -1; /*for parasoft */
478 : }
479 : }
480 :
481 : /* Initialize DLT Client */
482 1 : dlt_client_init(&dltclient, dltdata.vflag);
483 :
484 : /* Register callback to be called when message was received */
485 1 : dlt_client_register_message_callback(dlt_receive_message_callback);
486 :
487 : /* Setup DLT Client structure */
488 1 : if (dltdata.uflag) {
489 0 : dltclient.mode = DLT_CLIENT_MODE_UDP_MULTICAST;
490 : } else {
491 1 : dltclient.mode = dltdata.yflag;
492 : }
493 :
494 1 : if (dltclient.mode == DLT_CLIENT_MODE_TCP || dltclient.mode == DLT_CLIENT_MODE_UDP_MULTICAST) {
495 1 : dltclient.port = (uint16_t)dltdata.port;
496 :
497 : unsigned int servIPLength = 1; // Counting the terminating 0 byte
498 2 : for (index = optind; index < argc; index++) {
499 1 : servIPLength += (unsigned int)strlen(argv[index]);
500 1 : if (index > optind) {
501 0 : servIPLength++; // For the comma delimiter
502 : }
503 : }
504 1 : if (servIPLength > 1) {
505 1 : char* servIPString = malloc(servIPLength);
506 1 : strcpy(servIPString, argv[optind]);
507 :
508 1 : for (index = optind + 1; index < argc; index++) {
509 : strcat(servIPString, ",");
510 0 : strcat(servIPString, argv[index]);
511 : }
512 :
513 1 : int retval = dlt_client_set_server_ip(&dltclient, servIPString);
514 1 : free(servIPString);
515 :
516 1 : if (retval == -1) {
517 0 : fprintf(stderr, "set server ip didn't succeed\n");
518 0 : return -1;
519 : }
520 : }
521 :
522 1 : if (dltclient.servIP == 0) {
523 : /* no hostname selected, show usage and terminate */
524 0 : fprintf(stderr, "ERROR: No hostname selected\n");
525 0 : usage();
526 0 : dlt_client_cleanup(&dltclient, dltdata.vflag);
527 0 : return -1;
528 : }
529 :
530 1 : if (dltdata.ifaddr != 0) {
531 0 : if (dlt_client_set_host_if_address(&dltclient, dltdata.ifaddr) != DLT_RETURN_OK) {
532 0 : fprintf(stderr, "set host interface address didn't succeed\n");
533 0 : return -1;
534 : }
535 : }
536 : } else {
537 0 : for (index = optind; index < argc; index++)
538 0 : if (dlt_client_set_serial_device(&dltclient, argv[index]) == -1) {
539 0 : fprintf(stderr, "set serial device didn't succeed\n");
540 0 : return -1;
541 : }
542 :
543 0 : if (dltclient.serialDevice == 0) {
544 : /* no serial device name selected, show usage and terminate */
545 0 : fprintf(stderr, "ERROR: No serial device name specified\n");
546 0 : usage();
547 0 : return -1;
548 : }
549 :
550 0 : dlt_client_setbaudrate(&dltclient, dltdata.bvalue);
551 : }
552 :
553 : /* Update the send and resync serial header flags based on command line option */
554 1 : dltclient.send_serial_header = dltdata.sendSerialHeaderFlag;
555 1 : dltclient.resync_serial_header = dltdata.resyncSerialHeaderFlag;
556 :
557 : /* initialise structure to use DLT file */
558 1 : dlt_file_init(&(dltdata.file), dltdata.vflag);
559 :
560 : /* first parse filter file if filter parameter is used */
561 1 : dlt_filter_init(&(dltdata.filter), dltdata.vflag);
562 :
563 1 : if (dltdata.fvalue) {
564 0 : if (dlt_filter_load(&(dltdata.filter), dltdata.fvalue, dltdata.vflag) < DLT_RETURN_OK) {
565 0 : dlt_file_free(&(dltdata.file), dltdata.vflag);
566 0 : return -1;
567 : }
568 :
569 0 : dlt_file_set_filter(&(dltdata.file), &(dltdata.filter), dltdata.vflag);
570 : }
571 :
572 : #ifdef EXTENDED_FILTERING
573 :
574 : if (dltdata.jvalue) {
575 : if (dlt_json_filter_load(&(dltdata.filter), dltdata.jvalue, dltdata.vflag) < DLT_RETURN_OK) {
576 : dlt_file_free(&(dltdata.file), dltdata.vflag);
577 : return -1;
578 : }
579 :
580 : dlt_file_set_filter(&(dltdata.file), &(dltdata.filter), dltdata.vflag);
581 : }
582 :
583 : #endif
584 :
585 : /* open DLT output file */
586 1 : if (dltdata.ovalue) {
587 1 : if (dltdata.climit > -1) {
588 0 : dlt_vlog(LOG_INFO, "Using file size limit of %" PRId64 "bytes\n", dltdata.climit);
589 0 : dltdata.ohandle = dlt_receive_open_output_file(&dltdata);
590 : } else { /* in case no limit for the output file is given, we simply overwrite any existing file */
591 1 : dltdata.ohandle = open(dltdata.ovalue, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
592 : }
593 :
594 1 : if (dltdata.ohandle == -1) {
595 0 : dlt_file_free(&(dltdata.file), dltdata.vflag);
596 0 : fprintf(stderr, "ERROR: Output file %s cannot be opened!\n", dltdata.ovalue);
597 0 : return -1;
598 : }
599 : }
600 :
601 1 : if (dltdata.evalue)
602 0 : dlt_set_id(dltdata.ecuid, dltdata.evalue);
603 : else {
604 1 : dlt_set_id(dltdata.ecuid, DLT_RECEIVE_ECU_ID);
605 : }
606 :
607 : while (true) {
608 : /* Attempt to connect to TCP socket or open serial device */
609 1 : if (dlt_client_connect(&dltclient, dltdata.vflag) != DLT_RETURN_ERROR) {
610 : /* Dlt Client Main Loop */
611 1 : dlt_client_main_loop(&dltclient, &dltdata, dltdata.vflag);
612 :
613 1 : if (dltdata.rflag == 1 && sig_close_recv == false) {
614 0 : dlt_vlog(LOG_INFO, "Reconnect to server with %d milli seconds specified\n", dltdata.rvalue);
615 0 : sleep((unsigned int)(dltdata.rvalue / 1000));
616 : } else {
617 : /* Dlt Client Cleanup */
618 1 : dlt_client_cleanup(&dltclient, dltdata.vflag);
619 1 : break;
620 : }
621 : } else {
622 : break;
623 : }
624 : }
625 :
626 : /* dlt-receive cleanup */
627 1 : if (dltdata.ovalue)
628 1 : close(dltdata.ohandle);
629 :
630 1 : free(dltdata.ovaluebase);
631 :
632 1 : dlt_file_free(&(dltdata.file), dltdata.vflag);
633 :
634 1 : dlt_filter_free(&(dltdata.filter), dltdata.vflag);
635 :
636 1 : return 0;
637 : }
638 :
639 185 : int dlt_receive_message_callback(DltMessage* message, void* data)
640 : {
641 : DltReceiveData* dltdata;
642 : static char text[DLT_RECEIVE_BUFSIZE];
643 :
644 : struct iovec iov[2];
645 : int bytes_written;
646 :
647 185 : if ((message == 0) || (data == 0))
648 : return -1;
649 :
650 : dltdata = (DltReceiveData*)data;
651 :
652 : /* prepare storage header */
653 185 : if (DLT_IS_HTYP_WEID(message->standardheader->htyp))
654 185 : dlt_set_storageheader(message->storageheader, message->headerextra.ecu);
655 : else
656 0 : dlt_set_storageheader(message->storageheader, dltdata->ecuid);
657 :
658 185 : if (((dltdata->fvalue || dltdata->jvalue) == 0)
659 0 : || (dlt_message_filter_check(message, &(dltdata->filter), dltdata->vflag) == DLT_RETURN_TRUE)) {
660 : /* if no filter set or filter is matching display message */
661 185 : if (dltdata->xflag) {
662 0 : dlt_message_print_hex(message, text, DLT_RECEIVE_BUFSIZE, dltdata->vflag);
663 185 : } else if (dltdata->aflag) {
664 0 : dlt_message_header(message, text, DLT_RECEIVE_BUFSIZE, dltdata->vflag);
665 :
666 : printf("%s ", text);
667 :
668 0 : dlt_message_payload(message, text, DLT_RECEIVE_BUFSIZE, DLT_OUTPUT_ASCII, dltdata->vflag);
669 :
670 : printf("[%s]\n", text);
671 185 : } else if (dltdata->mflag) {
672 0 : dlt_message_print_mixed_plain(message, text, DLT_RECEIVE_BUFSIZE, dltdata->vflag);
673 185 : } else if (dltdata->sflag) {
674 0 : dlt_message_header(message, text, DLT_RECEIVE_BUFSIZE, dltdata->vflag);
675 :
676 : printf("%s \n", text);
677 : }
678 :
679 : /* if file output enabled write message */
680 185 : if (dltdata->ovalue) {
681 185 : iov[0].iov_base = message->headerbuffer;
682 185 : iov[0].iov_len = (uint32_t)message->headersize;
683 185 : iov[1].iov_base = message->databuffer;
684 185 : iov[1].iov_len = (uint32_t)message->datasize;
685 :
686 185 : if (dltdata->climit > -1) {
687 0 : uint32_t bytes_to_write = (uint32_t)message->headersize + (uint32_t)message->datasize;
688 :
689 0 : if ((bytes_to_write + dltdata->totalbytes > dltdata->climit)) {
690 : dlt_receive_close_output_file(dltdata);
691 :
692 0 : if (dlt_receive_open_output_file(dltdata) < 0) {
693 : printf(
694 : "ERROR: dlt_receive_message_callback: Unable to open log when maximum filesize was "
695 : "reached!\n");
696 0 : return -1;
697 : }
698 :
699 0 : dltdata->totalbytes = 0;
700 : }
701 : }
702 :
703 185 : bytes_written = (int)writev(dltdata->ohandle, iov, 2);
704 :
705 185 : dltdata->totalbytes += bytes_written;
706 :
707 185 : if (0 > bytes_written) {
708 : printf("dlt_receive_message_callback: writev(dltdata->ohandle, iov, 2); returned an error!");
709 0 : return -1;
710 : }
711 : }
712 : }
713 :
714 : return 0;
715 : }
|