2 * Dlt Test Client - Diagnostic Log and Trace
5 * Copyright (C) 2011, BMW AG - Alexander Wenzel <alexander.wenzel@bmw.de>
7 * This program is free software; you can redistribute it and/or modify it under the terms of the
8 * GNU Lesser General Public License, version 2.1, as published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
10 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
11 * Public License, version 2.1, for more details.
13 * You should have received a copy of the GNU Lesser General Public License, version 2.1, along
14 * with this program; if not, see <http://www.gnu.org/licenses/lgpl-2.1.html>.
16 * Note that the copyright holders assume that the GNU Lesser General Public License, version 2.1, may
17 * also be applicable to programs even in cases in which the program is not a library in the technical sense.
19 * Linking DLT statically or dynamically with other modules is making a combined work based on DLT. You may
20 * license such other modules under the GNU Lesser General Public License, version 2.1. If you do not want to
21 * license your linked modules under the GNU Lesser General Public License, version 2.1, you
22 * may use the program under the following exception.
24 * As a special exception, the copyright holders of DLT give you permission to combine DLT
25 * with software programs or libraries that are released under any license unless such a combination is not
26 * permitted by the license of such a software program or library. You may copy and distribute such a
27 * system following the terms of the GNU Lesser General Public License, version 2.1, including this
28 * special exception, for DLT and the licenses of the other code concerned.
30 * Note that people who make modified versions of DLT are not obligated to grant this special exception
31 * for their modified versions; it is their choice whether to do so. The GNU Lesser General Public License,
32 * version 2.1, gives permission to release a modified version without this exception; this exception
33 * also makes it possible to release a modified version which carries forward this exception.
39 /*******************************************************************************
41 ** SRC-MODULE: dlt-test-client.c **
47 ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de **
53 ** PLATFORM DEPENDANT [yes/no]: yes **
55 ** TO BE CHANGED BY USER [yes/no]: no **
57 *******************************************************************************/
59 /*******************************************************************************
61 ********************************************************************************
63 ** Initials Name Company **
64 ** -------- ------------------------- ---------------------------------- **
65 ** aw Alexander Wenzel BMW **
66 *******************************************************************************/
68 #include "dlt_filetransfer.h"
70 //!Defines the buffer size of a single file package which will be logged to dlt
71 #define BUFFER_SIZE 1024
73 //!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.
74 #define MIN_TIMEOUT 20
77 #define DLT_FILETRANSFER_TRANSFER_ALL_PACKAGES LONG_MAX
80 //!Buffer for dlt file transfer. The size is defined by BUFFER_SIZE
81 unsigned char buffer[BUFFER_SIZE];
84 //!Get some information about the file size of a file
85 /**See stat(2) for more informations.
86 * @param file Absolute file path
87 * @return Returns the size of the file (if it is a regular file or a symbolic link) in bytes.
89 unsigned long getFilesize(const char* file){
92 return (unsigned long)st.st_size;
95 //!Get some information about the file serial number of a file
96 /** See stat(2) for more informations.
97 * @param file Absolute file path
98 * @return Returns a unique number associated with each filename
100 unsigned long getFileSerialNumber(const char* file){
103 return (unsigned long)st.st_ino;
106 //!Returns the creation date of a file
107 /** See stat(2) for more informations.
108 * @param file Absolute file path
109 * @return Returns the creation date of a file
111 time_t getFileCreationDate(const char* file){
117 //!Returns the creation date of a file
118 /** Format of the creation date is Day Mon dd hh:mm:ss yyyy
119 * @param file Absolute file path
120 * @return Returns the creation date of a file
122 char* getFileCreationDate2(const char* file){
126 struct tm *ts= localtime(&st.st_ctime);
130 //!Checks if the file exists
131 /**@param file Absolute file path
132 * @return Returns 1 if the file exists, 0 if the file does not exist
134 int isFile (const char* file)
137 return (stat (file, &st) == 0);
140 //!Waits a period of time
141 /**Waits a period of time. The minimal time to wait is MIN_TIMEOUT. This makes sure that the FIFO of dlt is not flooded.
142 * @param timeout Timeout to in ms but can not be smaller as MIN_TIMEOUT
144 void doTimeout(int timeout)
146 usleep(timeout * 1000);
149 //!Checks free space of the user buffer
151 * @param returns -1 if more than 50% space in the user buffer is free. Otherwise 1 will be returned.
153 int checkUserBufferForFreeSpace()
155 int total_size, used_size;
157 dlt_user_check_buffer(&total_size, &used_size);
159 if((total_size - used_size) < (total_size/2))
166 //!Deletes the given file
168 * @param filename Absolute file path
169 * @return If the file is successfully deleted, a zero value is returned.If the file can not be deleted a nonzero value is returned.
171 int doRemoveFile(const char*filename){
172 return remove( filename);
175 void dlt_user_log_file_errorMessage(DltContext *fileContext, const char *filename, int errorCode){
179 DLT_LOG(*fileContext,DLT_LOG_ERROR,
183 DLT_UINT(getFileSerialNumber(filename)),
184 DLT_STRING(filename),
185 DLT_UINT(getFilesize(filename)),
186 DLT_STRING(getFileCreationDate2(filename)),
187 DLT_UINT(dlt_user_log_file_packagesCount(fileContext,filename)),
188 DLT_UINT(BUFFER_SIZE),
192 DLT_LOG(*fileContext,DLT_LOG_ERROR,
196 DLT_STRING(filename),
204 //!Logs specific file inforamtions to dlt
205 /**The filename, file size, file serial number and the number of packages will be logged to dlt.
206 * @param fileContext Specific context
207 * @param filename Absolute file path
208 * @return Returns 0 if everything was okey.If there was a failure a value < 0 will be returned.
210 int dlt_user_log_file_infoAbout(DltContext *fileContext, const char *filename){
214 DLT_LOG(*fileContext,DLT_LOG_INFO,
216 DLT_STRING("file serialnumber"),DLT_UINT(getFileSerialNumber(filename)),
217 DLT_STRING("filename"),DLT_STRING(filename),
218 DLT_STRING("file size in bytes"),DLT_UINT(getFilesize(filename)),
219 DLT_STRING("file creation date"),DLT_STRING(getFileCreationDate2(filename)),
220 DLT_STRING("number of packages"),DLT_UINT(dlt_user_log_file_packagesCount(fileContext, filename)),
225 dlt_user_log_file_errorMessage(fileContext,filename,DLT_FILETRANSFER_ERROR_INFO_ABOUT);
226 return DLT_FILETRANSFER_ERROR_INFO_ABOUT;
230 //!Transfer the complete file as several dlt logs.
231 /**This method transfer the complete file as several dlt logs. At first it will be checked that the file exist.
232 * In the next step some generic informations about the file will be logged to dlt.
233 * Now the header will be logged to dlt. See the method dlt_user_log_file_header for more informations.
234 * Then the method dlt_user_log_data will be called with the parameter to log all packages in a loop with some timeout.
235 * 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.
236 * @param fileContext Specific context to log the file to dlt
237 * @param filename Absolute file path
238 * @param deleteFlag Flag if the file will be deleted after transfer. 1->delete, 0->notDelete
239 * @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.
240 * @return Returns 0 if everything was okey. If there was a failure a value < 0 will be returned.
242 int dlt_user_log_file_complete(DltContext *fileContext, const char *filename, int deleteFlag, int timeout)
244 if(!isFile(filename))
246 dlt_user_log_file_errorMessage(fileContext,filename, DLT_FILETRANSFER_ERROR_FILE_COMPLETE);
247 return DLT_FILETRANSFER_ERROR_FILE_COMPLETE;
250 if(dlt_user_log_file_header(fileContext,filename) != 0)
252 return DLT_FILETRANSFER_ERROR_FILE_COMPLETE1;
255 if(dlt_user_log_file_data(fileContext, filename,DLT_FILETRANSFER_TRANSFER_ALL_PACKAGES,timeout) != 0)
257 return DLT_FILETRANSFER_ERROR_FILE_COMPLETE2;
260 if(dlt_user_log_file_end(fileContext,filename, deleteFlag) != 0)
262 return DLT_FILETRANSFER_ERROR_FILE_COMPLETE3;
268 //!This method gives information about the number of packages the file have
269 /**Every file will be divided into several packages. Every package will be logged as a single dlt log.
270 * The number of packages depends on the BUFFER_SIZE.
271 * At first it will be checked if the file exist. Then the file will be divided into
272 * several packages depending on the buffer size.
273 * @param fileContext Specific context to log the file to dlt
274 * @param filename Absolute file path
275 * @return Returns the number of packages if everything was okey. If there was a failure a value < 0 will be returned.
277 int dlt_user_log_file_packagesCount(DltContext *fileContext, const char *filename){
284 filesize = getFilesize(filename);
285 if(filesize < BUFFER_SIZE)
291 packages = filesize/BUFFER_SIZE;
293 if(filesize%BUFFER_SIZE == 0)
303 dlt_user_log_file_errorMessage(fileContext,filename,DLT_FILETRANSFER_ERROR_PACKAGE_COUNT);
308 //!Transfer the head of the file as a dlt logs.
309 /**The head of the file must be logged to dlt because the head contains inforamtion about the file serial number,
310 * the file name, the file size, package number the file have and the buffer size.
311 * All these informations are needed from the plugin of the dlt viewer.
312 * See the Mainpages.c for more informations.
313 * @param fileContext Specific context to log the file to dlt
314 * @param filename Absolute file path
315 * @return Returns 0 if everything was okey. If there was a failure a value < 0 will be returned.
317 int dlt_user_log_file_header(DltContext *fileContext,const char *filename){
321 DLT_LOG(*fileContext,DLT_LOG_INFO,
323 DLT_UINT(getFileSerialNumber(filename)),
324 DLT_STRING(filename),
325 DLT_UINT(getFilesize(filename)),
326 DLT_STRING(getFileCreationDate2(filename));
327 DLT_UINT(dlt_user_log_file_packagesCount(fileContext,filename)),
328 DLT_UINT(BUFFER_SIZE),
336 dlt_user_log_file_errorMessage(fileContext,filename, DLT_FILETRANSFER_ERROR_FILE_HEAD);
337 return DLT_FILETRANSFER_ERROR_FILE_HEAD;
341 //!Transfer the content data of a file.
342 /**See the Mainpages.c for more informations.
343 * @param fileContext Specific context to log the file to dlt
344 * @param filename Absolute file path
345 * @param packageToTransfer Package number to transfer. If this param is LONG_MAX, the whole file will be transferred with a specific timeout
346 * @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.
347 * @return Returns 0 if everything was okey. If there was a failure a value < 0 will be returned.
349 int dlt_user_log_file_data(DltContext *fileContext,const char *filename, int packageToTransfer, int timeout){
357 file = fopen (filename,"rb");
360 dlt_user_log_file_errorMessage(fileContext,filename,DLT_FILETRANSFER_ERROR_FILE_DATA);
361 return DLT_FILETRANSFER_ERROR_FILE_DATA;
364 if( (packageToTransfer != DLT_FILETRANSFER_TRANSFER_ALL_PACKAGES && packageToTransfer > dlt_user_log_file_packagesCount(fileContext,filename)) || packageToTransfer <= 0)
366 DLT_LOG(*fileContext,DLT_LOG_ERROR,
367 DLT_STRING("Error at dlt_user_log_file_data: packageToTransfer out of scope"),
368 DLT_STRING("packageToTransfer:"),
369 DLT_UINT(packageToTransfer),
370 DLT_STRING("numberOfMaximalPackages:"),
371 DLT_UINT(dlt_user_log_file_packagesCount(fileContext,filename)),
372 DLT_STRING("for File:"),
375 return DLT_FILETRANSFER_ERROR_FILE_DATA;
380 if(packageToTransfer != DLT_FILETRANSFER_TRANSFER_ALL_PACKAGES)
382 // If a single package should be transferred. The user has to check that the free space in the user buffer > 50%
383 // if(checkUserBufferForFreeSpace()<0)
384 // return DLT_FILETRANSFER_ERROR_FILE_DATA_USER_BUFFER_FAILED;
386 fseek ( file , (packageToTransfer-1)*BUFFER_SIZE , SEEK_SET );
387 readBytes = fread(buffer, sizeof(char), BUFFER_SIZE, file);
389 DLT_LOG(*fileContext,DLT_LOG_INFO,
391 DLT_UINT(getFileSerialNumber(filename)),
392 DLT_UINT(packageToTransfer),
393 DLT_RAW(buffer,readBytes),
401 while( !feof( file ) )
403 // If the complete file should be transferred, the user buffer will be checked.
404 // If free space < 50% the package won't be transferred.
405 if(checkUserBufferForFreeSpace()>0)
408 readBytes = fread(buffer, sizeof(char), BUFFER_SIZE, file);
410 DLT_LOG(*fileContext,DLT_LOG_INFO,
412 DLT_UINT(getFileSerialNumber(filename)),
414 DLT_RAW(buffer,readBytes),
427 dlt_user_log_file_errorMessage(fileContext,filename,DLT_FILETRANSFER_ERROR_FILE_DATA);
428 return DLT_FILETRANSFER_ERROR_FILE_DATA;
432 //!Transfer the end of the file as a dlt logs.
433 /**The end of the file must be logged to dlt because the end contains inforamtion about the file serial number.
434 * This informations is needed from the plugin of the dlt viewer.
435 * See the Mainpages.c for more informations.
436 * @param fileContext Specific context to log the file to dlt
437 * @param filename Absolute file path
438 * @param deleteFlag Flag to delete the file after the whole file is transferred (logged to dlt).1->delete,0->NotDelete
439 * @return Returns 0 if everything was okey. If there was a failure a value < 0 will be returned.
441 int dlt_user_log_file_end(DltContext *fileContext,const char *filename,int deleteFlag){
446 DLT_LOG(*fileContext,DLT_LOG_INFO,
448 DLT_UINT(getFileSerialNumber(filename)),
453 if( doRemoveFile(filename) != 0 ){
454 dlt_user_log_file_errorMessage(fileContext,filename,DLT_FILETRANSFER_ERROR_FILE_END);
461 dlt_user_log_file_errorMessage(fileContext,filename,DLT_FILETRANSFER_ERROR_FILE_END);
462 return DLT_FILETRANSFER_ERROR_FILE_END;