LCOV - code coverage report
Current view: top level - console - dlt-convert.c (source / functions) Hit Total Coverage
Test: dlt_final_coverage.info Lines: 40 184 21.7 %
Date: 2024-11-20 10:17:27 Functions: 1 3 33.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-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 1.14