3 * Copyright (C) 2012 BMW AG
5 * This file is part of GENIVI Project Dlt - Diagnostic Log and Trace console apps.
7 * Contributions are licensed to the GENIVI Alliance under one or more
8 * Contribution License Agreements.
11 * This Source Code Form is subject to the terms of the
12 * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with
13 * this file, You can obtain one at http://mozilla.org/MPL/2.0/.
16 * \author Alexander Wenzel <alexander.aw.wenzel@bmw.de> BMW 2011-2012
18 * \file dlt_offline_trace.c
19 * For further information see http://www.genivi.org/.
24 /*******************************************************************************
26 ** SRC-MODULE: dlt_offline_trace.c **
32 ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de **
38 ** PLATFORM DEPENDANT [yes/no]: yes **
40 ** TO BE CHANGED BY USER [yes/no]: no **
42 *******************************************************************************/
44 /*******************************************************************************
46 ********************************************************************************
48 ** Initials Name Company **
49 ** -------- ------------------------- ---------------------------------- **
50 ** aw Alexander Wenzel BMW **
51 *******************************************************************************/
57 #include <sys/types.h>
63 #include <dlt_offline_trace.h>
65 int dlt_offline_trace_create_new_file(DltOfflineTrace *trace) {
74 printf("dlt_offline_trace_create_new_file: pointer to tmp is NULL!");
77 if (strftime(outstr, sizeof(outstr),"%Y%m%d_%H%M%S", tmp) == 0) {
79 snprintf(trace->filename,NAME_MAX + 1,"%s/dlt_offlinetrace_%s.dlt",trace->directory,outstr);
81 /* open DLT output file */
82 trace->ohandle = open(trace->filename,O_WRONLY|O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); /* mode: wb */
83 if (trace->ohandle == -1)
85 /* trace file cannot be opened */
86 printf("Offline trace file %s cannot be created\n",trace->filename);
93 unsigned long dlt_offline_trace_get_total_size(DltOfflineTrace *trace) {
96 unsigned long size = 0;
99 /* go through all dlt files in directory */
100 DIR *dir = opendir(trace->directory);
101 while ((dp=readdir(dir)) != NULL) {
102 if(strstr(dp->d_name,".dlt"))
104 int res = snprintf(filename, sizeof(filename), "%s/%s",trace->directory,dp->d_name);
105 // if the total length of the string is greater than the buffer, silently forget it.
106 // snprintf: a return value of size or more means that the output was truncated
107 // if an output error is encountered, a negative value is returned.
108 if( (unsigned int)res<sizeof(filename) && res>0 )
110 if(0 == stat(filename,&status))
112 size += status.st_size;
115 printf("Offline trace file %s cannot be stat-ed",filename);
119 // dlt_log(3, "dlt_offline_trace_get_total_size: long filename ignored");
130 int dlt_offline_trace_delete_oldest_file(DltOfflineTrace *trace) {
132 char filename[PATH_MAX+1];
133 char filename_oldest[PATH_MAX+1];
134 unsigned long size_oldest = 0;
136 time_t time_oldest = 0;
139 filename_oldest[0] = 0;
141 /* go through all dlt files in directory */
142 DIR *dir = opendir(trace->directory);
143 while ((dp=readdir(dir)) != NULL) {
144 if(strstr(dp->d_name,".dlt")) {
145 int res = snprintf(filename, sizeof(filename), "%s/%s",trace->directory,dp->d_name);
146 // if the total length of the string is greater than the buffer, silently forget it.
147 // snprintf: a return value of size or more means that the output was truncated
148 // if an output error is encountered, a negative value is returned.
149 if( (unsigned int)res<sizeof(filename) && res>0 )
151 if(0 == stat(filename,&status))
153 if(time_oldest == 0 || status.st_mtime < time_oldest) {
154 time_oldest = status.st_mtime;
155 size_oldest = status.st_size;
156 strncpy(filename_oldest,filename,PATH_MAX);
157 filename_oldest[PATH_MAX]=0;
161 printf("Old offline trace file %s cannot be stat-ed",filename);
168 if(filename_oldest[0]) {
169 if(remove(filename_oldest)) {
170 printf("Remove file %s failed!\n",filename_oldest);
171 return -1; /* ERROR */
175 printf("No file to be removed!\n");
176 return -1; /* ERROR */
179 /* return size of deleted file*/
183 int dlt_offline_trace_check_size(DltOfflineTrace *trace) {
185 /* check size of complete offline trace */
186 while((int)dlt_offline_trace_get_total_size(trace) > (trace->maxSize-trace->fileSize))
188 /* remove oldest files as long as new file will not fit in completely into complete offline trace */
189 if(dlt_offline_trace_delete_oldest_file(trace)<0) {
197 int dlt_offline_trace_init(DltOfflineTrace *trace,const char *directory,int fileSize,int maxSize) {
199 /* init parameters */
200 strncpy(trace->directory,directory,NAME_MAX);
201 trace->directory[NAME_MAX]=0;
202 trace->fileSize = fileSize;
203 trace->maxSize = maxSize;
205 /* check complete offlien trace size, remove old logs if needed */
206 dlt_offline_trace_check_size(trace);
208 return dlt_offline_trace_create_new_file(trace);
211 int dlt_offline_trace_write(DltOfflineTrace *trace,unsigned char *data1,int size1,unsigned char *data2,int size2,unsigned char *data3,int size3) {
213 if(trace->ohandle <= 0)
216 /* check file size here */
217 if((lseek(trace->ohandle,0,SEEK_CUR)+size1+size2+size3)>=trace->fileSize)
220 close(trace->ohandle);
223 /* check complete offline trace size, remove old logs if needed */
224 dlt_offline_trace_check_size(trace);
226 /* create new file */
227 dlt_offline_trace_create_new_file(trace);
230 /* write data into log file */
231 if(data1 && (trace->ohandle >= 0)) {
232 if(write(trace->ohandle,data1,size1)!=size1) {
233 printf("Offline trace write failed!\n");
237 if(data2 && (trace->ohandle >= 0)) {
238 if(write(trace->ohandle,data2,size2)!=size2) {
239 printf("Offline trace write failed!\n");
243 if(data3 && (trace->ohandle >= 0)) {
244 if(write(trace->ohandle,data3,size3)!=size3) {
245 printf("Offline trace write failed!\n");
253 int dlt_offline_trace_free(DltOfflineTrace *trace) {
255 if(trace->ohandle <= 0)
258 /* close last used log file */
259 close(trace->ohandle);