LCOV - code coverage report
Current view: top level - shared - dlt_multiple_files.c (source / functions) Coverage Total Hit
Test: dlt_final_coverage.info Lines: 69.1 % 191 132
Test Date: 2025-12-12 09:13:23 Functions: 100.0 % 13 13

            Line data    Source code
       1              : /*
       2              :  * SPDX license identifier: MPL-2.0
       3              :  *
       4              :  * Copyright (C) 2022, Daimler TSS GmbH
       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 https://www.covesa.global/.
      14              :  */
      15              : 
      16              : /*!
      17              :  * \author
      18              :  * Oleg Tropmann <oleg.tropmann@daimler.com>
      19              :  * Daniel Weber <daniel.w.weber@daimler.com>
      20              :  *
      21              :  * \copyright Copyright © 2022 Daimler TSS GmbH. \n
      22              :  * License MPL-2.0: Mozilla Public License version 2.0 http://mozilla.org/MPL/2.0/.
      23              :  *
      24              :  * \file dlt_daemon_log.c
      25              :  */
      26              : 
      27              : #include <stdio.h>
      28              : #include <stdlib.h>
      29              : #include <string.h>
      30              : #include <time.h>
      31              : #include <sys/types.h>
      32              : #include <sys/stat.h>
      33              : #include <fcntl.h>
      34              : #include <unistd.h>
      35              : #include <dirent.h>
      36              : #include <syslog.h>
      37              : #include <errno.h>
      38              : #include <stdarg.h>
      39              : 
      40              : #include "dlt_multiple_files.h"
      41              : #include "dlt_common.h"
      42              : #include "dlt_log.h"
      43              : 
      44           12 : unsigned int multiple_files_buffer_storage_dir_info(const char *path, const char *file_name,
      45              :                                                     char *newest, char *oldest)
      46              : {
      47              :     int i = 0;
      48              :     unsigned int num_log_files = 0;
      49           12 :     struct dirent **files = { 0 };
      50              :     char *tmp_old = NULL;
      51              :     char *tmp_new = NULL;
      52              : 
      53           12 :     if ((path == NULL) || (file_name == NULL) || (newest == NULL) || (oldest == NULL)) {
      54            0 :         fprintf(stderr, "multiple_files_buffer_storage_dir_info: Invalid parameter(s)");
      55            0 :         return 0;
      56              :     }
      57              : 
      58           12 :     const int file_cnt = scandir(path, &files, NULL, alphasort);
      59           12 :     if (file_cnt <= 0) return 0;
      60              : 
      61          398 :     for (i = 0; i < file_cnt; i++) {
      62              :         int len = 0;
      63          386 :         len = (int)strlen(file_name);
      64              : 
      65          386 :         if ((strncmp(files[i]->d_name, file_name, (size_t)len) == 0) &&
      66          110 :             (files[i]->d_name[len] == MULTIPLE_FILES_FILENAME_INDEX_DELIM[0])) {
      67           48 :             num_log_files++;
      68              : 
      69           48 :             if ((tmp_old == NULL) || (strlen(tmp_old) >= strlen(files[i]->d_name))) {
      70              :                 if (tmp_old == NULL) {
      71              :                     tmp_old = files[i]->d_name;
      72           36 :                 } else if (strlen(tmp_old) > strlen(files[i]->d_name)) {
      73              :                     /* when file name is smaller, it is older */
      74              :                     tmp_old = files[i]->d_name;
      75           20 :                 } else if (strcmp(tmp_old, files[i]->d_name) > 0) {
      76              :                     /* filename length is equal, do a string compare */
      77              :                     tmp_old = files[i]->d_name;
      78              :                 }
      79              :             }
      80              : 
      81           48 :             if ((tmp_new == NULL) || (strlen(tmp_new) <= strlen(files[i]->d_name))) {
      82              :                 if (tmp_new == NULL) {
      83              :                     tmp_new = files[i]->d_name;
      84           20 :                 } else if (strlen(tmp_new) < strlen(files[i]->d_name)) {
      85              :                     /* when file name is longer, it is younger */
      86              :                     tmp_new = files[i]->d_name;
      87           20 :                 } else if (strcmp(tmp_new, files[i]->d_name) < 0) {
      88              :                     tmp_new = files[i]->d_name;
      89              :                 }
      90              :             }
      91              :         }
      92              :     }
      93              : 
      94           12 :     if (num_log_files > 0) {
      95           12 :         if ((tmp_old != NULL) && (strlen(tmp_old) < NAME_MAX)) {
      96              :             strncpy(oldest, tmp_old, NAME_MAX);
      97           12 :             oldest[NAME_MAX] = '\0';
      98              :         } else if ((tmp_old != NULL) && (strlen(tmp_old) >=  NAME_MAX)) {
      99              :             printf("length mismatch of file %s\n", tmp_old);
     100              :         }
     101              : 
     102           12 :         if ((tmp_new != NULL) && (strlen(tmp_new) < NAME_MAX)) {
     103              :             strncpy(newest, tmp_new, NAME_MAX);
     104           12 :             newest[NAME_MAX] = '\0';
     105              :         } else if ((tmp_new != NULL) && (strlen(tmp_new) >=  NAME_MAX)) {
     106              :             printf("length mismatch of file %s\n", tmp_new);
     107              :         }
     108              :     }
     109              : 
     110              :     /* free scandir result */
     111          398 :     for (i = 0; i < file_cnt; i++) free(files[i]);
     112              : 
     113           12 :     free(files);
     114              : 
     115           12 :     return num_log_files;
     116              : }
     117              : 
     118            9 : void multiple_files_buffer_file_name(MultipleFilesRingBuffer *files_buffer, const unsigned int idx)
     119              : {
     120              :     char file_index[11]; /* UINT_MAX = 4294967295 -> 10 digits */
     121              :     snprintf(file_index, sizeof(file_index), "%010u", idx);
     122              : 
     123              :     /* create log file name */
     124            9 :     char* file_name = files_buffer->filename;
     125              :     size_t bufsize = sizeof(files_buffer->filename);
     126              :     memset(file_name, 0, bufsize);
     127              : 
     128              :     int written = snprintf(file_name, bufsize, "%s%s%s%s",
     129            9 :                           files_buffer->filenameBase,
     130              :                           MULTIPLE_FILES_FILENAME_INDEX_DELIM,
     131              :                           file_index,
     132            9 :                           files_buffer->filenameExt);
     133            9 :     if (written < 0 || (size_t)written >= bufsize) {
     134            0 :         file_name[bufsize - 1] = '\0';
     135              :     }
     136            9 : }
     137              : 
     138           53 : unsigned int multiple_files_buffer_get_idx_of_log_file(char *file)
     139              : {
     140           53 :     if ((file == NULL) || (file[0] == '\0')) return 0;
     141              : 
     142           53 :     const char d[2] = MULTIPLE_FILES_FILENAME_INDEX_DELIM;
     143              :     char *token;
     144              : 
     145           53 :     token = strtok(file, d);
     146              :     /* we are interested in 2. token because of log file name */
     147           53 :     token = strtok(NULL, d);
     148              : 
     149           53 :     return token != NULL ? (unsigned int)strtol(token, NULL, 10) : 0;
     150              : }
     151              : 
     152            9 : DltReturnValue multiple_files_buffer_create_new_file(MultipleFilesRingBuffer *files_buffer)
     153              : {
     154            9 :     if (files_buffer == NULL) {
     155            0 :         fprintf(stderr, "multiple files buffer not set\n");
     156            0 :         return DLT_RETURN_ERROR;
     157              :     }
     158              : 
     159              :     time_t t;
     160              :     struct tm tmp;
     161              :     char file_path[PATH_MAX + 1];
     162              :     unsigned int idx = 0;
     163              :     int ret = 0;
     164              : 
     165              :     /* set filename */
     166            9 :     if (files_buffer->filenameTimestampBased) {
     167              :         /* timestamp format: "yyyymmdd_hhmmss" */
     168              :         char timestamp[16];
     169            0 :         t = time(NULL);
     170            0 :         tzset();
     171            0 :         localtime_r(&t, &tmp);
     172              : 
     173            0 :         strftime(timestamp, sizeof(timestamp), "%Y%m%d_%H%M%S", &tmp);
     174              : 
     175            0 :         ret = snprintf(files_buffer->filename, sizeof(files_buffer->filename), "%s%s%s%s",
     176            0 :                        files_buffer->filenameBase,
     177              :                        MULTIPLE_FILES_FILENAME_TIMESTAMP_DELIM, timestamp,
     178            0 :                        files_buffer->filenameExt);
     179              : 
     180            0 :         if ((ret < 0) || ((size_t)ret >= (int)sizeof(files_buffer->filename))) {
     181            0 :             fprintf(stderr, "filename cannot be concatenated\n");
     182            0 :             return DLT_RETURN_ERROR;
     183              :         }
     184              : 
     185              :         ret = snprintf(file_path, sizeof(file_path), "%s/%s",
     186            0 :                        files_buffer->directory, files_buffer->filename);
     187              : 
     188            0 :         if ((ret < 0) || ((size_t)ret >= (int)sizeof(file_path))) {
     189            0 :             fprintf(stderr, "file path cannot be concatenated\n");
     190            0 :             return DLT_RETURN_ERROR;
     191              :         }
     192              :     }
     193              :     else {
     194            9 :         char newest[NAME_MAX + 1] = { 0 };
     195            9 :         char oldest[NAME_MAX + 1] = { 0 };
     196              :         /* targeting newest file, ignoring number of files in dir returned */
     197            9 :         if (0 == multiple_files_buffer_storage_dir_info(files_buffer->directory,
     198            9 :                                                         files_buffer->filenameBase,
     199              :                                                         newest,
     200              :                                                         oldest)) {
     201              :             printf("No multiple files found\n");
     202              :         }
     203              : 
     204            9 :         idx = multiple_files_buffer_get_idx_of_log_file(newest) + 1;
     205              : 
     206            9 :         multiple_files_buffer_file_name(files_buffer, idx);
     207              :         ret = snprintf(file_path, sizeof(file_path), "%s/%s",
     208            9 :                        files_buffer->directory, files_buffer->filename);
     209              : 
     210            9 :         if ((ret < 0) || (ret >= NAME_MAX)) {
     211            0 :             fprintf(stderr, "filename cannot be concatenated\n");
     212            0 :             return DLT_RETURN_ERROR;
     213              :         }
     214              :     }
     215              : 
     216              :     /* open DLT output file */
     217            9 :     errno = 0;
     218            9 :     files_buffer->ohandle = open(file_path, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR |
     219              :                                                                 S_IRGRP | S_IROTH); /* mode: wb */
     220              : 
     221            9 :     if (files_buffer->ohandle == -1) {
     222              :         /* file cannot be opened */
     223            0 :         fprintf(stderr, "file %s cannot be created, error: %s\n", file_path, strerror(errno));
     224            0 :         return DLT_RETURN_ERROR;
     225              :     }
     226              : 
     227              :     return DLT_RETURN_OK;
     228              : }
     229              : 
     230           21 : ssize_t multiple_files_buffer_get_total_size(const MultipleFilesRingBuffer *files_buffer)
     231              : {
     232           21 :     if (files_buffer == NULL) {
     233            0 :         fprintf(stderr, "multiple files buffer not set\n");
     234            0 :         return -1;
     235              :     }
     236              : 
     237              :     struct dirent *dp;
     238              :     char filename[PATH_MAX + 1];
     239              :     ssize_t size = 0;
     240              :     struct stat status;
     241              : 
     242              :     /* go through all dlt files in directory */
     243           21 :     DIR *dir = opendir(files_buffer->directory);
     244           21 :     if (!dir) {
     245            0 :         fprintf(stderr, "directory %s cannot be opened, error=%s\n", files_buffer->directory, strerror(errno));
     246            0 :         return -1;
     247              :     }
     248              : 
     249          716 :     while ((dp = readdir(dir)) != NULL) {
     250              :         // consider files matching with a specific base name and a particular extension
     251          695 :         if (strstr(dp->d_name, files_buffer->filenameBase)  && strstr(dp->d_name, files_buffer->filenameExt)) {
     252              :             int res = snprintf(filename, sizeof(filename), "%s/%s", files_buffer->directory, dp->d_name);
     253              : 
     254              :             /* if the total length of the string is greater than the buffer, silently forget it. */
     255              :             /* snprintf: a return value of size  or more means that the output was truncated */
     256              :             /*           if an output error is encountered, a negative value is returned. */
     257           80 :             if (((unsigned int)res < sizeof(filename)) && (res > 0)) {
     258           80 :                 errno = 0;
     259           80 :                 if (0 == stat(filename, &status))
     260           80 :                     size += status.st_size;
     261              :                 else
     262            0 :                     fprintf(stderr, "file %s cannot be stat-ed, error=%s\n", filename, strerror(errno));
     263              :             }
     264              :         }
     265              :     }
     266              : 
     267           21 :     closedir(dir);
     268              : 
     269              :     /* return size */
     270           21 :     return size;
     271              : }
     272              : 
     273            9 : int multiple_files_buffer_delete_oldest_file(MultipleFilesRingBuffer *files_buffer)
     274              : {
     275            9 :     if (files_buffer == NULL) {
     276            0 :         fprintf(stderr, "multiple files buffer not set\n");
     277            0 :         return -1;  /* ERROR */
     278              :     }
     279              : 
     280              :     struct dirent *dp;
     281              :     char filename[PATH_MAX + 1];
     282              :     char filename_oldest[PATH_MAX + 1];
     283              :     unsigned long size_oldest = 0;
     284              :     struct stat status;
     285              :     time_t time_oldest = 0;
     286              :     int index_oldest = INT_MAX;
     287              : 
     288            9 :     filename[0] = 0;
     289            9 :     filename_oldest[0] = 0;
     290              : 
     291              :     /* go through all dlt files in directory */
     292            9 :     DIR *dir = opendir(files_buffer->directory);
     293              : 
     294            9 :     if(!dir)
     295              :         return -1;
     296              : 
     297          318 :     while ((dp = readdir(dir)) != NULL) {
     298          309 :         if (strstr(dp->d_name, files_buffer->filenameBase) && strstr(dp->d_name, files_buffer->filenameExt)) {
     299              :             int res = snprintf(filename, sizeof(filename), "%s/%s", files_buffer->directory, dp->d_name);
     300              : 
     301              :             /* if the total length of the string is greater than the buffer, silently forget it. */
     302              :             /* snprintf: a return value of size  or more means that the output was truncated */
     303              :             /*           if an output error is encountered, a negative value is returned. */
     304           44 :             if (((unsigned int) res >= sizeof(filename)) || (res <= 0)) {
     305              :                 printf("Filename for delete oldest too long. Skip file.\n");
     306            0 :                 continue;
     307              :             }
     308              : 
     309           44 :             if (files_buffer->filenameTimestampBased) {
     310            0 :                 errno = 0;
     311            0 :                 if (0 == stat(filename, &status)) {
     312            0 :                     if ((time_oldest == 0) || (status.st_mtime < time_oldest)) {
     313            0 :                         time_oldest = status.st_mtime;
     314            0 :                         size_oldest = (unsigned long)status.st_size;
     315              :                         strncpy(filename_oldest, filename, PATH_MAX);
     316            0 :                         filename_oldest[PATH_MAX] = 0;
     317              :                     }
     318              :                 } else {
     319            0 :                     printf("Old file %s cannot be stat-ed, error=%s\n", filename, strerror(errno));
     320              :                 }
     321              :             } else {
     322              :                 //index based
     323           44 :                 const unsigned int index = multiple_files_buffer_get_idx_of_log_file(filename);
     324           44 :                 if (index < (unsigned int)index_oldest) {
     325           23 :                     index_oldest = (int)index;
     326              :                     snprintf(filename, sizeof(filename), "%s/%s", files_buffer->directory, dp->d_name);
     327              :                     strncpy(filename_oldest, filename, PATH_MAX);
     328           23 :                     filename_oldest[PATH_MAX] = 0;
     329              :                 }
     330              :             }
     331              :         }
     332              :     }
     333              : 
     334            9 :     closedir(dir);
     335              : 
     336              :     /* delete file */
     337            9 :     if (filename_oldest[0]) {
     338            9 :         if (remove(filename_oldest)) {
     339            0 :             fprintf(stderr, "Remove file %s failed! error=%s\n", filename_oldest, strerror(errno));
     340            0 :             return -1; /* ERROR */
     341              :         }
     342              :     } else {
     343            0 :         fprintf(stderr, "No file to be removed!\n");
     344            0 :         return -1; /* ERROR */
     345              :     }
     346              : 
     347              :     /* return size of deleted file*/
     348            9 :     return (int)size_oldest;
     349              : }
     350              : 
     351           12 : DltReturnValue multiple_files_buffer_check_size(MultipleFilesRingBuffer *files_buffer)
     352              : {
     353           12 :     if (files_buffer == NULL) {
     354            0 :         fprintf(stderr, "multiple files buffer not set\n");
     355            0 :         return DLT_RETURN_ERROR;
     356              :     }
     357              : 
     358              :     struct stat status;
     359              : 
     360              :     /* check for existence of buffer files directory */
     361           12 :     errno = 0;
     362           12 :     if (stat(files_buffer->directory, &status) == -1) {
     363            0 :         fprintf(stderr, "Buffer files directory: %s doesn't exist, error=%s\n", files_buffer->directory, strerror(errno));
     364            0 :         return DLT_RETURN_ERROR;
     365              :     }
     366              :     /* check for accessibility of buffer files directory */
     367           12 :     else if (access(files_buffer->directory, W_OK) != 0) {
     368            0 :         fprintf(stderr, "Buffer files directory: %s doesn't have the write access \n", files_buffer->directory);
     369            0 :         return DLT_RETURN_ERROR;
     370              :     }
     371              : 
     372              :     ssize_t total_size = 0;
     373              :     /* check size of complete buffer file */
     374           21 :     while ((total_size = multiple_files_buffer_get_total_size(files_buffer)) > (files_buffer->maxSize - files_buffer->fileSize)) {
     375              :         /* remove the oldest files as long as new file will not fit in completely into complete multiple files buffer */
     376            9 :         if (multiple_files_buffer_delete_oldest_file(files_buffer) < 0) return DLT_RETURN_ERROR;
     377              :     }
     378              : 
     379           12 :     return total_size == -1 ? DLT_RETURN_ERROR : DLT_RETURN_OK;
     380              : }
     381              : 
     382            3 : DltReturnValue multiple_files_buffer_open_file_for_append(MultipleFilesRingBuffer *files_buffer) {
     383            3 :     if (files_buffer == NULL || files_buffer->filenameTimestampBased) return DLT_RETURN_ERROR;
     384              : 
     385            3 :     char newest[NAME_MAX + 1] = {0};
     386            3 :     char oldest[NAME_MAX + 1] = {0};
     387              :     /* targeting the newest file, ignoring number of files in dir returned */
     388              : 
     389            3 :     if (0 == multiple_files_buffer_storage_dir_info(files_buffer->directory,
     390            3 :                                                    files_buffer->filenameBase, newest, oldest) ) {
     391              :         // no file for appending found. Create a new one
     392              :         printf("No multiple files for appending found. Create a new one\n");
     393            0 :         return multiple_files_buffer_create_new_file(files_buffer);
     394              :     }
     395              : 
     396              :     char file_path[PATH_MAX + 1];
     397              :     int ret = snprintf(file_path, sizeof(file_path), "%s/%s",
     398              :                          files_buffer->directory, newest);
     399              : 
     400            3 :     if ((ret < 0) || (ret >= NAME_MAX)) {
     401            0 :         fprintf(stderr, "filename cannot be concatenated\n");
     402            0 :         return DLT_RETURN_ERROR;
     403              :     }
     404              : 
     405              :     /* open DLT output file */
     406            3 :     errno = 0;
     407            3 :     files_buffer->ohandle = open(file_path, O_WRONLY | O_APPEND); /* mode: wb */
     408              : 
     409            3 :     return files_buffer->ohandle == -1 ? DLT_RETURN_ERROR : DLT_RETURN_OK;
     410              : }
     411              : 
     412            3 : DltReturnValue multiple_files_buffer_init(MultipleFilesRingBuffer *files_buffer,
     413              :                                           const char *directory,
     414              :                                           const int file_size,
     415              :                                           const int max_size,
     416              :                                           const bool filename_timestamp_based,
     417              :                                           const bool append,
     418              :                                           const char *filename_base,
     419              :                                           const char *filename_ext)
     420              : {
     421            3 :     if (files_buffer == NULL) {
     422            0 :         fprintf(stderr, "multiple files buffer not set\n");
     423            0 :         return DLT_RETURN_ERROR;
     424              :     }
     425              : 
     426              :     /* init parameters */
     427            3 :     strncpy(files_buffer->directory, directory, NAME_MAX);
     428            3 :     files_buffer->directory[NAME_MAX] = 0;
     429            3 :     files_buffer->fileSize = file_size;
     430            3 :     files_buffer->maxSize = max_size;
     431            3 :     files_buffer->filenameTimestampBased = filename_timestamp_based;
     432            3 :     strncpy(files_buffer->filenameBase, filename_base, NAME_MAX);
     433            3 :     files_buffer->filenameBase[NAME_MAX] = 0;
     434            3 :     strncpy(files_buffer->filenameExt, filename_ext, NAME_MAX);
     435            3 :     files_buffer->filenameExt[NAME_MAX] = 0;
     436              : 
     437            3 :     if (DLT_RETURN_ERROR == multiple_files_buffer_check_size(files_buffer)) return DLT_RETURN_ERROR;
     438              : 
     439            3 :     return (!files_buffer->filenameTimestampBased && append)
     440            3 :         ? multiple_files_buffer_open_file_for_append(files_buffer)
     441            3 :         : multiple_files_buffer_create_new_file(files_buffer);
     442              : }
     443              : 
     444           12 : void multiple_files_buffer_rotate_file(MultipleFilesRingBuffer *files_buffer, const int size)
     445              : {
     446              :     /* check file size here */
     447           12 :     if ((lseek(files_buffer->ohandle, 0, SEEK_CUR) + size) < files_buffer->fileSize) return;
     448              : 
     449              :     /* close old file */
     450            9 :     close(files_buffer->ohandle);
     451            9 :     files_buffer->ohandle = -1;
     452              : 
     453              :     /* check complete files size, remove old logs if needed */
     454            9 :     if (DLT_RETURN_ERROR == multiple_files_buffer_check_size(files_buffer)) return;
     455              : 
     456              :     /* create new file */
     457            9 :     multiple_files_buffer_create_new_file(files_buffer);
     458              : }
     459              : 
     460           12 : DltReturnValue multiple_files_buffer_write_chunk(const MultipleFilesRingBuffer *files_buffer,
     461              :                                                  const unsigned char *data,
     462              :                                                  const int size)
     463              : {
     464           12 :     if (files_buffer == NULL) {
     465            0 :         fprintf(stderr, "multiple files buffer not set\n");
     466            0 :         return DLT_RETURN_ERROR;
     467              :     }
     468              : 
     469           12 :     if (data && (files_buffer->ohandle >= 0)) {
     470           12 :         if (write(files_buffer->ohandle, data, (size_t)size) != (ssize_t)size) {
     471            0 :             fprintf(stderr, "file write failed!\n");
     472            0 :             return DLT_RETURN_ERROR;
     473              :         }
     474              :     }
     475              :     return DLT_RETURN_OK;
     476              : }
     477              : 
     478           12 : DltReturnValue multiple_files_buffer_write(MultipleFilesRingBuffer *files_buffer,
     479              :                                            const unsigned char *data,
     480              :                                            const int size)
     481              : {
     482           12 :     if (files_buffer->ohandle < 0) return DLT_RETURN_ERROR;
     483              : 
     484           12 :     multiple_files_buffer_rotate_file(files_buffer, size);
     485              : 
     486              :     /* write data into log file */
     487           12 :     return multiple_files_buffer_write_chunk(files_buffer, data, size);
     488              : }
     489              : 
     490            3 : DltReturnValue multiple_files_buffer_free(const MultipleFilesRingBuffer *files_buffer)
     491              : {
     492            3 :     if (files_buffer == NULL) {
     493            0 :         fprintf(stderr, "multiple files buffer not set\n");
     494            0 :         return DLT_RETURN_ERROR;
     495              :     }
     496              : 
     497            3 :     if (files_buffer->ohandle < 0) return DLT_RETURN_ERROR;
     498              : 
     499              :     /* close last used log file */
     500            3 :     close(files_buffer->ohandle);
     501              : 
     502            3 :     return DLT_RETURN_OK;
     503              : }
        

Generated by: LCOV version 2.0-1