LCOV - code coverage report
Current view: top level - console - dlt-receive.c (source / functions) Coverage Total Hit
Test: dlt_final_coverage.info Lines: 35.5 % 245 87
Test Date: 2025-03-25 20:53:42 Functions: 42.9 % 7 3

            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 2.0-1