1 #include "dlt_filetransfer.h"
3 //!Defines the buffer size of a single file package which will be logged to dlt
4 #define BUFFER_SIZE 1024
6 //!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.
10 #define DLT_FILETRANSFER_TRANSFER_ALL_PACKAGES LONG_MAX
13 //!Buffer for dlt file transfer. The size is defined by BUFFER_SIZE
14 unsigned char buffer[BUFFER_SIZE];
17 //!Get some information about the file size of a file
18 /**See stat(2) for more informations.
19 * @param file Absolute file path
20 * @return Returns the size of the file (if it is a regular file or a symbolic link) in bytes.
22 unsigned long getFilesize(const char* file){
25 return (unsigned long)st.st_size;
28 //!Get some information about the file serial number of a file
29 /** See stat(2) for more informations.
30 * @param file Absolute file path
31 * @return Returns a unique number associated with each filename
33 unsigned long getFileSerialNumber(const char* file){
36 return (unsigned long)st.st_ino;
39 //!Returns the creation date of a file
40 /** See stat(2) for more informations.
41 * @param file Absolute file path
42 * @return Returns the creation date of a file
44 time_t getFileCreationDate(const char* file){
50 //!Returns the creation date of a file
51 /** Format of the creation date is Day Mon dd hh:mm:ss yyyy
52 * @param file Absolute file path
53 * @return Returns the creation date of a file
55 char* getFileCreationDate2(const char* file){
59 struct tm *ts= localtime(&st.st_ctime);
63 //!Checks if the file exists
64 /**@param file Absolute file path
65 * @return Returns 1 if the file exists, 0 if the file does not exist
67 int isFile (const char* file)
70 return (stat (file, &st) == 0);
73 //!Waits a period of time
74 /**Waits a period of time. The minimal time to wait is MIN_TIMEOUT. This makes sure that the FIFO of dlt is not flooded.
75 * @param timeout Timeout to in ms but can not be smaller as MIN_TIMEOUT
77 void doTimeout(int timeout)
79 usleep(timeout * 1000);
82 //!Checks free space of the user buffer
84 * @param returns -1 if more than 50% space in the user buffer is free. Otherwise 1 will be returned.
86 int checkUserBufferForFreeSpace()
88 int total_size, used_size;
90 dlt_user_check_buffer(&total_size, &used_size);
92 if((total_size - used_size) < (total_size/2))
99 //!Deletes the given file
101 * @param filename Absolute file path
102 * @return If the file is successfully deleted, a zero value is returned.If the file can not be deleted a nonzero value is returned.
104 int doRemoveFile(const char*filename){
105 return remove( filename);
108 void dlt_user_log_file_errorMessage(DltContext *fileContext, const char *filename, int errorCode){
112 DLT_LOG(*fileContext,DLT_LOG_ERROR,
116 DLT_UINT(getFileSerialNumber(filename)),
117 DLT_STRING(filename),
118 DLT_UINT(getFilesize(filename)),
119 DLT_STRING(getFileCreationDate2(filename)),
120 DLT_UINT(dlt_user_log_file_packagesCount(fileContext,filename)),
121 DLT_UINT(BUFFER_SIZE),
125 DLT_LOG(*fileContext,DLT_LOG_ERROR,
129 DLT_STRING(filename),
137 //!Logs specific file inforamtions to dlt
138 /**The filename, file size, file serial number and the number of packages will be logged to dlt.
139 * @param fileContext Specific context
140 * @param filename Absolute file path
141 * @return Returns 0 if everything was okey.If there was a failure a value < 0 will be returned.
143 int dlt_user_log_file_infoAbout(DltContext *fileContext, const char *filename){
147 DLT_LOG(*fileContext,DLT_LOG_INFO,
149 DLT_STRING("file serialnumber"),DLT_UINT(getFileSerialNumber(filename)),
150 DLT_STRING("filename"),DLT_STRING(filename),
151 DLT_STRING("file size in bytes"),DLT_UINT(getFilesize(filename)),
152 DLT_STRING("file creation date"),DLT_STRING(getFileCreationDate2(filename)),
153 DLT_STRING("number of packages"),DLT_UINT(dlt_user_log_file_packagesCount(fileContext, filename)),
158 dlt_user_log_file_errorMessage(fileContext,filename,DLT_FILETRANSFER_ERROR_INFO_ABOUT);
159 return DLT_FILETRANSFER_ERROR_INFO_ABOUT;
163 //!Transfer the complete file as several dlt logs.
164 /**This method transfer the complete file as several dlt logs. At first it will be checked that the file exist.
165 * In the next step some generic informations about the file will be logged to dlt.
166 * Now the header will be logged to dlt. See the method dlt_user_log_file_header for more informations.
167 * Then the method dlt_user_log_data will be called with the parameter to log all packages in a loop with some timeout.
168 * 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.
169 * @param fileContext Specific context to log the file to dlt
170 * @param filename Absolute file path
171 * @param deleteFlag Flag if the file will be deleted after transfer. 1->delete, 0->notDelete
172 * @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.
173 * @return Returns 0 if everything was okey. If there was a failure a value < 0 will be returned.
175 int dlt_user_log_file_complete(DltContext *fileContext, const char *filename, int deleteFlag, int timeout)
177 if(!isFile(filename))
179 dlt_user_log_file_errorMessage(fileContext,filename, DLT_FILETRANSFER_ERROR_FILE_COMPLETE);
180 return DLT_FILETRANSFER_ERROR_FILE_COMPLETE;
183 if(dlt_user_log_file_header(fileContext,filename) != 0)
185 return DLT_FILETRANSFER_ERROR_FILE_COMPLETE1;
188 if(dlt_user_log_file_data(fileContext, filename,DLT_FILETRANSFER_TRANSFER_ALL_PACKAGES,timeout) != 0)
190 return DLT_FILETRANSFER_ERROR_FILE_COMPLETE2;
193 if(dlt_user_log_file_end(fileContext,filename, deleteFlag) != 0)
195 return DLT_FILETRANSFER_ERROR_FILE_COMPLETE3;
201 //!This method gives information about the number of packages the file have
202 /**Every file will be divided into several packages. Every package will be logged as a single dlt log.
203 * The number of packages depends on the BUFFER_SIZE.
204 * At first it will be checked if the file exist. Then the file will be divided into
205 * several packages depending on the buffer size.
206 * @param fileContext Specific context to log the file to dlt
207 * @param filename Absolute file path
208 * @return Returns the number of packages if everything was okey. If there was a failure a value < 0 will be returned.
210 int dlt_user_log_file_packagesCount(DltContext *fileContext, const char *filename){
217 filesize = getFilesize(filename);
218 if(filesize < BUFFER_SIZE)
224 packages = filesize/BUFFER_SIZE;
226 if(filesize%BUFFER_SIZE == 0)
236 dlt_user_log_file_errorMessage(fileContext,filename,DLT_FILETRANSFER_ERROR_PACKAGE_COUNT);
241 //!Transfer the head of the file as a dlt logs.
242 /**The head of the file must be logged to dlt because the head contains inforamtion about the file serial number,
243 * the file name, the file size, package number the file have and the buffer size.
244 * All these informations are needed from the plugin of the dlt viewer.
245 * See the Mainpages.c for more informations.
246 * @param fileContext Specific context to log the file to dlt
247 * @param filename Absolute file path
248 * @return Returns 0 if everything was okey. If there was a failure a value < 0 will be returned.
250 int dlt_user_log_file_header(DltContext *fileContext,const char *filename){
254 DLT_LOG(*fileContext,DLT_LOG_INFO,
256 DLT_UINT(getFileSerialNumber(filename)),
257 DLT_STRING(filename),
258 DLT_UINT(getFilesize(filename)),
259 DLT_STRING(getFileCreationDate2(filename));
260 DLT_UINT(dlt_user_log_file_packagesCount(fileContext,filename)),
261 DLT_UINT(BUFFER_SIZE),
269 dlt_user_log_file_errorMessage(fileContext,filename, DLT_FILETRANSFER_ERROR_FILE_HEAD);
270 return DLT_FILETRANSFER_ERROR_FILE_HEAD;
274 //!Transfer the content data of a file.
275 /**See the Mainpages.c for more informations.
276 * @param fileContext Specific context to log the file to dlt
277 * @param filename Absolute file path
278 * @param packageToTransfer Package number to transfer. If this param is LONG_MAX, the whole file will be transferred with a specific timeout
279 * @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.
280 * @return Returns 0 if everything was okey. If there was a failure a value < 0 will be returned.
282 int dlt_user_log_file_data(DltContext *fileContext,const char *filename, int packageToTransfer, int timeout){
290 file = fopen (filename,"rb");
293 dlt_user_log_file_errorMessage(fileContext,filename,DLT_FILETRANSFER_ERROR_FILE_DATA);
294 return DLT_FILETRANSFER_ERROR_FILE_DATA;
297 if( (packageToTransfer != DLT_FILETRANSFER_TRANSFER_ALL_PACKAGES && packageToTransfer > dlt_user_log_file_packagesCount(fileContext,filename)) || packageToTransfer <= 0)
299 DLT_LOG(*fileContext,DLT_LOG_ERROR,
300 DLT_STRING("Error at dlt_user_log_file_data: packageToTransfer out of scope"),
301 DLT_STRING("packageToTransfer:"),
302 DLT_UINT(packageToTransfer),
303 DLT_STRING("numberOfMaximalPackages:"),
304 DLT_UINT(dlt_user_log_file_packagesCount(fileContext,filename)),
305 DLT_STRING("for File:"),
308 return DLT_FILETRANSFER_ERROR_FILE_DATA;
313 if(packageToTransfer != DLT_FILETRANSFER_TRANSFER_ALL_PACKAGES)
315 // If a single package should be transferred. The user has to check that the free space in the user buffer > 50%
316 // if(checkUserBufferForFreeSpace()<0)
317 // return DLT_FILETRANSFER_ERROR_FILE_DATA_USER_BUFFER_FAILED;
319 fseek ( file , (packageToTransfer-1)*BUFFER_SIZE , SEEK_SET );
320 readBytes = fread(buffer, sizeof(char), BUFFER_SIZE, file);
322 DLT_LOG(*fileContext,DLT_LOG_INFO,
324 DLT_UINT(getFileSerialNumber(filename)),
325 DLT_UINT(packageToTransfer),
326 DLT_RAW(buffer,readBytes),
334 while( !feof( file ) )
336 // If the complete file should be transferred, the user buffer will be checked.
337 // If free space < 50% the package won't be transferred.
338 if(checkUserBufferForFreeSpace()>0)
341 readBytes = fread(buffer, sizeof(char), BUFFER_SIZE, file);
343 DLT_LOG(*fileContext,DLT_LOG_INFO,
345 DLT_UINT(getFileSerialNumber(filename)),
347 DLT_RAW(buffer,readBytes),
360 dlt_user_log_file_errorMessage(fileContext,filename,DLT_FILETRANSFER_ERROR_FILE_DATA);
361 return DLT_FILETRANSFER_ERROR_FILE_DATA;
365 //!Transfer the end of the file as a dlt logs.
366 /**The end of the file must be logged to dlt because the end contains inforamtion about the file serial number.
367 * This informations is needed from the plugin of the dlt viewer.
368 * See the Mainpages.c for more informations.
369 * @param fileContext Specific context to log the file to dlt
370 * @param filename Absolute file path
371 * @param deleteFlag Flag to delete the file after the whole file is transferred (logged to dlt).1->delete,0->NotDelete
372 * @return Returns 0 if everything was okey. If there was a failure a value < 0 will be returned.
374 int dlt_user_log_file_end(DltContext *fileContext,const char *filename,int deleteFlag){
379 DLT_LOG(*fileContext,DLT_LOG_INFO,
381 DLT_UINT(getFileSerialNumber(filename)),
386 if( doRemoveFile(filename) != 0 ){
387 dlt_user_log_file_errorMessage(fileContext,filename,DLT_FILETRANSFER_ERROR_FILE_END);
394 dlt_user_log_file_errorMessage(fileContext,filename,DLT_FILETRANSFER_ERROR_FILE_END);
395 return DLT_FILETRANSFER_ERROR_FILE_END;