LCOV - code coverage report
Current view: top level - console - dlt-receive.c (source / functions) Coverage Total Hit
Test: dlt_final_coverage.info Lines: 32.5 % 246 80
Test Date: 2026-08-27 10:11:10 Functions: 28.6 % 7 2

            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              : }
        

Generated by: LCOV version 2.0-1