summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlexander Wenzel <Alexander.AW.Wenzel@bmw.de>2011-09-29 13:36:57 +0200
committerAlexander Wenzel <Alexander.AW.Wenzel@bmw.de>2011-09-29 13:36:57 +0200
commit8fd55260f1d572939f185e014aef34a53b50de8b (patch)
tree88ab496b6e7b6f24ea8f502f5594a003c6472f40 /src
parent966bffa7397f0479640f2232c6a2d1667026952e (diff)
downloadDLT-daemon-8fd55260f1d572939f185e014aef34a53b50de8b.tar.gz
Add Filetransfer feature to DLT user library.
Added missing offline trace files.
Diffstat (limited to 'src')
-rwxr-xr-xsrc/lib/CMakeLists.txt2
-rw-r--r--src/lib/dlt_filetransfer.c406
-rw-r--r--src/shared/dlt_offline_trace.c246
-rwxr-xr-xsrc/tests/CMakeLists.txt8
-rw-r--r--src/tests/dlt-test-filetransfer.c340
5 files changed, 1001 insertions, 1 deletions
diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt
index 1d33d21..7956e1f 100755
--- a/src/lib/CMakeLists.txt
+++ b/src/lib/CMakeLists.txt
@@ -35,7 +35,7 @@
# @licence end@
########
-set(dlt_LIB_SRCS dlt_user dlt_client ${CMAKE_SOURCE_DIR}/src/shared/dlt_common.c ${CMAKE_SOURCE_DIR}/src/shared/dlt_user_shared.c ${CMAKE_SOURCE_DIR}/src/shared/dlt_shm.c)
+set(dlt_LIB_SRCS dlt_user dlt_client dlt_filetransfer ${CMAKE_SOURCE_DIR}/src/shared/dlt_common.c ${CMAKE_SOURCE_DIR}/src/shared/dlt_user_shared.c ${CMAKE_SOURCE_DIR}/src/shared/dlt_shm.c)
add_library(dlt ${dlt_LIB_SRCS})
diff --git a/src/lib/dlt_filetransfer.c b/src/lib/dlt_filetransfer.c
new file mode 100644
index 0000000..a78c418
--- /dev/null
+++ b/src/lib/dlt_filetransfer.c
@@ -0,0 +1,406 @@
+#include "dlt_filetransfer.h"
+
+//!Defines the buffer size of a single file package which will be logged to dlt
+#define BUFFER_SIZE 1024
+
+//!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.
+#define MIN_TIMEOUT 20
+
+
+#define ERROR_FILE_COMPLETE -300
+#define ERROR_FILE_COMPLETE1 -301
+#define ERROR_FILE_COMPLETE2 -302
+#define ERROR_FILE_COMPLETE3 -303
+#define ERROR_FILE_HEAD -400
+#define ERROR_FILE_DATA -500
+#define ERROR_FILE_END -600
+#define ERROR_INFO_ABOUT -700
+#define ERROR_PACKAGE_COUNT -800
+
+
+//!Buffer for dlt file transfer. The size is defined by BUFFER_SIZE
+unsigned char buffer[BUFFER_SIZE];
+
+
+//!Get some information about the file size of a file
+/**See stat(2) for more informations.
+ * @param file Absolute file path
+ * @return Returns the size of the file (if it is a regular file or a symbolic link) in bytes.
+ */
+unsigned long getFilesize(const char* file){
+ struct stat st;
+ stat(file, &st);
+ return (unsigned long)st.st_size;
+}
+
+//!Get some information about the file serial number of a file
+/** See stat(2) for more informations.
+ * @param file Absolute file path
+ * @return Returns a unique number associated with each filename
+ */
+unsigned long getFileSerialNumber(const char* file){
+ struct stat st;
+ stat(file, &st);
+ return (unsigned long)st.st_ino;
+}
+
+//!Returns the creation date of a file
+/** See stat(2) for more informations.
+ * @param file Absolute file path
+ * @return Returns the creation date of a file
+*/
+time_t getFileCreationDate(const char* file){
+ struct stat st;
+ stat(file, &st);
+ return st.st_ctime;
+}
+char* getFileCreationDate2(const char* file){
+ struct stat st;
+ stat(file, &st);
+
+ struct tm *ts= localtime(&st.st_ctime);
+ //char buf[80];
+ /* Format and print the time, "ddd yyyy-mm-dd hh:mm:ss zzz" */
+ //strftime(buf, sizeof(buf), "%a %Y-%m-%d %H:%M:%S %Z", ts);
+ return asctime(ts);
+}
+
+
+
+
+//void sighandler(int sig)
+//{
+//
+// fprintf(stderr, "Signal handler called with %d\n", sig);
+// signal(sig, &sighandler);
+// exit(1);
+//
+//}
+
+
+
+//!Checks if the file exists
+/**@param file Absolute file path
+ * @return Returns 1 if the file exists, 0 if the file does not exist
+ */
+int isFile (const char* file)
+{
+ struct stat st;
+ return (stat (file, &st) == 0);
+}
+
+//!Waits a period of time
+/**Waits a period of time. The minimal time to wait is MIN_TIMEOUT. This makes sure that the FIFO of dlt is not flooded.
+ * @param timeout Timeout to wait in seconds in ms but can not be smaller as MIN_TIMEOUT
+ */
+void doTimeout(int timeout)
+{
+ if(timeout>MIN_TIMEOUT)
+ {
+ usleep(timeout * 1000);
+ }
+ else
+ {
+ usleep(MIN_TIMEOUT * 1000);
+ }
+}
+
+//!Deletes the given file
+/**
+ * @param filename Absolute file path
+ * @return If the file is successfully deleted, a zero value is returned.If the file can not be deleted a nonzero value is returned.
+ */
+int doRemoveFile(const char*filename){
+ return remove( filename);
+}
+
+void dlt_user_log_file_errorMessage(DltContext *fileContext, const char *filename, int errorCode){
+
+ if(-errno != -2)
+ {
+ DLT_LOG(*fileContext,DLT_LOG_ERROR,
+ DLT_STRING("FLER"),
+ DLT_INT(errorCode),
+ DLT_INT(-errno),
+ DLT_UINT(getFileSerialNumber(filename)),
+ DLT_STRING(filename),
+ DLT_UINT(getFilesize(filename)),
+ DLT_STRING(getFileCreationDate2(filename)),
+ DLT_UINT(dlt_user_log_file_packagesCount(fileContext,filename)),
+ DLT_UINT(BUFFER_SIZE),
+ DLT_STRING("FLER")
+ );
+ } else {
+ DLT_LOG(*fileContext,DLT_LOG_ERROR,
+ DLT_STRING("FLER"),
+ DLT_INT(errorCode),
+ DLT_INT(-errno),
+ DLT_STRING(filename),
+ DLT_STRING("FLER")
+ );
+ }
+}
+
+
+
+//!Logs specific file inforamtions to dlt
+/**The filename, file size, file serial number and the number of packages will be logged to dlt.
+ * @param fileContext Specific context
+ * @param filename Absolute file path
+ * @return Returns 0 if everything was okey.If there was a failure a value < 0 will be returned.
+ */
+int dlt_user_log_file_infoAbout(DltContext *fileContext, const char *filename){
+
+ if(isFile(filename))
+ {
+ DLT_LOG(*fileContext,DLT_LOG_INFO,
+ DLT_STRING("FLIF"),
+ DLT_STRING("file serialnumber"),DLT_UINT(getFileSerialNumber(filename)),
+ DLT_STRING("filename"),DLT_STRING(filename),
+ DLT_STRING("file size in bytes"),DLT_UINT(getFilesize(filename)),
+ DLT_STRING("file creation date"),DLT_STRING(getFileCreationDate2(filename)),
+ DLT_STRING("number of packages"),DLT_UINT(dlt_user_log_file_packagesCount(fileContext, filename)),
+ DLT_STRING("FLIF")
+ );
+ return 0;
+ } else {
+
+ dlt_user_log_file_errorMessage(fileContext,filename,ERROR_INFO_ABOUT);
+ return ERROR_INFO_ABOUT;
+ }
+}
+
+//!Transfer the complete file as several dlt logs.
+/**This method transfer the complete file as several dlt logs. At first it will be checked that the file exist.
+ * In the next step some generic informations about the file will be logged to dlt.
+ * Now the header will be logged to dlt. See the method dlt_user_log_file_header for more informations.
+ * Then the method dlt_user_log_data will be called with the parameter to log all packages in a loop with some timeout.
+ * 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.
+ * @param fileContext Specific context to log the file to dlt
+ * @param filename Absolute file path
+ * @param deleteFlag Flag if the file will be deleted after transfer. 1->delete, 0->notDelete
+ * @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.
+ * @return Returns 0 if everything was okey. If there was a failure a value < 0 will be returned.
+ */
+int dlt_user_log_file_complete(DltContext *fileContext, const char *filename, int deleteFlag, int timeout)
+{
+ //No signal handling in library - part of the main program!
+ //signal(SIGABRT, &sighandler);
+ //signal(SIGTERM, &sighandler);
+ //signal(SIGINT, &sighandler);
+
+ if(!isFile(filename))
+ {
+ dlt_user_log_file_errorMessage(fileContext,filename, ERROR_FILE_COMPLETE);
+ return ERROR_FILE_COMPLETE;
+ }
+
+ //dlt_user_log_file_infoAbout(fileContext,filename);
+
+ if(dlt_user_log_file_header(fileContext,filename) != 0)
+ {
+ return ERROR_FILE_COMPLETE1;
+ }
+
+ if(dlt_user_log_file_data(fileContext, filename,LONG_MAX,timeout) != 0)
+ {
+ return ERROR_FILE_COMPLETE2;
+ }
+
+ if(dlt_user_log_file_end(fileContext,filename, deleteFlag) != 0)
+ {
+ return ERROR_FILE_COMPLETE3;
+ }
+
+ return 0;
+}
+
+//!This method gives information about the number of packages the file have
+/**Every file will be divided into several packages. Every package will be logged as a single dlt log.
+ * The number of packages depends on the BUFFER_SIZE.
+ * At first it will be checked if the file exist. Then the file will be divided into
+ * several packages depending on the buffer size.
+ * @param fileContext Specific context to log the file to dlt
+ * @param filename Absolute file path
+ * @return Returns the number of packages if everything was okey. If there was a failure a value < 0 will be returned.
+ */
+int dlt_user_log_file_packagesCount(DltContext *fileContext, const char *filename){
+ int packages;
+ long filesize;
+
+ if(isFile(filename))
+ {
+ packages = 1;
+ filesize = getFilesize(filename);
+ if(filesize < BUFFER_SIZE)
+ {
+ return packages;
+ }
+ else
+ {
+ packages = filesize/BUFFER_SIZE;
+
+ if(filesize%BUFFER_SIZE == 0)
+ {
+ return packages;
+ }
+ else
+ {
+ return packages+1;
+ }
+ }
+ } else {
+ dlt_user_log_file_errorMessage(fileContext,filename,ERROR_PACKAGE_COUNT);
+ return -1;
+ }
+}
+
+//!Transfer the head of the file as a dlt logs.
+/**The head of the file must be logged to dlt because the head contains inforamtion about the file serial number,
+ * the file name, the file size, package number the file have and the buffer size.
+ * All these informations are needed from the plugin of the dlt viewer.
+ * See the Mainpages.c for more informations.
+ * @param fileContext Specific context to log the file to dlt
+ * @param filename Absolute file path
+ * @return Returns 0 if everything was okey. If there was a failure a value < 0 will be returned.
+ */
+int dlt_user_log_file_header(DltContext *fileContext,const char *filename){
+
+ if(isFile(filename))
+ {
+ DLT_LOG(*fileContext,DLT_LOG_INFO,
+ DLT_STRING("FLST"),
+ DLT_UINT(getFileSerialNumber(filename)),
+ DLT_STRING(filename),
+ DLT_UINT(getFilesize(filename)),
+ DLT_STRING(getFileCreationDate2(filename));
+ DLT_UINT(dlt_user_log_file_packagesCount(fileContext,filename)),
+ DLT_UINT(BUFFER_SIZE),
+ DLT_STRING("FLST")
+ );
+
+ return 0;
+ }
+ else
+ {
+ dlt_user_log_file_errorMessage(fileContext,filename, ERROR_FILE_HEAD);
+ return ERROR_FILE_HEAD;
+ }
+}
+
+//!Transfer the content data of a file.
+/**See the Mainpages.c for more informations.
+ * @param fileContext Specific context to log the file to dlt
+ * @param filename Absolute file path
+ * @param packageToTransfer Package number to transfer. If this param is LONG_MAX, the whole file will be transferred with a specific timeout
+ * @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.
+ * @return Returns 0 if everything was okey. If there was a failure a value < 0 will be returned.
+ */
+int dlt_user_log_file_data(DltContext *fileContext,const char *filename, int packageToTransfer, int timeout){
+ FILE *file;
+ int i,pkgNumber;
+ long positionIndicator,readBytes;
+
+ if(isFile(filename))
+ {
+
+ file = fopen (filename,"rb");
+ if (file == NULL)
+ {
+ dlt_user_log_file_errorMessage(fileContext,filename,ERROR_FILE_DATA);
+ return ERROR_FILE_DATA;
+ }
+
+ if( (packageToTransfer != LONG_MAX && packageToTransfer > dlt_user_log_file_packagesCount(fileContext,filename)) || packageToTransfer <= 0)
+ {
+ DLT_LOG(*fileContext,DLT_LOG_ERROR,
+ DLT_STRING("Error at dlt_user_log_file_data: packageToTransfer out of scope"),
+ DLT_STRING("packageToTransfer:"),
+ DLT_UINT(packageToTransfer),
+ DLT_STRING("numberOfMaximalPackages:"),
+ DLT_UINT(dlt_user_log_file_packagesCount(fileContext,filename)),
+ DLT_STRING("for File:"),
+ DLT_STRING(filename)
+ );
+ return ERROR_FILE_DATA;
+ }
+
+ readBytes = 0;
+
+ if(packageToTransfer != LONG_MAX)
+ {
+ fseek ( file , (packageToTransfer-1)*BUFFER_SIZE , SEEK_SET );
+ readBytes = fread(buffer, sizeof(char), BUFFER_SIZE, file);
+
+ DLT_LOG(*fileContext,DLT_LOG_INFO,
+ DLT_STRING("FLDA"),
+ DLT_UINT(getFileSerialNumber(filename)),
+ DLT_UINT(packageToTransfer),
+ DLT_RAW(buffer,readBytes),
+ DLT_STRING("FLDA")
+ );
+
+ doTimeout(timeout);
+
+ } else {
+ pkgNumber = 0;
+ while( !feof( file ) )
+ {
+ pkgNumber++;
+ readBytes = fread(buffer, sizeof(char), BUFFER_SIZE, file);
+
+ DLT_LOG(*fileContext,DLT_LOG_INFO,
+ DLT_STRING("FLDA"),
+ DLT_UINT(getFileSerialNumber(filename)),
+ DLT_UINT(pkgNumber),
+ DLT_RAW(buffer,readBytes),
+ DLT_STRING("FLDA")
+ );
+
+ doTimeout(timeout);
+ }
+ }
+
+ fclose(file);
+
+ return 0;
+
+ } else {
+ dlt_user_log_file_errorMessage(fileContext,filename,ERROR_FILE_DATA);
+ return ERROR_FILE_DATA;
+ }
+
+}
+//!Transfer the end of the file as a dlt logs.
+/**The end of the file must be logged to dlt because the end contains inforamtion about the file serial number.
+ * This informations is needed from the plugin of the dlt viewer.
+ * See the Mainpages.c for more informations.
+ * @param fileContext Specific context to log the file to dlt
+ * @param filename Absolute file path
+ * @param deleteFlag Flag to delete the file after the whole file is transferred (logged to dlt).1->delete,0->NotDelete
+ * @return Returns 0 if everything was okey. If there was a failure a value < 0 will be returned.
+ */
+int dlt_user_log_file_end(DltContext *fileContext,const char *filename,int deleteFlag){
+
+ if(isFile(filename))
+ {
+
+ DLT_LOG(*fileContext,DLT_LOG_INFO,
+ DLT_STRING("FLFI"),
+ DLT_UINT(getFileSerialNumber(filename)),
+ DLT_STRING("FLFI")
+ );
+
+ if(deleteFlag){
+ if( doRemoveFile(filename) != 0 ){
+ dlt_user_log_file_errorMessage(fileContext,filename,ERROR_FILE_END);
+ return -1;
+ }
+ }
+
+ return 0;
+ }else{
+ dlt_user_log_file_errorMessage(fileContext,filename,ERROR_FILE_END);
+ return ERROR_FILE_END;
+ }
+}
diff --git a/src/shared/dlt_offline_trace.c b/src/shared/dlt_offline_trace.c
new file mode 100644
index 0000000..5f7f5b5
--- /dev/null
+++ b/src/shared/dlt_offline_trace.c
@@ -0,0 +1,246 @@
+/*
+* Dlt- Diagnostic Log and Trace user library
+* @licence app begin@
+ *
+ * Copyright (C) 2011, BMW AG - Alexander Wenzel <alexander.wenzel@bmw.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under the terms of the
+ * GNU Lesser General Public License, version 2.1, as published by the Free Software Foundation.
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
+ * Public License, version 2.1, for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License, version 2.1, along
+ * with this program; if not, see <http://www.gnu.org/licenses/lgpl-2.1.html>.
+ *
+ * Note that the copyright holders assume that the GNU Lesser General Public License, version 2.1, may
+ * also be applicable to programs even in cases in which the program is not a library in the technical sense.
+ *
+ * Linking DLT statically or dynamically with other modules is making a combined work based on DLT. You may
+ * license such other modules under the GNU Lesser General Public License, version 2.1. If you do not want to
+ * license your linked modules under the GNU Lesser General Public License, version 2.1, you
+ * may use the program under the following exception.
+ *
+ * As a special exception, the copyright holders of DLT give you permission to combine DLT
+ * with software programs or libraries that are released under any license unless such a combination is not
+ * permitted by the license of such a software program or library. You may copy and distribute such a
+ * system following the terms of the GNU Lesser General Public License, version 2.1, including this
+ * special exception, for DLT and the licenses of the other code concerned.
+ *
+ * Note that people who make modified versions of DLT are not obligated to grant this special exception
+ * for their modified versions; it is their choice whether to do so. The GNU Lesser General Public License,
+ * version 2.1, gives permission to release a modified version without this exception; this exception
+ * also makes it possible to release a modified version which carries forward this exception.
+ *
+ * @licence end@
+*/
+
+
+/*******************************************************************************
+** **
+** SRC-MODULE: dlt_offline_trace.c **
+** **
+** TARGET : linux **
+** **
+** PROJECT : DLT **
+** **
+** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de **
+** **
+** PURPOSE : **
+** **
+** REMARKS : **
+** **
+** PLATFORM DEPENDANT [yes/no]: yes **
+** **
+** TO BE CHANGED BY USER [yes/no]: no **
+** **
+*******************************************************************************/
+
+/*******************************************************************************
+** Author Identity **
+********************************************************************************
+** **
+** Initials Name Company **
+** -------- ------------------------- ---------------------------------- **
+** aw Alexander Wenzel BMW **
+*******************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <dirent.h>
+
+#include <dlt_offline_trace.h>
+
+int dlt_offline_trace_create_new_file(DltOfflineTrace *trace) {
+ time_t t;
+ struct tm *tmp;
+ char outstr[200];
+
+ /* set filename */
+ t = time(NULL);
+ tmp = localtime(&t);
+ if (tmp == NULL) {
+ }
+ if (strftime(outstr, sizeof(outstr),"%Y%m%d_%H%M%S", tmp) == 0) {
+ }
+ sprintf(trace->filename,"%s/entrynav_%s.dlt",trace->directory,outstr);
+
+ /* open DLT output file */
+ trace->ohandle = open(trace->filename,O_WRONLY|O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); /* mode: wb */
+ if (trace->ohandle == -1)
+ {
+ /* trace file cannot be opened */
+ printf("Offline trace file %s cannot be created\n",trace->filename);
+ return -1;
+ } /* if */
+
+ return 0; /* OK */
+}
+
+unsigned long dlt_offline_trace_get_total_size(DltOfflineTrace *trace) {
+ struct dirent *dp;
+ char filename[256];
+ unsigned long size = 0;
+ struct stat status;
+
+ /* go through all dlt files in directory */
+ DIR *dir = opendir(trace->directory);
+ while ((dp=readdir(dir)) != NULL) {
+ if(strstr(dp->d_name,".dlt")) {
+ sprintf(filename,"%s/%s",trace->directory,dp->d_name);
+ stat(filename,&status);
+ size += status.st_size;
+ }
+ }
+ closedir(dir);
+
+ /* return size */
+ return size;
+}
+
+int dlt_offline_trace_delete_oldest_file(DltOfflineTrace *trace) {
+ struct dirent *dp;
+ char filename[256];
+ char filename_oldest[256];
+ unsigned long size_oldest = 0;
+ struct stat status;
+ time_t time_oldest = 0;
+
+ filename[0] = 0;
+ filename_oldest[0] = 0;
+
+ /* go through all dlt files in directory */
+ DIR *dir = opendir(trace->directory);
+ while ((dp=readdir(dir)) != NULL) {
+ if(strstr(dp->d_name,".dlt")) {
+ sprintf(filename,"%s/%s",trace->directory,dp->d_name);
+ stat(filename,&status);
+ if(time_oldest == 0 || status.st_mtime < time_oldest) {
+ time_oldest = status.st_mtime;
+ size_oldest = status.st_size;
+ strcpy(filename_oldest,filename);
+ }
+ }
+ }
+ closedir(dir);
+
+ /* delete file */
+ if(filename_oldest[0]) {
+ if(remove(filename_oldest)) {
+ printf("Remove file %s failed!\n",filename_oldest);
+ return -1; /* ERROR */
+ }
+ }
+ else {
+ printf("No file to be removed!\n");
+ return -1; /* ERROR */
+ }
+
+ /* return size of deleted file*/
+ return size_oldest;
+}
+
+int dlt_offline_trace_check_size(DltOfflineTrace *trace) {
+
+ /* check size of complete offline trace */
+ while(dlt_offline_trace_get_total_size(trace) > (trace->maxSize-trace->fileSize))
+ {
+ /* remove oldest files as long as new file will not fit in completely into complete offline trace */
+ if(dlt_offline_trace_delete_oldest_file(trace)<0) {
+ return -1;
+ }
+ }
+
+ return 0; /* OK */
+}
+
+int dlt_offline_trace_init(DltOfflineTrace *trace,const char *directory,int fileSize,int maxSize) {
+
+ /* init parameters */
+ strcpy(trace->directory,directory);
+ trace->fileSize = fileSize;
+ trace->maxSize = maxSize;
+
+ /* check complete offlien trace size, remove old logs if needed */
+ dlt_offline_trace_check_size(trace);
+
+ return dlt_offline_trace_create_new_file(trace);
+}
+
+int dlt_offline_trace_write(DltOfflineTrace *trace,unsigned char *data1,int size1,unsigned char *data2,int size2,unsigned char *data3,int size3) {
+
+ if(trace->ohandle <= 0)
+ return -1;
+
+ /* check file size here */
+ if((lseek(trace->ohandle,0,SEEK_CUR)+size1+size2+size3)>=trace->fileSize)
+ {
+ /* close old file */
+ close(trace->ohandle);
+
+ /* check complete offline trace size, remove old logs if needed */
+ dlt_offline_trace_check_size(trace);
+
+ /* create new file */
+ dlt_offline_trace_create_new_file(trace);
+ }
+
+ /* write data into log file */
+ if(data1) {
+ if(write(trace->ohandle,data1,size1)!=size1) {
+ printf("Offline trace write failed!\n");
+ return -1;
+ }
+ }
+ if(data2) {
+ if(write(trace->ohandle,data2,size2)!=size2) {
+ printf("Offline trace write failed!\n");
+ return -1;
+ }
+ }
+ if(data3) {
+ if(write(trace->ohandle,data3,size3)!=size3) {
+ printf("Offline trace write failed!\n");
+ return -1;
+ }
+ }
+
+ return 0; /* OK */
+}
+
+int dlt_offline_trace_free(DltOfflineTrace *trace) {
+
+ if(trace->ohandle <= 0)
+ return -1;
+
+ /* close last used log file */
+ close(trace->ohandle);
+
+ return 0; /* OK */
+}
diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt
index 16a4f93..94a931e 100755
--- a/src/tests/CMakeLists.txt
+++ b/src/tests/CMakeLists.txt
@@ -83,6 +83,14 @@ ENDIF(GPROF_DLT_TESTS)
target_link_libraries(dlt-test-internal dlt)
set_target_properties(dlt-test-internal PROPERTIES LINKER_LANGUAGE C)
+set(dlt_test_filetransfer_SRCS dlt-test-filetransfer)
+add_executable(dlt-test-filetransfer ${dlt_test_filetransfer_SRCS})
+IF(GPROF_DLT_TESTS)
+ SET(CMAKE_C_FLAGS "-pg")
+ENDIF(GPROF_DLT_TESTS)
+target_link_libraries(dlt-test-filetransfer dlt)
+set_target_properties(dlt-test-filetransfer PROPERTIES LINKER_LANGUAGE C)
+
install(TARGETS dlt-test-user dlt-test-client dlt-test-stress-user dlt-test-stress-client dlt-test-stress dlt-test-internal
RUNTIME DESTINATION bin
COMPONENT base)
diff --git a/src/tests/dlt-test-filetransfer.c b/src/tests/dlt-test-filetransfer.c
new file mode 100644
index 0000000..a3418eb
--- /dev/null
+++ b/src/tests/dlt-test-filetransfer.c
@@ -0,0 +1,340 @@
+#include <dlt_filetransfer.h> /*Needed for transferring files with the dlt protocol*/
+#include <dlt.h> /*Needed for dlt logging*/
+
+//!Declare some context for the main program. It's a must have to do this, when you want to log with dlt.
+DLT_DECLARE_CONTEXT(mainContext);
+
+//!Declare some context for the file transfer. It's not a must have to do this, but later you can set a filter on this context in the dlt viewer.
+DLT_DECLARE_CONTEXT(fileContext);
+
+//!Textfile which will be transferred.
+char *file1;
+//!Image which will be transferred.
+char *file2;
+//!Not existing file which will be transferred.
+char *file3;
+//!Just some variables
+int i,countPackages, transferResult, dltResult;
+
+
+//!Main program dlt-test-filestransfer starts here
+int main(void)
+{
+ //First file contains some text
+ file1 = "/usr/share/dlt-filetransfer/dlt-test-filetransfer-file";
+ //Second file is a picture
+ file2 = "/usr/share/dlt-filetransfer/dlt-test-filetransfer-image.png";
+ //Third file doesn't exist. Just to test the reaction when the file isn't available.
+ file3 = "/usr/share/dlt-filetransfer/dlt-test-filetransfer-doesntExist";
+
+
+ //Register the application at the dlt-daemon
+ dltResult = DLT_REGISTER_APP("FLTR","Test Application filetransfer");
+ if(dltResult < 0){
+ printf("Error: DLT_REIGSTER_APP: FLTR\n");
+ return -1;
+ }
+ //Register the context of the main program at the dlt-daemon
+ dltResult = DLT_REGISTER_CONTEXT(mainContext,"MAIN","Main context for filetransfer test");
+ if(dltResult < 0){
+ printf("Error: DLT_REGISTER_CONTEXT: MAIN\n");
+ return -1;
+ }
+ //Register the context in which the file transfer will be logged at the dlt-daemon
+ dltResult = DLT_REGISTER_CONTEXT(fileContext,"FLTR","Test Context for filetransfer");
+ if(dltResult < 0){
+ printf("Error: DLT_REGISTER_CONTEXT:FLTR\n");
+ return -1;
+ }
+ //More details in corresponding methods
+ if(testF1P1() >= 0){
+ printf("testF1P1 successful\n");
+ }
+ else
+ {
+ printf("testF1P1 failed\n");
+ }
+
+ if(testF1P2() >= 0){
+ printf("testF1P2 successful\n");
+ }
+ else
+ {
+ printf("testF1P2 failed\n");
+ }
+
+ if(testF2P1() >= 0){
+ printf("testF2P1 successful\n");
+ }
+ else
+ {
+ printf("testF2P1 failed\n");
+ }
+
+ if(testF2P2() >= 0){
+ printf("testF2P2 successful\n");
+ }
+ else
+ {
+ printf("testF2P2 failed\n");
+ }
+
+ if(testF3P1() < 0){
+ printf("testF3P1 successful\n");
+ }
+ else
+ {
+ printf("testF3P1 failed\n");
+ }
+
+ if(testF3P2() < 0){
+ printf("testF3P2 successful\n");
+ }
+ else
+ {
+ printf("testF3P2 failed\n");
+ }
+
+ if(testF3P3() < 0 ){
+ printf("testF3P3 successful\n");
+ }
+ else
+ {
+ printf("testF3P3 failed\n");
+ }
+
+
+ //Unregister the context in which the file transfer happened from the dlt-daemon
+ DLT_UNREGISTER_CONTEXT(fileContext);
+ //Unregister the context of the main program from the dlt-daemon
+ DLT_UNREGISTER_CONTEXT(mainContext);
+ //Unregister the app from the dlt-daemon
+ DLT_UNREGISTER_APP();
+
+ return(0);
+}
+
+//!Test the file transfer with the condition that the transferred file is smaller as the file transfer buffer using dlt_user_log_file_complete.
+int testF1P1(){
+ //Just some log to the main context
+ DLT_LOG(mainContext,DLT_LOG_INFO,DLT_STRING("Started testF1P1 - dlt_user_log_file_complete"),DLT_STRING(file1));
+
+ //Here's the line where the dlt file transfer is called. The method call needs a context, the absolute file path, will the file be deleted after transfer and the timeout between the packages
+ transferResult = dlt_user_log_file_complete(&fileContext,file1,0,20);
+ if(transferResult < 0 )
+ {
+ printf("Error: dlt_user_log_file_complete\n");
+ return transferResult;
+ }
+ //Just some log to the main context
+ DLT_LOG(mainContext,DLT_LOG_INFO,DLT_STRING("Finished testF1P1"),DLT_STRING(file1));
+
+ return transferResult;
+}
+
+//!Test the file transfer with the condition that the transferred file is smaller as the file transfer buffer using single package transfer
+int testF1P2(){
+
+ //Get the information how many packages have the file
+ countPackages = dlt_user_log_file_packagesCount(&fileContext,file1);
+ if(countPackages < 0 )
+ {
+ printf("Error: dlt_user_log_file_packagesCount\n");
+ return -1;
+ }
+ //Just some log to the main context
+ DLT_LOG(mainContext,DLT_LOG_INFO,DLT_STRING("Started testF1P2 - transfer single package"),DLT_STRING(file1));
+
+ //Logs the header of the file transfer. For more details see Mainpage.c.
+ //The header gives information about the file serial number, filename (with absolute path), filesize, packages of file, buffer size
+ transferResult = dlt_user_log_file_header(&fileContext,file1);
+ if(transferResult >= 0)
+ {
+ //Loop to log all packages
+ for(i=1;i<=countPackages;i++)
+ {
+ //Logs one single package to the file context
+ transferResult = dlt_user_log_file_data(&fileContext,file1,i,20);
+ if(transferResult < 0)
+ {
+ printf("Error: dlt_user_log_file_data\n");
+ return transferResult;
+ }
+ }
+
+ //Logs the end of the file transfer. For more details see Mainpage.c
+ //The end gives just information about the file serial number but is needed to signal that the file transfer has correctly finished and needed for the file transfer plugin of the dlt viewer.
+ transferResult = dlt_user_log_file_end(&fileContext,file1,0);
+ if(transferResult < 0)
+ {
+ printf("Error: dlt_user_log_file_end\n");
+ return transferResult;
+ }
+ }
+ else
+ {
+ printf("Error: dlt_user_log_file_header\n");
+ return transferResult;
+ }
+
+ //Just some log to main context
+ DLT_LOG(mainContext,DLT_LOG_INFO,DLT_STRING("Finished testF1P2 - transfer single package"),DLT_STRING(file1));
+
+ return 0;
+}
+//!Test the file transfer with the condition that the transferred file is bigger as the file transfer buffer using dlt_user_log_file_complete.
+int testF2P1(){
+ //Just some log to main context
+ DLT_LOG(mainContext,DLT_LOG_INFO,DLT_STRING("Started testF2P1 - dlt_user_log_file_complete"),DLT_STRING(file2));
+
+ //Here's the line where the dlt file transfer is called. The method call needs a context, the absolute file path, will the file be deleted after transfer and the timeout between the packages
+ transferResult = dlt_user_log_file_complete(&fileContext,file2,0,20);
+ if(transferResult < 0)
+ {
+ printf("Error: dlt_user_log_file_complete\n");
+ return transferResult;
+ }
+ //Just some log to main context
+ DLT_LOG(mainContext,DLT_LOG_INFO,DLT_STRING("Finished testF2P1"),DLT_STRING(file2));
+
+ return transferResult;
+}
+
+//!Test the file transfer with the condition that the transferred file is bigger as the file transfer buffer using single package transfer
+int testF2P2(){
+
+ //Get the information how many packages have the file
+ countPackages = dlt_user_log_file_packagesCount(&fileContext,file2);
+ if(countPackages < 0 )
+ {
+ printf("Error: dlt_user_log_file_packagesCount\n");
+ return -1;
+ }
+
+ //Just some log to the main context
+ DLT_LOG(mainContext,DLT_LOG_INFO,DLT_STRING("Started testF2P2 - transfer single package"),DLT_STRING(file2));
+
+ //Logs the header of the file transfer. For more details see Mainpage.c.
+ //The header gives information about the file serial number, filename (with absolute path), filesize, packages of file, buffer size
+ transferResult = dlt_user_log_file_header(&fileContext,file2);
+ if( transferResult >= 0){
+
+ //Loop to log all packages
+ for(i=1;i<=countPackages;i++)
+ {
+ //Logs one single package to the file context
+ transferResult = dlt_user_log_file_data(&fileContext,file2,i,20);
+ if(transferResult < 0)
+ {
+ printf("Error: dlt_user_log_file_data\n");
+ return transferResult;
+ }
+ }
+
+ //Logs the end of the file transfer. For more details see Mainpage.c
+ //The end gives just information about the file serial number but is needed to signal that the file transfer has correctly finished and needed for the file transfer plugin of the dlt viewer.
+ transferResult = dlt_user_log_file_end(&fileContext,file2,0);
+ if(transferResult < 0)
+ {
+ printf("Error: dlt_user_log_file_end\n");
+ return transferResult;
+ }
+ }
+ else
+ {
+ printf("Error: dlt_user_log_file_header\n");
+ return transferResult;
+ }
+ //Just some log to the main context
+ DLT_LOG(mainContext,DLT_LOG_INFO,DLT_STRING("Finished testF2P2"),DLT_STRING(file2));
+
+ return 0;
+}
+
+//!Test the file transfer with the condition that the transferred file does not exist using dlt_user_log_file_complete.
+int testF3P1(){
+
+ //Just some log to the main context
+ DLT_LOG(mainContext,DLT_LOG_INFO,DLT_STRING("Started testF3P1"),DLT_STRING(file3));
+
+ //Here's the line where the dlt file transfer is called. The method call needs a context, the absolute file path, will the file be deleted after transfer and the timeout between the packages
+ transferResult = dlt_user_log_file_complete(&fileContext,file3,0,20);
+ if(transferResult < 0)
+ {
+ //Error expected because file doesn't exist
+ //printf("Error: dlt_user_log_file_complete\n");
+ //Just some log to the main context
+ DLT_LOG(mainContext,DLT_LOG_INFO,DLT_STRING("Finished testF3P1"),DLT_STRING(file3));
+ return transferResult;
+ }
+ return transferResult;
+}
+
+
+//!Test the file transfer with the condition that the transferred file does not exist using single package transfer
+int testF3P2(){
+
+ //Get the information how many packages have the file
+ countPackages = dlt_user_log_file_packagesCount(&fileContext,file3);
+ if(countPackages < 0 )
+ {
+ //Error expected because file doesn't exist
+ //printf("Error: dlt_user_log_file_packagesCount\n");
+ //Just some log to the main context
+ DLT_LOG(mainContext,DLT_LOG_INFO,DLT_STRING("Finished testF3P1"),DLT_STRING(file3));
+ return -1;
+ }
+ //Just some log to the main context
+ DLT_LOG(mainContext,DLT_LOG_INFO,DLT_STRING("Started testF3P1"),DLT_STRING(file3));
+
+ //Logs the header of the file transfer. For more details see Mainpage.c.
+ //The header gives information about the file serial number, filename (with absolute path), filesize, packages of file, buffer size
+ transferResult = dlt_user_log_file_header(&fileContext,file3);
+ if( transferResult >= 0){
+
+ //Loop to log all packages
+ for(i=1;i<=countPackages;i++)
+ {
+ //Logs one single package to the file context
+ transferResult = dlt_user_log_file_data(&fileContext,file3,i,20);
+ if(transferResult < 0)
+ {
+ printf("Error: dlt_user_log_file_data\n");
+ return transferResult;
+ }
+ }
+
+ //Logs the end of the file transfer. For more details see Mainpage.c
+ //The end gives just information about the file serial number but is needed to signal that the file transfer has correctly finished and needed for the file transfer plugin of the dlt viewer.
+ transferResult = dlt_user_log_file_end(&fileContext,file3,0);
+ if(transferResult < 0)
+ {
+ printf("Error: dlt_user_log_file_end\n");
+ return transferResult;
+ }
+ }
+
+ return 0;
+}
+
+
+//!Logs some information about the file.
+int testF3P3(){
+
+ //Just some log to the main context
+ DLT_LOG(mainContext,DLT_LOG_INFO,DLT_STRING("Started testF3P2"),DLT_STRING(file3));
+
+ //Here's the line where the dlt file file info is called. The method call logs some information to dlt about the file, filesize, file serial number and number of packages
+ transferResult = dlt_user_log_file_infoAbout(&fileContext,file3);
+ if(transferResult < 0)
+ {
+ //Error expected because file doesn't exist
+ //printf("Error: dlt_user_log_file_infoAbout\n");
+ //Just some log to the main context
+ DLT_LOG(mainContext,DLT_LOG_INFO,DLT_STRING("Finished testF3P2"),DLT_STRING(file3));
+
+ return transferResult;
+ }
+
+ return 0;
+}