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