LCOV - code coverage report
Current view: top level - console - dlt-convert.c (source / functions) Coverage Total Hit
Test: dlt_final_coverage.info Lines: 21.7 % 184 40
Test Date: 2025-03-25 20:53:42 Functions: 33.3 % 3 1

            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-convert.c
      23              :  */
      24              : 
      25              : /*******************************************************************************
      26              : **                                                                            **
      27              : **  SRC-MODULE: dlt-convert.c                                                 **
      28              : **                                                                            **
      29              : **  TARGET    : linux                                                         **
      30              : **                                                                            **
      31              : **  PROJECT   : DLT                                                           **
      32              : **                                                                            **
      33              : **  AUTHOR    : Alexander Wenzel Alexander.AW.Wenzel@bmw.de                   **
      34              : **              Markus Klein                                                  **
      35              : **                                                                            **
      36              : **  PURPOSE   :                                                               **
      37              : **                                                                            **
      38              : **  REMARKS   :                                                               **
      39              : **                                                                            **
      40              : **  PLATFORM DEPENDANT [yes/no]: yes                                          **
      41              : **                                                                            **
      42              : **  TO BE CHANGED BY USER [yes/no]: no                                        **
      43              : **                                                                            **
      44              : *******************************************************************************/
      45              : 
      46              : /*******************************************************************************
      47              : **                      Author Identity                                       **
      48              : ********************************************************************************
      49              : **                                                                            **
      50              : ** Initials     Name                       Company                            **
      51              : ** --------     -------------------------  ---------------------------------- **
      52              : **  aw          Alexander Wenzel           BMW                                **
      53              : **  mk          Markus Klein               Fraunhofer ESK                     **
      54              : *******************************************************************************/
      55              : 
      56              : /*******************************************************************************
      57              : **                      Author Identity                                       **
      58              : ********************************************************************************
      59              : **                                                                            **
      60              : ** Initials     Name                       Company                            **
      61              : ** --------     -------------------------  ---------------------------------- **
      62              : **  aw          Alexander Wenzel           BMW                                **
      63              : *******************************************************************************/
      64              : 
      65              : /*******************************************************************************
      66              : **                      Revision Control History                              **
      67              : *******************************************************************************/
      68              : 
      69              : /*
      70              :  * $LastChangedRevision: 1670 $
      71              :  * $LastChangedDate: 2011-04-08 15:12:06 +0200 (Fr, 08. Apr 2011) $
      72              :  * $LastChangedBy$
      73              :  * Initials    Date         Comment
      74              :  * aw          13.01.2010   initial
      75              :  */
      76              : 
      77              : #include <dirent.h>
      78              : #include <stdio.h>
      79              : #include <stdlib.h>
      80              : #include <unistd.h>
      81              : #include <string.h>
      82              : #include <ctype.h>
      83              : #include <errno.h>
      84              : 
      85              : #include <sys/stat.h>
      86              : #include <fcntl.h>
      87              : 
      88              : #include <sys/uio.h> /* writev() */
      89              : 
      90              : #include "dlt_common.h"
      91              : 
      92              : #define COMMAND_SIZE        1024    /* Size of command */
      93              : #define FILENAME_SIZE       1024    /* Size of filename */
      94              : #define DLT_EXTENSION       "dlt"
      95              : #define DLT_CONVERT_WS      "/tmp/dlt_convert_workspace/"
      96              : 
      97              : /**
      98              :  * Print usage information of tool.
      99              :  */
     100            0 : void usage()
     101              : {
     102              :     char version[DLT_CONVERT_TEXTBUFSIZE];
     103              : 
     104            0 :     dlt_get_version(version, 255);
     105              : 
     106              :     printf("Usage: dlt-convert [options] [commands] file1 [file2]\n");
     107              :     printf("Read DLT files, print DLT messages as ASCII and store the messages again.\n");
     108              :     printf("Use filters to filter DLT messages.\n");
     109              :     printf("Use Ranges and Output file to cut DLT files.\n");
     110              :     printf("Use two files and Output file to join DLT files.\n");
     111              :     printf("%s \n", version);
     112              :     printf("Commands:\n");
     113              :     printf("  -h            Usage\n");
     114              :     printf("  -a            Print DLT file; payload as ASCII\n");
     115              :     printf("  -x            Print DLT file; payload as hex\n");
     116              :     printf("  -m            Print DLT file; payload as hex and ASCII\n");
     117              :     printf("  -s            Print DLT file; only headers\n");
     118              :     printf("  -o filename   Output messages in new DLT file\n");
     119              :     printf("Options:\n");
     120              :     printf("  -v            Verbose mode\n");
     121              :     printf("  -c            Count number of messages\n");
     122              :     printf("  -f filename   Enable filtering of messages\n");
     123              :     printf("  -b number     First <number> messages to be handled\n");
     124              :     printf("  -e number     Last <number> messages to be handled\n");
     125              :     printf("  -w            Follow dlt file while file is increasing\n");
     126              :     printf("  -t            Handling input compressed files (tar.gz)\n");
     127            0 : }
     128              : 
     129            0 : void empty_dir(const char *dir)
     130              : {
     131            0 :     struct dirent **files = { 0 };
     132              :     struct stat st;
     133              :     uint32_t n = 0;
     134            0 :     char tmp_filename[FILENAME_SIZE] = { 0 };
     135              :     uint32_t i;
     136              : 
     137            0 :     if (dir == NULL) {
     138            0 :         fprintf(stderr, "ERROR: %s: invalid arguments\n", __FUNCTION__);
     139            0 :         return;
     140              :     }
     141              : 
     142            0 :     if (stat(dir, &st) == 0) {
     143            0 :         if (S_ISDIR(st.st_mode)) {
     144            0 :             n = (uint32_t) scandir(dir, &files, NULL, alphasort);
     145              : 
     146              :             /* Do not include /. and /.. */
     147            0 :             if (n < 2)
     148            0 :                 fprintf(stderr, "ERROR: Failed to scan %s with error %s\n",
     149            0 :                         dir, strerror(errno));
     150            0 :             else if (n == 2)
     151              :                 printf("%s is already empty\n", dir);
     152              :             else {
     153            0 :                 for (i = 2; i < n; i++) {
     154              :                     memset(tmp_filename, 0, FILENAME_SIZE);
     155            0 :                     snprintf(tmp_filename, FILENAME_SIZE, "%s%s", dir, files[i]->d_name);
     156              : 
     157            0 :                     if (remove(tmp_filename) != 0)
     158            0 :                         fprintf(stderr, "ERROR: Failed to delete %s with error %s\n",
     159            0 :                                 tmp_filename, strerror(errno));
     160              :                 }
     161            0 :                 if (files) {
     162            0 :                     for (i = 0; i < n ; i++)
     163            0 :                         if (files[i]) {
     164            0 :                             free(files[i]);
     165            0 :                             files[i] = NULL;
     166              :                         }
     167            0 :                     free(files);
     168              :                     files = NULL;
     169              :                 }
     170              :             }
     171              :         }
     172              :         else
     173            0 :             fprintf(stderr, "ERROR: %s is not a directory\n", dir);
     174              :     }
     175              :     else
     176            0 :         fprintf(stderr, "ERROR: Failed to stat %s with error %s\n", dir, strerror(errno));
     177              : }
     178              : 
     179              : /**
     180              :  * Main function of tool.
     181              :  */
     182           18 : int main(int argc, char *argv[])
     183              : {
     184              :     int vflag = 0;
     185              :     int cflag = 0;
     186              :     int aflag = 0;
     187              :     int sflag = 0;
     188              :     int xflag = 0;
     189              :     int mflag = 0;
     190              :     int wflag = 0;
     191              :     int tflag = 0;
     192              :     char *fvalue = 0;
     193              :     char *bvalue = 0;
     194              :     char *evalue = 0;
     195              :     char *ovalue = 0;
     196              : 
     197              :     int index;
     198              :     int c;
     199              : 
     200              :     DltFile file;
     201              :     DltFilter filter;
     202              : 
     203              :     int ohandle = -1;
     204              : 
     205              :     int num, begin, end;
     206              : 
     207           18 :     char text[DLT_CONVERT_TEXTBUFSIZE] = { 0 };
     208              : 
     209              :     /* For handling compressed files */
     210           18 :     char tmp_filename[FILENAME_SIZE] = { 0 };
     211              :     struct stat st;
     212              :     memset(&st, 0, sizeof(struct stat));
     213           18 :     struct dirent **files = { 0 };
     214              :     int n = 0;
     215              :     int i = 0;
     216              : 
     217              :     struct iovec iov[2];
     218              :     int bytes_written = 0;
     219              :     int syserr = 0;
     220              : 
     221           18 :     opterr = 0;
     222              : 
     223           36 :     while ((c = getopt (argc, argv, "vcashxmwtf:b:e:o:")) != -1) {
     224           18 :         switch (c)
     225              :         {
     226              :         case 'v':
     227              :         {
     228              :             vflag = 1;
     229              :             break;
     230              :         }
     231            0 :         case 'c':
     232              :         {
     233              :             cflag = 1;
     234            0 :             break;
     235              :         }
     236           18 :         case 'a':
     237              :         {
     238              :             aflag = 1;
     239           18 :             break;
     240              :         }
     241            0 :         case 's':
     242              :         {
     243              :             sflag = 1;
     244            0 :             break;
     245              :         }
     246            0 :         case 'x':
     247              :         {
     248              :             xflag = 1;
     249            0 :             break;
     250              :         }
     251            0 :         case 'm':
     252              :         {
     253              :             mflag = 1;
     254            0 :             break;
     255              :         }
     256            0 :         case 'w':
     257              :         {
     258              :             wflag = 1;
     259            0 :             break;
     260              :         }
     261            0 :         case 't':
     262              :         {
     263              :             tflag = 1;
     264            0 :             break;
     265              :         }
     266            0 :         case 'h':
     267              :         {
     268            0 :             usage();
     269            0 :             return -1;
     270              :         }
     271            0 :         case 'f':
     272              :         {
     273            0 :             fvalue = optarg;
     274            0 :             break;
     275              :         }
     276            0 :         case 'b':
     277              :         {
     278            0 :             bvalue = optarg;
     279            0 :             break;
     280              :         }
     281            0 :         case 'e':
     282              :         {
     283            0 :             evalue = optarg;
     284            0 :             break;
     285              :         }
     286            0 :         case 'o':
     287              :         {
     288            0 :             ovalue = optarg;
     289            0 :             break;
     290              :         }
     291            0 :         case '?':
     292              :         {
     293            0 :             if ((optopt == 'f') || (optopt == 'b') || (optopt == 'e') || (optopt == 'o'))
     294            0 :                 fprintf (stderr, "Option -%c requires an argument.\n", optopt);
     295            0 :             else if (isprint (optopt))
     296            0 :                 fprintf (stderr, "Unknown option `-%c'.\n", optopt);
     297              :             else
     298            0 :                 fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt);
     299              : 
     300              :             /* unknown or wrong option used, show usage information and terminate */
     301            0 :             usage();
     302            0 :             return -1;
     303              :         }
     304              :         default:
     305              :         {
     306              :             return -1;    /*for parasoft */
     307              :         }
     308              :         }
     309              :     }
     310              : 
     311              :     /* Initialize structure to use DLT file */
     312           18 :     dlt_file_init(&file, vflag);
     313              : 
     314              :     /* first parse filter file if filter parameter is used */
     315           18 :     if (fvalue) {
     316            0 :         if (dlt_filter_load(&filter, fvalue, vflag) < DLT_RETURN_OK) {
     317            0 :             dlt_file_free(&file, vflag);
     318            0 :             return -1;
     319              :         }
     320              : 
     321            0 :         dlt_file_set_filter(&file, &filter, vflag);
     322              :     }
     323              : 
     324           18 :     if (ovalue) {
     325              :         ohandle = open(ovalue, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); /* mode: wb */
     326              : 
     327            0 :         if (ohandle == -1) {
     328            0 :             dlt_file_free(&file, vflag);
     329            0 :             fprintf(stderr, "ERROR: Output file %s cannot be opened!\n", ovalue);
     330            0 :             return -1;
     331              :         }
     332              :     }
     333              : 
     334           18 :     if (tflag) {
     335              :         /* Prepare the temp dir to untar compressed files */
     336            0 :         if (stat(DLT_CONVERT_WS, &st) == -1) {
     337            0 :             if (mkdir(DLT_CONVERT_WS, 0700) != 0) {
     338            0 :                 fprintf(stderr,"ERROR: Cannot create temp dir %s!\n", DLT_CONVERT_WS);
     339            0 :                 if (ovalue)
     340            0 :                     close(ohandle);
     341              : 
     342            0 :                 return -1;
     343              :             }
     344              :         }
     345              :         else {
     346            0 :             if (S_ISDIR(st.st_mode))
     347            0 :                 empty_dir(DLT_CONVERT_WS);
     348              :             else
     349            0 :                 fprintf(stderr, "ERROR: %s is not a directory", DLT_CONVERT_WS);
     350              :         }
     351              : 
     352            0 :         for (index = optind; index < argc; index++) {
     353              :             /* Check extension of input file
     354              :              * If it is a compressed file, uncompress it
     355              :              */
     356            0 :             if (strcmp(get_filename_ext(argv[index]), DLT_EXTENSION) != 0) {
     357            0 :                 syserr = dlt_execute_command(NULL, "tar", "xf", argv[index], "-C", DLT_CONVERT_WS, NULL);
     358            0 :                 if (syserr != 0)
     359            0 :                     fprintf(stderr, "ERROR: Failed to uncompress %s to %s with error [%d]\n",
     360            0 :                             argv[index], DLT_CONVERT_WS, WIFEXITED(syserr));
     361              :             }
     362              :             else {
     363            0 :                 syserr = dlt_execute_command(NULL, "cp", argv[index], DLT_CONVERT_WS, NULL);
     364            0 :                 if (syserr != 0)
     365            0 :                     fprintf(stderr, "ERROR: Failed to copy %s to %s with error [%d]\n",
     366            0 :                             argv[index], DLT_CONVERT_WS, WIFEXITED(syserr));
     367              :             }
     368              : 
     369              :         }
     370              : 
     371            0 :         n = scandir(DLT_CONVERT_WS, &files, NULL, alphasort);
     372            0 :         if (n == -1) {
     373            0 :             fprintf(stderr,"ERROR: Cannot scan temp dir %s!\n", DLT_CONVERT_WS);
     374            0 :             if (ovalue)
     375            0 :                 close(ohandle);
     376              : 
     377            0 :             return -1;
     378              :         }
     379              : 
     380              :         /* do not include ./ and ../ in the files */
     381            0 :         argc = optind + (n - 2);
     382              :     }
     383              : 
     384           35 :     for (index = optind; index < argc; index++) {
     385           18 :         if (tflag) {
     386              :             memset(tmp_filename, 0, FILENAME_SIZE);
     387              :             snprintf(tmp_filename, FILENAME_SIZE, "%s%s",
     388            0 :                     DLT_CONVERT_WS, files[index - optind + 2]->d_name);
     389              : 
     390            0 :             argv[index] = tmp_filename;
     391              :         }
     392              : 
     393              :         /* load, analyze data file and create index list */
     394           18 :         if (dlt_file_open(&file, argv[index], vflag) >= DLT_RETURN_OK) {
     395          526 :             while (dlt_file_read(&file, vflag) >= DLT_RETURN_OK) {
     396              :             }
     397              :         }
     398              : 
     399           18 :         if (aflag || sflag || xflag || mflag || ovalue) {
     400           18 :             if (bvalue)
     401              :                 begin = atoi(bvalue);
     402              :             else
     403              :                 begin = 0;
     404              : 
     405           18 :             if (evalue && (wflag == 0))
     406              :                 end = atoi(evalue);
     407              :             else
     408           18 :                 end = file.counter - 1;
     409              : 
     410           18 :             if ((begin < 0) || (begin >= file.counter)) {
     411            1 :                 fprintf(stderr, "ERROR: Selected first message %d is out of range!\n", begin);
     412            1 :                 if (ovalue)
     413            0 :                     close(ohandle);
     414              : 
     415            1 :                 return -1;
     416              :             }
     417              : 
     418           17 :             if ((end < 0) || (end >= file.counter) || (end < begin)) {
     419            0 :                 fprintf(stderr, "ERROR: Selected end message %d is out of range!\n", end);
     420            0 :                 if (ovalue)
     421            0 :                     close(ohandle);
     422              : 
     423            0 :                 return -1;
     424              :             }
     425              : 
     426          526 :             for (num = begin; num <= end; num++) {
     427          509 :                 if (dlt_file_message(&file, num, vflag) < DLT_RETURN_OK)
     428            0 :                     continue;
     429              : 
     430          509 :                 if (xflag) {
     431              :                     printf("%d ", num);
     432            0 :                     if (dlt_message_print_hex(&(file.msg), text, DLT_CONVERT_TEXTBUFSIZE, vflag) < DLT_RETURN_OK)
     433            0 :                         continue;
     434              :                 }
     435          509 :                 else if (aflag) {
     436              :                     printf("%d ", num);
     437              : 
     438          509 :                     if (dlt_message_header(&(file.msg), text, DLT_CONVERT_TEXTBUFSIZE, vflag) < DLT_RETURN_OK)
     439            0 :                         continue;
     440              : 
     441              :                     printf("%s ", text);
     442              : 
     443          509 :                     if (dlt_message_payload(&file.msg, text, DLT_CONVERT_TEXTBUFSIZE, DLT_OUTPUT_ASCII, vflag) < DLT_RETURN_OK)
     444            0 :                         continue;
     445              : 
     446              :                     printf("[%s]\n", text);
     447              :                 }
     448            0 :                 else if (mflag) {
     449              :                     printf("%d ", num);
     450            0 :                     if (dlt_message_print_mixed_plain(&(file.msg), text, DLT_CONVERT_TEXTBUFSIZE, vflag) < DLT_RETURN_OK)
     451            0 :                         continue;
     452              :                 }
     453            0 :                 else if (sflag) {
     454              :                     printf("%d ", num);
     455              : 
     456            0 :                     if (dlt_message_header(&(file.msg), text, DLT_CONVERT_TEXTBUFSIZE, vflag) < DLT_RETURN_OK)
     457            0 :                         continue;
     458              : 
     459              :                     printf("%s \n", text);
     460              :                 }
     461              : 
     462              :                 /* if file output enabled write message */
     463          509 :                 if (ovalue) {
     464            0 :                     iov[0].iov_base = file.msg.headerbuffer;
     465            0 :                     iov[0].iov_len = (uint32_t) file.msg.headersize;
     466            0 :                     iov[1].iov_base = file.msg.databuffer;
     467            0 :                     iov[1].iov_len = (uint32_t) file.msg.datasize;
     468              : 
     469            0 :                     bytes_written =(int) writev(ohandle, iov, 2);
     470              : 
     471            0 :                     if (0 > bytes_written) {
     472              :                         printf("in main: writev(ohandle, iov, 2); returned an error!");
     473            0 :                         close(ohandle);
     474            0 :                         dlt_file_free(&file, vflag);
     475            0 :                         return -1;
     476              :                     }
     477              :                 }
     478              : 
     479              :                 /* check for new messages if follow flag set */
     480          509 :                 if (wflag && (num == end)) {
     481              :                     while (1) {
     482            0 :                         while (dlt_file_read(&file, 0) >= 0){
     483              :                         }
     484              : 
     485            0 :                         if (end == (file.counter - 1)) {
     486              :                             /* Sleep if no new message was received */
     487              :                             struct timespec req;
     488            0 :                             req.tv_sec = 0;
     489            0 :                             req.tv_nsec = 100000000;
     490            0 :                             nanosleep(&req, NULL);
     491              :                         }
     492              :                         else {
     493              :                             /* set new end of log file and continue reading */
     494              :                             end = file.counter - 1;
     495              :                             break;
     496              :                         }
     497              :                     }
     498              :                 }
     499              :             }
     500              :         }
     501              : 
     502           17 :         if (cflag) {
     503            0 :             printf("Total number of messages: %d\n", file.counter_total);
     504              : 
     505            0 :             if (file.filter)
     506            0 :                 printf("Filtered number of messages: %d\n", file.counter);
     507              :         }
     508              :     }
     509              : 
     510           17 :     if (ovalue)
     511            0 :         close(ohandle);
     512              : 
     513           17 :     if (tflag) {
     514            0 :         empty_dir(DLT_CONVERT_WS);
     515            0 :         if (files) {
     516            0 :             for (i = 0; i < n ; i++)
     517            0 :                 if (files[i])
     518            0 :                     free(files[i]);
     519              : 
     520            0 :             free(files);
     521              :         }
     522            0 :         rmdir(DLT_CONVERT_WS);
     523              :     }
     524           17 :     if (index == optind) {
     525              :         /* no file selected, show usage and terminate */
     526            0 :         fprintf(stderr, "ERROR: No file selected\n");
     527            0 :         usage();
     528            0 :         return -1;
     529              :     }
     530              : 
     531           17 :     dlt_file_free(&file, vflag);
     532              : 
     533           17 :     return 0;
     534              : }
        

Generated by: LCOV version 2.0-1