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.
9 //! Error code for dlt_user_log_file_complete
10 #define ERROR_FILE_COMPLETE -300
11 //! Error code for dlt_user_log_file_complete
12 #define ERROR_FILE_COMPLETE1 -301
13 //! Error code for dlt_user_log_file_complete
14 #define ERROR_FILE_COMPLETE2 -302
15 //! Error code for dlt_user_log_file_complete
16 #define ERROR_FILE_COMPLETE3 -303
17 //! Error code for dlt_user_log_file_head
18 #define ERROR_FILE_HEAD -400
19 //! Error code for dlt_user_log_file_data
20 #define ERROR_FILE_DATA -500
21 //! Error code for dlt_user_log_file_end
22 #define ERROR_FILE_END -600
23 //! Error code for dlt_user_log_file_infoAbout
24 #define ERROR_INFO_ABOUT -700
25 //! Error code for dlt_user_log_file_packagesCount
26 #define ERROR_PACKAGE_COUNT -800
29 //!Buffer for dlt file transfer. The size is defined by BUFFER_SIZE
30 unsigned char buffer[BUFFER_SIZE];
33 //!Get some information about the file size of a file
34 /**See stat(2) for more informations.
35 * @param file Absolute file path
36 * @return Returns the size of the file (if it is a regular file or a symbolic link) in bytes.
38 unsigned long getFilesize(const char* file){
41 return (unsigned long)st.st_size;
44 //!Get some information about the file serial number of a file
45 /** See stat(2) for more informations.
46 * @param file Absolute file path
47 * @return Returns a unique number associated with each filename
49 unsigned long getFileSerialNumber(const char* file){
52 return (unsigned long)st.st_ino;
55 //!Returns the creation date of a file
56 /** See stat(2) for more informations.
57 * @param file Absolute file path
58 * @return Returns the creation date of a file
60 time_t getFileCreationDate(const char* file){
66 //!Returns the creation date of a file
67 /** Format of the creation date is Day Mon dd hh:mm:ss yyyy
68 * @param file Absolute file path
69 * @return Returns the creation date of a file
71 char* getFileCreationDate2(const char* file){
75 struct tm *ts= localtime(&st.st_ctime);
79 //!Checks if the file exists
80 /**@param file Absolute file path
81 * @return Returns 1 if the file exists, 0 if the file does not exist
83 int isFile (const char* file)
86 return (stat (file, &st) == 0);
89 //!Waits a period of time
90 /**Waits a period of time. The minimal time to wait is MIN_TIMEOUT. This makes sure that the FIFO of dlt is not flooded.
91 * @param timeout Timeout to wait in seconds in ms but can not be smaller as MIN_TIMEOUT
93 void doTimeout(int timeout)
95 int total_size, used_size;
97 dlt_user_check_buffer(&total_size, &used_size);
99 /* sleep only if more than 50% of buffer used */
100 if((total_size - used_size) < (total_size/2))
102 printf("Wait %d of %d already used\n",used_size,total_size);
104 if(timeout>MIN_TIMEOUT)
106 usleep(timeout * 1000);
110 usleep(MIN_TIMEOUT * 1000);
115 //!Deletes the given file
117 * @param filename Absolute file path
118 * @return If the file is successfully deleted, a zero value is returned.If the file can not be deleted a nonzero value is returned.
120 int doRemoveFile(const char*filename){
121 return remove( filename);
124 void dlt_user_log_file_errorMessage(DltContext *fileContext, const char *filename, int errorCode){
128 DLT_LOG(*fileContext,DLT_LOG_ERROR,
132 DLT_UINT(getFileSerialNumber(filename)),
133 DLT_STRING(filename),
134 DLT_UINT(getFilesize(filename)),
135 DLT_STRING(getFileCreationDate2(filename)),
136 DLT_UINT(dlt_user_log_file_packagesCount(fileContext,filename)),
137 DLT_UINT(BUFFER_SIZE),
141 DLT_LOG(*fileContext,DLT_LOG_ERROR,
145 DLT_STRING(filename),
153 //!Logs specific file inforamtions to dlt
154 /**The filename, file size, file serial number and the number of packages will be logged to dlt.
155 * @param fileContext Specific context
156 * @param filename Absolute file path
157 * @return Returns 0 if everything was okey.If there was a failure a value < 0 will be returned.
159 int dlt_user_log_file_infoAbout(DltContext *fileContext, const char *filename){
163 DLT_LOG(*fileContext,DLT_LOG_INFO,
165 DLT_STRING("file serialnumber"),DLT_UINT(getFileSerialNumber(filename)),
166 DLT_STRING("filename"),DLT_STRING(filename),
167 DLT_STRING("file size in bytes"),DLT_UINT(getFilesize(filename)),
168 DLT_STRING("file creation date"),DLT_STRING(getFileCreationDate2(filename)),
169 DLT_STRING("number of packages"),DLT_UINT(dlt_user_log_file_packagesCount(fileContext, filename)),
174 dlt_user_log_file_errorMessage(fileContext,filename,ERROR_INFO_ABOUT);
175 return ERROR_INFO_ABOUT;
179 //!Transfer the complete file as several dlt logs.
180 /**This method transfer the complete file as several dlt logs. At first it will be checked that the file exist.
181 * In the next step some generic informations about the file will be logged to dlt.
182 * Now the header will be logged to dlt. See the method dlt_user_log_file_header for more informations.
183 * Then the method dlt_user_log_data will be called with the parameter to log all packages in a loop with some timeout.
184 * 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.
185 * @param fileContext Specific context to log the file to dlt
186 * @param filename Absolute file path
187 * @param deleteFlag Flag if the file will be deleted after transfer. 1->delete, 0->notDelete
188 * @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.
189 * @return Returns 0 if everything was okey. If there was a failure a value < 0 will be returned.
191 int dlt_user_log_file_complete(DltContext *fileContext, const char *filename, int deleteFlag, int timeout)
193 if(!isFile(filename))
195 dlt_user_log_file_errorMessage(fileContext,filename, ERROR_FILE_COMPLETE);
196 return ERROR_FILE_COMPLETE;
199 if(dlt_user_log_file_header(fileContext,filename) != 0)
201 return ERROR_FILE_COMPLETE1;
204 if(dlt_user_log_file_data(fileContext, filename,LONG_MAX,timeout) != 0)
206 return ERROR_FILE_COMPLETE2;
209 if(dlt_user_log_file_end(fileContext,filename, deleteFlag) != 0)
211 return ERROR_FILE_COMPLETE3;
217 //!This method gives information about the number of packages the file have
218 /**Every file will be divided into several packages. Every package will be logged as a single dlt log.
219 * The number of packages depends on the BUFFER_SIZE.
220 * At first it will be checked if the file exist. Then the file will be divided into
221 * several packages depending on the buffer size.
222 * @param fileContext Specific context to log the file to dlt
223 * @param filename Absolute file path
224 * @return Returns the number of packages if everything was okey. If there was a failure a value < 0 will be returned.
226 int dlt_user_log_file_packagesCount(DltContext *fileContext, const char *filename){
233 filesize = getFilesize(filename);
234 if(filesize < BUFFER_SIZE)
240 packages = filesize/BUFFER_SIZE;
242 if(filesize%BUFFER_SIZE == 0)
252 dlt_user_log_file_errorMessage(fileContext,filename,ERROR_PACKAGE_COUNT);
257 //!Transfer the head of the file as a dlt logs.
258 /**The head of the file must be logged to dlt because the head contains inforamtion about the file serial number,
259 * the file name, the file size, package number the file have and the buffer size.
260 * All these informations are needed from the plugin of the dlt viewer.
261 * See the Mainpages.c for more informations.
262 * @param fileContext Specific context to log the file to dlt
263 * @param filename Absolute file path
264 * @return Returns 0 if everything was okey. If there was a failure a value < 0 will be returned.
266 int dlt_user_log_file_header(DltContext *fileContext,const char *filename){
270 DLT_LOG(*fileContext,DLT_LOG_INFO,
272 DLT_UINT(getFileSerialNumber(filename)),
273 DLT_STRING(filename),
274 DLT_UINT(getFilesize(filename)),
275 DLT_STRING(getFileCreationDate2(filename));
276 DLT_UINT(dlt_user_log_file_packagesCount(fileContext,filename)),
277 DLT_UINT(BUFFER_SIZE),
285 dlt_user_log_file_errorMessage(fileContext,filename, ERROR_FILE_HEAD);
286 return ERROR_FILE_HEAD;
290 //!Transfer the content data of a file.
291 /**See the Mainpages.c for more informations.
292 * @param fileContext Specific context to log the file to dlt
293 * @param filename Absolute file path
294 * @param packageToTransfer Package number to transfer. If this param is LONG_MAX, the whole file will be transferred with a specific timeout
295 * @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.
296 * @return Returns 0 if everything was okey. If there was a failure a value < 0 will be returned.
298 int dlt_user_log_file_data(DltContext *fileContext,const char *filename, int packageToTransfer, int timeout){
306 file = fopen (filename,"rb");
309 dlt_user_log_file_errorMessage(fileContext,filename,ERROR_FILE_DATA);
310 return ERROR_FILE_DATA;
313 if( (packageToTransfer != LONG_MAX && packageToTransfer > dlt_user_log_file_packagesCount(fileContext,filename)) || packageToTransfer <= 0)
315 DLT_LOG(*fileContext,DLT_LOG_ERROR,
316 DLT_STRING("Error at dlt_user_log_file_data: packageToTransfer out of scope"),
317 DLT_STRING("packageToTransfer:"),
318 DLT_UINT(packageToTransfer),
319 DLT_STRING("numberOfMaximalPackages:"),
320 DLT_UINT(dlt_user_log_file_packagesCount(fileContext,filename)),
321 DLT_STRING("for File:"),
324 return ERROR_FILE_DATA;
329 if(packageToTransfer != LONG_MAX)
331 fseek ( file , (packageToTransfer-1)*BUFFER_SIZE , SEEK_SET );
332 readBytes = fread(buffer, sizeof(char), BUFFER_SIZE, file);
334 DLT_LOG(*fileContext,DLT_LOG_INFO,
336 DLT_UINT(getFileSerialNumber(filename)),
337 DLT_UINT(packageToTransfer),
338 DLT_RAW(buffer,readBytes),
342 //doTimeout(timeout);
346 while( !feof( file ) )
349 readBytes = fread(buffer, sizeof(char), BUFFER_SIZE, file);
351 DLT_LOG(*fileContext,DLT_LOG_INFO,
353 DLT_UINT(getFileSerialNumber(filename)),
355 DLT_RAW(buffer,readBytes),
359 //doTimeout(timeout);
368 dlt_user_log_file_errorMessage(fileContext,filename,ERROR_FILE_DATA);
369 return ERROR_FILE_DATA;
373 //!Transfer the end of the file as a dlt logs.
374 /**The end of the file must be logged to dlt because the end contains inforamtion about the file serial number.
375 * This informations is needed from the plugin of the dlt viewer.
376 * See the Mainpages.c for more informations.
377 * @param fileContext Specific context to log the file to dlt
378 * @param filename Absolute file path
379 * @param deleteFlag Flag to delete the file after the whole file is transferred (logged to dlt).1->delete,0->NotDelete
380 * @return Returns 0 if everything was okey. If there was a failure a value < 0 will be returned.
382 int dlt_user_log_file_end(DltContext *fileContext,const char *filename,int deleteFlag){
387 DLT_LOG(*fileContext,DLT_LOG_INFO,
389 DLT_UINT(getFileSerialNumber(filename)),
394 if( doRemoveFile(filename) != 0 ){
395 dlt_user_log_file_errorMessage(fileContext,filename,ERROR_FILE_END);
402 dlt_user_log_file_errorMessage(fileContext,filename,ERROR_FILE_END);
403 return ERROR_FILE_END;