d0aa038e59c1d40e92ba711b6b6fd39665462350
[profile/ivi/dlt-daemon.git] / src / lib / dlt_filetransfer.c
1 /**
2  * @licence app begin@
3  * Copyright (C) 2012  BMW AG
4  *
5  * This file is part of GENIVI Project Dlt - Diagnostic Log and Trace console apps.
6  *
7  * Contributions are licensed to the GENIVI Alliance under one or more
8  * Contribution License Agreements.
9  *
10  * \copyright
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/.
14  *
15  *
16  * \author Alexander Wenzel <alexander.aw.wenzel@bmw.de> BMW 2011-2012
17  *
18  * \file dlt_filetransfer.c
19  * For further information see http://www.genivi.org/.
20  * @licence end@
21  */
22
23
24 /*******************************************************************************
25 **                                                                            **
26 **  SRC-MODULE: dlt-test-client.c                                             **
27 **                                                                            **
28 **  TARGET    : linux                                                         **
29 **                                                                            **
30 **  PROJECT   : DLT                                                           **
31 **                                                                            **
32 **  AUTHOR    : Alexander Wenzel Alexander.AW.Wenzel@bmw.de                   **
33 **                                                                            **
34 **  PURPOSE   :                                                               **
35 **                                                                            **
36 **  REMARKS   :                                                               **
37 **                                                                            **
38 **  PLATFORM DEPENDANT [yes/no]: yes                                          **
39 **                                                                            **
40 **  TO BE CHANGED BY USER [yes/no]: no                                        **
41 **                                                                            **
42 *******************************************************************************/
43
44 /*******************************************************************************
45 **                      Author Identity                                       **
46 ********************************************************************************
47 **                                                                            **
48 ** Initials     Name                       Company                            **
49 ** --------     -------------------------  ---------------------------------- **
50 **  aw          Alexander Wenzel           BMW                                **
51 *******************************************************************************/
52
53 #include <errno.h>
54 #include <stdio.h>
55 #include <string.h>
56 #include "dlt_filetransfer.h"
57 #include "dlt_common.h"
58
59 //!Defines the buffer size of a single file package which will be logged to dlt
60 #define BUFFER_SIZE 1024
61
62 //!Defines the minimum timeout between two dlt logs. This is important because dlt should not be flooded with too many logs in a short period of time.
63 #define MIN_TIMEOUT 20
64
65
66 #define DLT_FILETRANSFER_TRANSFER_ALL_PACKAGES LONG_MAX
67
68
69 //!Buffer for dlt file transfer. The size is defined by BUFFER_SIZE
70 unsigned char buffer[BUFFER_SIZE];
71
72
73 //!Get some information about the file size of a file
74 /**See stat(2) for more informations.
75  * @param file Absolute file path
76  * @return Returns the size of the file (if it is a regular file or a symbolic link) in bytes.
77  */
78 unsigned long getFilesize(const char* file, int *ok){
79         struct stat st;
80
81     if ( -1 == stat(file, &st))
82     {
83         //we can only return 0, as the value is unsigned
84         *ok = 0;
85         return 0;
86     }
87     *ok = 1;
88         return (unsigned long)st.st_size;
89 }
90
91 /** A simple Hash function for C-strings
92  * @param str input string. E.g. a file path.
93  * @param hash start and result value for hash computation
94  *
95  */
96 void stringHash(const char* str, unsigned long *hash )
97 {
98     if (!str || !hash)
99         return;
100    unsigned int len = strlen(str);
101
102    unsigned int i = 0;
103    if (len <= 0){
104     return;
105    }
106
107    for(i = 0; i < len;  i++)
108    {
109       *hash = 53 * *hash  + str[i];
110    }
111
112 }
113
114
115 //!Get some information about the file serial number of a file
116 /** See stat(2) for more informations.
117  * @param file Absolute file path
118  * @param value *ok == 0 -> error; *ok == 1 -> ok
119  * @return Returns a unique number associated with each filename
120  */
121 unsigned long getFileSerialNumber(const char* file, int *ok){
122         struct stat st;
123         unsigned long ret;
124     if ( -1 == stat(file, &st))
125     {
126         *ok = 0;
127         ret = 0;
128     }
129     else
130     {
131         *ok = 1;
132         ret = st.st_ino;
133         ret = ret << (sizeof(ret)*8)/2;
134         ret |= st.st_size;
135         ret ^= st.st_ctime;
136         stringHash(file, &ret);
137     }
138         return ret;
139 }
140
141 //!Returns the creation date of a file
142 /** See stat(2) for more informations.
143  * @param file Absolute file path
144  * @return Returns the creation date of a file
145 */
146 time_t getFileCreationDate(const char* file,int *ok){
147         struct stat st;
148     if (-1 == stat(file, &st))
149     {
150         *ok = 0;
151         return 0;
152     }
153     *ok = 1;
154     return st.st_ctime;
155 }
156
157 //!Returns the creation date of a file
158 /** Format of the creation date is Day Mon dd hh:mm:ss yyyy
159  * @param file Absolute file path
160  * @return Returns the creation date of a file
161 */
162 char* getFileCreationDate2(const char* file,int *ok){
163         struct stat st;
164     if (-1 == stat(file, &st))
165     {
166         *ok = 0;
167         return 0;
168     }
169     *ok = 1;
170         struct tm  *ts= localtime(&st.st_ctime);
171         return asctime(ts);
172 }
173
174 //!Checks if the file exists
175 /**@param file Absolute file path
176  * @return Returns 1 if the file exists, 0 if the file does not exist
177  */
178 int isFile (const char* file)
179 {
180         struct stat   st;   
181         return (stat (file, &st) == 0);
182 }
183
184 //!Waits a period of time
185 /**Waits a period of time. The minimal time to wait is MIN_TIMEOUT. This makes sure that the FIFO of dlt is not flooded.
186  * @param timeout Timeout to in ms but can not be smaller as MIN_TIMEOUT
187  */
188 void doTimeout(int timeout)
189 {
190         usleep(timeout * 1000);
191 }
192
193 //!Checks free space of the user buffer
194 /**
195  * @param returns -1 if more than 50% space in the user buffer is free. Otherwise 1 will be returned.
196  */
197 int checkUserBufferForFreeSpace()
198 {
199         int total_size, used_size;
200
201         dlt_user_check_buffer(&total_size, &used_size);
202
203         if((total_size - used_size) < (total_size/2))
204         {
205                 return -1;
206         }
207         return 1;
208 }
209
210 //!Deletes the given file
211 /**
212  * @param filename Absolute file path
213  * @return If the file is successfully deleted, a zero value is returned.If the file can not be deleted a nonzero value is returned.
214  */
215 int doRemoveFile(const char*filename){
216         return remove( filename); 
217 }
218
219 void dlt_user_log_file_errorMessage(DltContext *fileContext, const char *filename, int errorCode){
220
221         if(errno != ENOENT)
222         {
223         int ok = 0;
224         unsigned long fserial = getFileSerialNumber(filename,&ok);
225         if (!ok)
226             DLT_LOG(*fileContext,DLT_LOG_ERROR,DLT_STRING("dlt_user_log_file_errorMessage, error in getFileSerialNumber for: "),DLT_STRING(filename));
227         unsigned long fsize = getFilesize(filename,&ok);
228         if (!ok)
229             DLT_LOG(*fileContext,DLT_LOG_ERROR,DLT_STRING("dlt_user_log_file_errorMessage, error in getFilesize for: "),DLT_STRING(filename));
230         char *fcreationdate = getFileCreationDate2(filename,&ok);
231         if (!ok)
232             DLT_LOG(*fileContext,DLT_LOG_ERROR,DLT_STRING("dlt_user_log_file_errorMessage, error in getFilesize for: "),DLT_STRING(filename));
233
234         int package_count = dlt_user_log_file_packagesCount(fileContext,filename);
235
236                 DLT_LOG(*fileContext,DLT_LOG_ERROR,
237                         DLT_STRING("FLER"),
238                         DLT_INT(errorCode),
239                         DLT_INT(-errno),
240             DLT_UINT(fserial),
241                         DLT_STRING(filename),
242             DLT_UINT(fsize),
243             DLT_STRING(fcreationdate),
244             DLT_INT(package_count),
245                         DLT_UINT(BUFFER_SIZE),
246                         DLT_STRING("FLER")
247                 );              
248         } else {
249                 DLT_LOG(*fileContext,DLT_LOG_ERROR,
250                         DLT_STRING("FLER"),
251                         DLT_INT(errorCode),
252                         DLT_INT(-errno),
253                         DLT_STRING(filename),
254                         DLT_STRING("FLER")
255                 );
256         }
257 }
258
259
260
261 //!Logs specific file inforamtions to dlt
262 /**The filename, file size, file serial number and the number of packages will be logged to dlt.
263  * @param fileContext Specific context
264  * @param filename Absolute file path
265  * @return Returns 0 if everything was okey.If there was a failure a value < 0 will be returned.
266  */
267 int dlt_user_log_file_infoAbout(DltContext *fileContext, const char *filename){
268         
269         if(isFile(filename))
270         {
271         int ok;
272
273         unsigned long fsize = getFilesize(filename,&ok);
274         if (!ok)
275             DLT_LOG(*fileContext,DLT_LOG_ERROR,DLT_STRING("dlt_user_log_file_infoAbout, Error getting size of file:"),DLT_STRING(filename));
276
277         unsigned long fserialnumber = getFileSerialNumber(filename,&ok);
278         if (!ok)
279             DLT_LOG(*fileContext,DLT_LOG_ERROR,DLT_STRING("dlt_user_log_file_infoAbout, Error getting serial number of file:"),DLT_STRING(filename));
280
281
282         char *creationdate = getFileCreationDate2(filename,&ok);
283         if (!ok)
284             DLT_LOG(*fileContext,DLT_LOG_ERROR,DLT_STRING("dlt_user_log_file_infoAbout, Error getting creation date of file:"),DLT_STRING(filename));
285
286                 DLT_LOG(*fileContext,DLT_LOG_INFO,
287                         DLT_STRING("FLIF"),
288             DLT_STRING("file serialnumber"),DLT_UINT(fserialnumber),
289                         DLT_STRING("filename"),DLT_STRING(filename),
290             DLT_STRING("file size in bytes"),DLT_UINT(fsize),
291             DLT_STRING("file creation date"),DLT_STRING(creationdate),
292                         DLT_STRING("number of packages"),DLT_UINT(dlt_user_log_file_packagesCount(fileContext, filename)),
293                         DLT_STRING("FLIF")
294                 );
295                 return 0;
296         } else {
297                 dlt_user_log_file_errorMessage(fileContext,filename,DLT_FILETRANSFER_ERROR_INFO_ABOUT);
298                 return DLT_FILETRANSFER_ERROR_INFO_ABOUT;
299         }
300 }
301
302 //!Transfer the complete file as several dlt logs.
303 /**This method transfer the complete file as several dlt logs. At first it will be checked that the file exist.
304  * In the next step some generic informations about the file will be logged to dlt.
305  * Now the header will be logged to dlt. See the method dlt_user_log_file_header for more informations.
306  * Then the method dlt_user_log_data will be called with the parameter to log all packages in a loop with some timeout.
307  * At last dlt_user_log_end is called to signal that the complete file transfer was okey. This is important for the plugin of the dlt viewer. 
308  * @param fileContext Specific context to log the file to dlt
309  * @param filename Absolute file path
310  * @param deleteFlag Flag if the file will be deleted after transfer. 1->delete, 0->notDelete
311  * @param timeout Timeout in ms to wait between some logs. Important that the FIFO of dlt will not be flooded with to many messages in a short period of time.
312  * @return Returns 0 if everything was okey. If there was a failure a value < 0 will be returned.
313  */
314 int dlt_user_log_file_complete(DltContext *fileContext, const char *filename, int deleteFlag, int timeout)
315 {       
316         if(!isFile(filename))
317         {
318                 dlt_user_log_file_errorMessage(fileContext,filename, DLT_FILETRANSFER_ERROR_FILE_COMPLETE);
319                 return DLT_FILETRANSFER_ERROR_FILE_COMPLETE;
320         }
321         
322         if(dlt_user_log_file_header(fileContext,filename) != 0)
323         {
324                 return DLT_FILETRANSFER_ERROR_FILE_COMPLETE1;
325         }
326                 
327         if(dlt_user_log_file_data(fileContext, filename,DLT_FILETRANSFER_TRANSFER_ALL_PACKAGES,timeout) != 0)
328         {
329                 return DLT_FILETRANSFER_ERROR_FILE_COMPLETE2;
330         }
331                 
332         if(dlt_user_log_file_end(fileContext,filename, deleteFlag) != 0)
333         {
334                 return DLT_FILETRANSFER_ERROR_FILE_COMPLETE3;
335         }               
336                         
337         return 0;
338 }
339
340 //!This method gives information about the number of packages the file have
341 /**Every file will be divided into several packages. Every package will be logged as a single dlt log.
342  * The number of packages depends on the BUFFER_SIZE.
343  * At first it will be checked if the file exist. Then the file will be divided into
344  * several packages depending on the buffer size.
345  * @param fileContext Specific context to log the file to dlt
346  * @param filename Absolute file path
347  * @return Returns the number of packages if everything was okey. If there was a failure a value < 0 will be returned.
348  */
349 int dlt_user_log_file_packagesCount(DltContext *fileContext, const char *filename){
350         int packages;
351         long filesize;
352         
353         if(isFile(filename))
354         {
355                 packages = 1;
356         int ok;
357         filesize = getFilesize(filename,&ok);
358         if (!ok){
359             DLT_LOG(*fileContext,DLT_LOG_ERROR,DLT_STRING("Error in: dlt_user_log_file_packagesCount, isFile"),DLT_STRING(filename),DLT_INT(DLT_FILETRANSFER_ERROR_PACKAGE_COUNT));
360             return -1;
361         }
362         if(filesize < BUFFER_SIZE)
363                 {       
364                         return packages;
365                 } 
366                 else 
367                 {
368                         packages = filesize/BUFFER_SIZE;
369                         
370                         if(filesize%BUFFER_SIZE == 0)
371                         {       
372                                 return packages;
373                         }
374                         else
375                         {
376                                 return packages+1;
377                         }
378                 }
379         } else {
380         DLT_LOG(*fileContext,DLT_LOG_ERROR,DLT_STRING("Error in: dlt_user_log_file_packagesCount, !isFile"),DLT_STRING(filename),DLT_INT(DLT_FILETRANSFER_ERROR_PACKAGE_COUNT));
381                 return -1;
382         }
383 }
384
385 //!Transfer the head of the file as a dlt logs.
386 /**The head of the file must be logged to dlt because the head contains inforamtion about the file serial number,
387  * the file name, the file size, package number the file have and the buffer size.
388  * All these informations are needed from the plugin of the dlt viewer.
389  * See the Mainpages.c for more informations.
390  * @param fileContext Specific context to log the file to dlt
391  * @param filename Absolute file path
392  * @param alias Alias for the file. An alternative name to show in the receiving end
393  * @return Returns 0 if everything was okey. If there was a failure a value < 0 will be returned.
394  */
395 int dlt_user_log_file_header_alias(DltContext *fileContext,const char *filename, const char *alias){
396
397         if(isFile(filename))
398     {
399         int ok;
400
401         unsigned long fserialnumber = getFileSerialNumber(filename,&ok);
402         if (!ok)
403             DLT_LOG(*fileContext,DLT_LOG_ERROR,DLT_STRING("dlt_user_log_file_header_alias, Error getting serial number of file:"),DLT_STRING(filename));
404
405         unsigned long fsize = getFilesize(filename,&ok);
406         if (!ok)
407             DLT_LOG(*fileContext,DLT_LOG_ERROR,DLT_STRING("dlt_user_log_file_header_alias, Error getting size of file:"),DLT_STRING(filename));
408
409         char *fcreationdate = getFileCreationDate2(filename,&ok);
410         if (!ok)
411             DLT_LOG(*fileContext,DLT_LOG_ERROR,DLT_STRING("dlt_user_log_file_header_alias, Error getting creation date of file:"),DLT_STRING(filename));
412
413
414
415         DLT_LOG(*fileContext,DLT_LOG_INFO,
416                 DLT_STRING("FLST"),
417                 DLT_UINT(fserialnumber),
418                 DLT_STRING(alias),
419                 DLT_UINT(fsize),
420                 DLT_STRING(fcreationdate);
421                 DLT_UINT(dlt_user_log_file_packagesCount(fileContext,filename)),
422                 DLT_UINT(BUFFER_SIZE),
423                 DLT_STRING("FLST")
424                 );
425
426                 return 0;
427         }
428         else
429         {
430                 dlt_user_log_file_errorMessage(fileContext,filename, DLT_FILETRANSFER_ERROR_FILE_HEAD);
431                 return DLT_FILETRANSFER_ERROR_FILE_HEAD;
432         }
433 }
434
435 //!Transfer the head of the file as a dlt logs.
436 /**The head of the file must be logged to dlt because the head contains inforamtion about the file serial number,
437  * the file name, the file size, package number the file have and the buffer size.
438  * All these informations are needed from the plugin of the dlt viewer.
439  * See the Mainpages.c for more informations.
440  * @param fileContext Specific context to log the file to dlt
441  * @param filename Absolute file path
442  * @return Returns 0 if everything was okey. If there was a failure a value < 0 will be returned.
443  */
444 int dlt_user_log_file_header(DltContext *fileContext,const char *filename){
445
446         if(isFile(filename))
447         {
448         int ok;
449
450         unsigned long fserialnumber = getFileSerialNumber(filename,&ok);
451         if (!ok)
452             DLT_LOG(*fileContext,DLT_LOG_ERROR,DLT_STRING("dlt_user_log_file_header, Error getting serial number of file:"),DLT_STRING(filename));
453
454         unsigned long fsize = getFilesize(filename,&ok);
455         if (!ok)
456             DLT_LOG(*fileContext,DLT_LOG_ERROR,DLT_STRING("dlt_user_log_file_header, Error getting size of file:"),DLT_STRING(filename));
457
458         char *fcreationdate = getFileCreationDate2(filename,&ok);
459         if (!ok)
460             DLT_LOG(*fileContext,DLT_LOG_ERROR,DLT_STRING("dlt_user_log_file_header, Error getting creation date of file:"),DLT_STRING(filename));
461
462
463
464
465                 DLT_LOG(*fileContext,DLT_LOG_INFO,
466                                         DLT_STRING("FLST"),
467                     DLT_UINT(fserialnumber),
468                                         DLT_STRING(filename),
469                     DLT_UINT(fsize),
470                     DLT_STRING(fcreationdate);
471                                         DLT_UINT(dlt_user_log_file_packagesCount(fileContext,filename)),
472                                         DLT_UINT(BUFFER_SIZE),
473                                         DLT_STRING("FLST")              
474                                 );
475
476                 return 0;
477         }
478         else
479         {
480                 dlt_user_log_file_errorMessage(fileContext,filename, DLT_FILETRANSFER_ERROR_FILE_HEAD);
481                 return DLT_FILETRANSFER_ERROR_FILE_HEAD;
482         }
483 }
484
485 //!Transfer the content data of a file.
486 /**See the Mainpages.c for more informations.
487  * @param fileContext Specific context to log the file to dlt
488  * @param filename Absolute file path
489  * @param packageToTransfer Package number to transfer. If this param is LONG_MAX, the whole file will be transferred with a specific timeout
490  * @param timeout Timeout to wait between dlt logs. Important because the dlt FIFO should not be flooded. Default is defined by MIN_TIMEOUT. The given timeout in ms can not be smaller than MIN_TIMEOUT.
491  * @return Returns 0 if everything was okey. If there was a failure a value < 0 will be returned.
492  */
493 int dlt_user_log_file_data(DltContext *fileContext,const char *filename, int packageToTransfer, int timeout){
494         FILE *file;
495         int pkgNumber;
496         long readBytes;
497                 
498         if(isFile(filename))
499         {
500         
501                 file = fopen (filename,"rb");
502                 if (file == NULL)
503                 {
504                         dlt_user_log_file_errorMessage(fileContext,filename,DLT_FILETRANSFER_ERROR_FILE_DATA);
505                         return DLT_FILETRANSFER_ERROR_FILE_DATA;
506                 }
507                 
508                 if( (packageToTransfer != DLT_FILETRANSFER_TRANSFER_ALL_PACKAGES && packageToTransfer > dlt_user_log_file_packagesCount(fileContext,filename)) || packageToTransfer <= 0)
509                 {
510                         DLT_LOG(*fileContext,DLT_LOG_ERROR,
511                                 DLT_STRING("Error at dlt_user_log_file_data: packageToTransfer out of scope"),
512                                 DLT_STRING("packageToTransfer:"),
513                                 DLT_UINT(packageToTransfer),
514                                 DLT_STRING("numberOfMaximalPackages:"),
515                                 DLT_UINT(dlt_user_log_file_packagesCount(fileContext,filename)),
516                                 DLT_STRING("for File:"),
517                                 DLT_STRING(filename)
518                         );
519                         fclose(file);
520                         return DLT_FILETRANSFER_ERROR_FILE_DATA;
521                 }
522
523                 readBytes = 0;
524                 
525                 if(packageToTransfer != DLT_FILETRANSFER_TRANSFER_ALL_PACKAGES)
526                 {
527 //                              If a single package should be transferred. The user has to check that the free space in the user buffer > 50%
528 //                              if(checkUserBufferForFreeSpace()<0)
529 //                                      return DLT_FILETRANSFER_ERROR_FILE_DATA_USER_BUFFER_FAILED;
530
531                 if ( 0 != fseek ( file , (packageToTransfer-1)*BUFFER_SIZE , SEEK_SET ) )
532                 {
533                         DLT_LOG(*fileContext,DLT_LOG_ERROR,
534                         DLT_STRING("failed to fseek in file: "),
535                         DLT_STRING(filename),
536                         DLT_STRING("ferror:"),
537                         DLT_INT(ferror(file))
538                     );
539
540                     fclose (file);
541                     return -1;
542
543                 }
544                                 readBytes = fread(buffer, sizeof(char), BUFFER_SIZE, file);
545                 int ok;
546
547                 unsigned long fserial = getFileSerialNumber(filename,&ok);
548
549                 if (1 != ok)
550                 {
551                     DLT_LOG(*fileContext,DLT_LOG_ERROR,
552                     DLT_STRING("failed to get FileSerialNumber for: "),
553                     DLT_STRING(filename));
554                 }
555
556                                 DLT_LOG(*fileContext,DLT_LOG_INFO,
557                                 DLT_STRING("FLDA"),
558                 DLT_UINT(fserial),
559                                 DLT_UINT(packageToTransfer),
560                                 DLT_RAW(buffer,readBytes),
561                                 DLT_STRING("FLDA")
562                                 );
563
564                                 doTimeout(timeout);
565
566                 } else {
567                         pkgNumber = 0;
568                         while( !feof( file ) )
569                         {
570 //                              If the complete file should be transferred, the user buffer will be checked.
571 //                              If free space < 50% the package won't be transferred.
572                                 if(checkUserBufferForFreeSpace()>0)
573                                 {
574                                         pkgNumber++;
575                                         readBytes = fread(buffer, sizeof(char), BUFFER_SIZE, file);
576                                         int ok;
577
578                     unsigned long fserial = getFileSerialNumber(filename,&ok);
579
580                     if (1 != ok)
581                     {
582                         DLT_LOG(*fileContext,DLT_LOG_ERROR,
583                         DLT_STRING("failed to get FileSerialNumber for: "),
584                         DLT_STRING(filename));
585                     }
586
587                                         DLT_LOG(*fileContext,DLT_LOG_INFO,
588                                                         DLT_STRING("FLDA"),
589                             DLT_UINT(fserial),
590                                                         DLT_UINT(pkgNumber),
591                                                         DLT_RAW(buffer,readBytes),
592                                                         DLT_STRING("FLDA")
593                                         );
594                                 }
595                                 doTimeout(timeout);
596                         }
597                 }
598                 
599                 fclose(file);
600                 
601                 return 0;
602                 
603         } else {
604                 dlt_user_log_file_errorMessage(fileContext,filename,DLT_FILETRANSFER_ERROR_FILE_DATA);
605                 return DLT_FILETRANSFER_ERROR_FILE_DATA;
606         }
607         
608 }
609 //!Transfer the end of the file as a dlt logs.
610 /**The end of the file must be logged to dlt because the end contains inforamtion about the file serial number.
611  * This informations is needed from the plugin of the dlt viewer.
612  * See the Mainpages.c for more informations.
613  * @param fileContext Specific context to log the file to dlt
614  * @param filename Absolute file path
615  * @param deleteFlag Flag to delete the file after the whole file is transferred (logged to dlt).1->delete,0->NotDelete
616  * @return Returns 0 if everything was okey. If there was a failure a value < 0 will be returned.
617  */
618 int dlt_user_log_file_end(DltContext *fileContext,const char *filename,int deleteFlag){
619
620         if(isFile(filename))
621         {
622
623                 int ok;
624         unsigned long fserial = getFileSerialNumber(filename,&ok);
625
626         if (1 != ok)
627         {
628             DLT_LOG(*fileContext,DLT_LOG_ERROR,
629             DLT_STRING("failed to get FileSerialNumber for: "),
630             DLT_STRING(filename));
631         }
632
633                 DLT_LOG(*fileContext,DLT_LOG_INFO,
634                                 DLT_STRING("FLFI"),
635                 DLT_UINT(fserial),
636                                 DLT_STRING("FLFI")
637                 );
638                 
639                 if(deleteFlag){
640                                 if( doRemoveFile(filename) != 0 ){
641                                         dlt_user_log_file_errorMessage(fileContext,filename,DLT_FILETRANSFER_ERROR_FILE_END);
642                                         return -1;
643                                 }
644                 }
645         
646                 return 0;
647         }else{
648                 dlt_user_log_file_errorMessage(fileContext,filename,DLT_FILETRANSFER_ERROR_FILE_END);
649                 return DLT_FILETRANSFER_ERROR_FILE_END;
650         }
651 }