LCOV - code coverage report
Current view: top level - console - dlt-receive.c (source / functions) Hit Total Coverage
Test: dlt_final_coverage.info Lines: 87 245 35.5 %
Date: 2024-10-22 04:07:23 Functions: 3 7 42.9 %

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

Generated by: LCOV version 1.14