diff options
author | Alexander Wenzel <Alexander.AW.Wenzel@bmw.de> | 2011-09-28 18:24:37 +0200 |
---|---|---|
committer | Alexander Wenzel <Alexander.AW.Wenzel@bmw.de> | 2011-09-28 18:24:37 +0200 |
commit | 966bffa7397f0479640f2232c6a2d1667026952e (patch) | |
tree | 1593c54018d6ba6e50faa641000379be98b8d9bc | |
parent | 76b3293857f63563ae0a98a834591cd9d26353d9 (diff) | |
parent | 106dbe47ccd610a6cad2980838498ba8497a249f (diff) | |
download | DLT-daemon-966bffa7397f0479640f2232c6a2d1667026952e.tar.gz |
Merge branch 'master' of QMUC300924:/home/git/DLT-daemon
-rwxr-xr-x | ReleaseNotes.txt | 12 | ||||
-rwxr-xr-x | include/dlt/CMakeLists.txt | 2 | ||||
-rwxr-xr-x | include/dlt/dlt_common.h | 70 | ||||
-rw-r--r-- | include/dlt/dlt_shm.h | 186 | ||||
-rwxr-xr-x | include/dlt/dlt_user.h | 3 | ||||
-rwxr-xr-x | include/dlt/dlt_version.h | 2 | ||||
-rwxr-xr-x | src/daemon/CMakeLists.txt | 2 | ||||
-rwxr-xr-x | src/daemon/dlt-daemon.c | 738 | ||||
-rwxr-xr-x | src/daemon/dlt-daemon.h | 26 | ||||
-rwxr-xr-x | src/daemon/dlt_daemon_common.c | 22 | ||||
-rwxr-xr-x | src/daemon/dlt_daemon_common.h | 1 | ||||
-rwxr-xr-x | src/lib/CMakeLists.txt | 2 | ||||
-rwxr-xr-x | src/lib/dlt_user.c | 115 | ||||
-rwxr-xr-x | src/lib/dlt_user_cfg.h | 6 | ||||
-rwxr-xr-x | src/shared/dlt_common.c | 463 | ||||
-rw-r--r-- | src/shared/dlt_shm.c | 563 | ||||
-rwxr-xr-x | src/tests/dlt-test-internal.c | 119 | ||||
-rwxr-xr-x | src/tests/dlt-test-stress.c | 9 | ||||
-rw-r--r-- | testscripts/dlt.conf | 81 |
19 files changed, 1295 insertions, 1127 deletions
diff --git a/ReleaseNotes.txt b/ReleaseNotes.txt index cba8059..126c0b7 100755 --- a/ReleaseNotes.txt +++ b/ReleaseNotes.txt @@ -1,6 +1,6 @@ DLT - Automotive Diagnostic Log and Trace
-Version: 2.3.0
+Version: 2.4.0
Introduction
@@ -23,6 +23,16 @@ Alexander.AW.Wenzel@bmw.de Changes in this release
-----------------------
+2.4.0
+
+Improvements
+ * [GSW-61] Replace command line parameter by configuration file
+ * [GSW-13] Support for keep-alive messages as configuration parameter
+ * [GSW-60] Extended offline DLT Trace memory handling.
+
+Bugfixes
+ *
+
2.3.0
Improvements
diff --git a/include/dlt/CMakeLists.txt b/include/dlt/CMakeLists.txt index 6ddcfad..95b9929 100755 --- a/include/dlt/CMakeLists.txt +++ b/include/dlt/CMakeLists.txt @@ -35,6 +35,6 @@ # @licence end@ ######## -install(FILES dlt.h dlt_user.h dlt_user_macros.h dlt_client.h dlt_protocol.h dlt_common.h dlt_types.h dlt_version.h +install(FILES dlt.h dlt_user.h dlt_user_macros.h dlt_client.h dlt_protocol.h dlt_common.h dlt_types.h dlt_version.h dlt_shm.h DESTINATION include/dlt COMPONENT devel) diff --git a/include/dlt/dlt_common.h b/include/dlt/dlt_common.h index 67371be..3a1c9d2 100755 --- a/include/dlt/dlt_common.h +++ b/include/dlt/dlt_common.h @@ -932,76 +932,6 @@ extern "C" */ int dlt_check_storageheader(DltStorageHeader *storageheader); - /** - * Initialize ringbuffer of with a maximum size of size - * @param dltbuf Pointer to ringbuffer structure - * @param size Maximum size of buffer in bytes - * @return negative value if there was an error - */ - int dlt_ringbuffer_init(DltRingBuffer *dltbuf, uint32_t size); - - /** - * Release and free memory used by ringbuffer - * @param dltbuf Pointer to ringbuffer structure - * @return negative value if there was an error - */ - int dlt_ringbuffer_free(DltRingBuffer *dltbuf); - - /** - * Write one entry to ringbuffer - * @param dltbuf Pointer to ringbuffer structure - * @param data Pointer to data to be written to ringbuffer - * @param size Size of data in bytes to be written to ringbuffer - * @return negative value if there was an error - */ - int dlt_ringbuffer_put(DltRingBuffer *dltbuf, void *data, uint32_t size); - - /** - * Write one entry given as 3 chunks to ringbuffer - * @param dltbuf Pointer to ringbuffer structure - * @param data1 Pointer to data1 to be written to ringbuffer - * @param size1 Size of data1 in bytes to be written to ringbuffer - * @param data2 Pointer to data2 to be written to ringbuffer - * @param size2 Size of data2 in bytes to be written to ringbuffer - * @param data3 Pointer to data3 to be written to ringbuffer - * @param size3 Size of data3 in bytes to be written to ringbuffer - * @return negative value if there was an error - */ - int dlt_ringbuffer_put3(DltRingBuffer *dltbuf, void *data1, uint32_t size1, void *data2, uint32_t size2, void *data3, uint32_t size3); - - /** - * Read one entry from ringbuffer - * @param dltbuf Pointer to ringbuffer structure - * @param data Pointer to data read from ringbuffer - * @param size Size of read data in bytes from ringbuffer - * @return negative value if there was an error - */ - int dlt_ringbuffer_get(DltRingBuffer *dltbuf, void *data, size_t *size); - - /** - * Helper function: Skip one readable entry in ringbuffer - * @param dltbuf Pointer to ringbuffer structure - * @return negative value if there was an error - */ - int dlt_ringbuffer_get_skip(DltRingBuffer *dltbuf); - - /** - * Helper function: Get free space in bytes for writting between write and read position - * @param dltbuf Pointer to ringbuffer structure - * @param freespace Free Space in bytes for writting is returned - * @return negative value if there was an error - */ - int dlt_ringbuffer_freespacewrite(DltRingBuffer *dltbuf, uint32_t *freespace); - - /** - * Helper function: Check free space and if necessary discard entries, so that at least - * reqspace bytes are available for writting - * @param dltbuf Pointer to ringbuffer structure - * @param reqspace Requested space for writting in bytes - * @return negative value if there was an error - */ - int dlt_ringbuffer_checkandfreespace(DltRingBuffer *dltbuf, uint32_t reqspace); - #if !defined (__WIN32__) /** diff --git a/include/dlt/dlt_shm.h b/include/dlt/dlt_shm.h new file mode 100644 index 0000000..fc37117 --- /dev/null +++ b/include/dlt/dlt_shm.h @@ -0,0 +1,186 @@ +/* +* 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_shm.h ** +** ** +** 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 ** +*******************************************************************************/ + +#ifndef DLT_SHM_H +#define DLT_SHM_H + +/* shared memory key */ +/* must be the same for server and cleint */ +#define DLT_SHM_KEY 11771 + +/* default size of shared memory */ +/* size is extended during creation to fit segment size */ +/* client retreives real size from shm buffer */ +#define DLT_SHM_SIZE 100000 + +/* Id of the used semaphore */ +/* used for synchronisation of write and read access of multiple clients and server */ +/* must be the same for server and client */ +#define DLT_SHM_SEM 22771 + +typedef struct +{ + int shmid; /* Id of shared memory */ + int semid; /* Id of semaphore */ + char* shm; /* pointer to beginning of shared memory */ + int size; /* size of data area in shared memory */ + char* mem; /* pointer to data area in shared memory */ +} DltShm; + +#define DLT_SHM_SEM_GET(id) dlt_shm_pv(id,-1) +#define DLT_SHM_SEM_FREE(id) dlt_shm_pv(id,1) + +/** + * Initialise the shared memory on the client side. + * This function must be called before using further shm functions. + * @param buf pointer to shm structure + * @param key the identifier of the shm, must be the same for server and client + * @return negative value if there was an error + */ +extern int dlt_shm_init_client(DltShm *buf,int key); + +/** + * Initialise the shared memory on the server side. + * This function must be called before using further shm functions. + * @param buf pointer to shm structure + * @param key the identifier of the shm, must be the same for server and client + * @param size the requested size of the shm + * @return negative value if there was an error + */ +extern int dlt_shm_init_server(DltShm *buf,int key,int size); + +/** + * Push data from client onto the shm. + * @param buf pointer to shm structure + * @param data1 pointer to first data block to be written, null if not used + * @param size1 size in bytes of first data block to be written, 0 if not used + * @param data2 pointer to second data block to be written, null if not used + * @param size2 size in bytes of second data block to be written, 0 if not used + * @param data3 pointer to third data block to be written, null if not used + * @param size3 size in bytes of third data block to be written, 0 if not used + * @return negative value if there was an error + */ +extern int dlt_shm_push(DltShm *buf,const unsigned char *data1,unsigned int size1,const unsigned char *data2,unsigned int size2,const unsigned char *data3,unsigned int size3); + +/** + * Pull data from shm. + * This function should be called from client. + * Data is deleted from shm after this call. + * @param buf pointer to shm structure + * @param data pointer to buffer where data is to be written + * @param size maximum size to be written into buffer + * @return negative value if there was an error + */ +extern int dlt_shm_pull(DltShm *buf,unsigned char *data, int size); + +/** + * Copy message from shm. + * This function should be called from server. + * Data is not deleted from shm after this call. + * @param buf pointer to shm structure + * @param data pointer to buffer where data is to be written + * @param size maximum size to be written into buffer + * @return negative value if there was an error + */ +extern int dlt_shm_copy(DltShm *buf,unsigned char *data, int size); + +/** + * Delete message from shm. + * This function should be called from server. + * This function should be called after each succesful copy. + * @param buf pointer to shm structure + * @return negative value if there was an error + */ +extern int dlt_shm_remove(DltShm *buf); + +/** + * Print information about shm. + * @param buf pointer to shm structure + */ +extern void dlt_shm_info(DltShm *buf); + +/** + * Print status about shm. + * @param buf pointer to shm structure + */ +extern void dlt_shm_status(DltShm *buf); + +/** + * Deinitialise the shared memory on the client side. + * @param buf pointer to shm structure + * @return negative value if there was an error + */ +extern int dlt_shm_free_client(DltShm *buf); + +/** + * Deinitialise the shared memory on the server side. + * @param buf pointer to shm structure + * @return negative value if there was an error + */ +extern int dlt_shm_free_server(DltShm *buf); + +#endif /* DLT_SHM_H */ diff --git a/include/dlt/dlt_user.h b/include/dlt/dlt_user.h index 263a5f2..1ea46cc 100755 --- a/include/dlt/dlt_user.h +++ b/include/dlt/dlt_user.h @@ -91,6 +91,7 @@ #include "dlt_types.h" #include "dlt_common.h" #include "dlt_user_macros.h" +#include "dlt_shm.h" #if !defined (__WIN32__) #include <semaphore.h> @@ -225,7 +226,7 @@ typedef struct int8_t enable_local_print; /**< Local printing of log messages: 1 enabled, 0 disabled */ int8_t local_print_mode; /**< Local print mode, controlled by environment variable */ - DltRingBuffer rbuf; /**< Ring-buffer for buffering messages during startup and missing connection */ + DltShm dlt_shm; } DltUser; /************************************************************************************************** diff --git a/include/dlt/dlt_version.h b/include/dlt/dlt_version.h index 1ea8756..30152fd 100755 --- a/include/dlt/dlt_version.h +++ b/include/dlt/dlt_version.h @@ -7,6 +7,6 @@ #define PACKAGE_MAJOR_VERSION "2" #define PACKAGE_MINOR_VERSION "3" #define PACKAGE_PATCH_LEVEL "0" -#define PACKAGE_REVISION "v2.3.0" +#define PACKAGE_REVISION "v2.3.0-20-g9e988e6" #endif diff --git a/src/daemon/CMakeLists.txt b/src/daemon/CMakeLists.txt index c9f0162..c309a91 100755 --- a/src/daemon/CMakeLists.txt +++ b/src/daemon/CMakeLists.txt @@ -35,7 +35,7 @@ # @licence end@ ######## -set(dlt_daemon_SRCS dlt-daemon dlt_daemon_common ${CMAKE_SOURCE_DIR}/src/shared/dlt_user_shared.c ${CMAKE_SOURCE_DIR}/src/shared/dlt_common.c) +set(dlt_daemon_SRCS dlt-daemon dlt_daemon_common ${CMAKE_SOURCE_DIR}/src/shared/dlt_user_shared.c ${CMAKE_SOURCE_DIR}/src/shared/dlt_common.c ${CMAKE_SOURCE_DIR}/src/shared/dlt_shm.c ${CMAKE_SOURCE_DIR}/src/shared/dlt_offline_trace.c) add_executable(dlt-daemon ${dlt_daemon_SRCS}) IF(GPROF_DLT_DAEMON) SET(CMAKE_C_FLAGS "-pg") diff --git a/src/daemon/dlt-daemon.c b/src/daemon/dlt-daemon.c index 4f30a86..7dcf025 100755 --- a/src/daemon/dlt-daemon.c +++ b/src/daemon/dlt-daemon.c @@ -134,24 +134,10 @@ void usage() printf("Usage: dlt-daemon [options]\n"); printf("DLT logging daemon\n"); printf("Options:\n"); - printf(" -a Print DLT messages; payload as ASCII\n"); - printf(" -x Print DLT messages; payload as hex\n"); - printf(" -s Print DLT messages; only headers\n"); printf(" -d Daemonize\n"); printf(" -v Verbose mode\n"); printf(" -h Usage\n"); - printf(" -l Send DLT messages with serial header\n"); - printf(" -r Send automatic get log info response during\n"); - printf(" context registration\n"); - printf(" -m Sync to serial header on serial connection\n"); - printf(" -n Sync to serial header on all TCP connections\n"); - printf(" -y devname Additional support for serial device\n"); - printf(" -b baudrate Serial device baudrate (Default: 115200)\n"); - printf(" -e ecuid Set ECU ID (Default: ECU1)\n"); - printf(" -o filename Store DLT messages to local log file\n"); - printf(" -f filename Enable filtering of messages\n"); - printf(" -u size Size of the ringbuffer in bytes (Default: 10024)\n"); - printf(" -i directory Directory where to store the persistant configuration (Default: /tmp)\n"); + printf(" -c filename DLT daemon configuration file (Default: /etc/dlt.conf)\n"); } /* usage() */ /** @@ -172,7 +158,7 @@ int option_handling(DltDaemonLocal *daemon_local,int argc, char* argv[]) opterr = 0; - while ((c = getopt (argc, argv, "hvasxdlrmnf:o:e:b:y:u:i:")) != -1) + while ((c = getopt (argc, argv, "hvdc:")) != -1) { switch (c) { @@ -181,79 +167,14 @@ int option_handling(DltDaemonLocal *daemon_local,int argc, char* argv[]) daemon_local->flags.vflag = 1; break; } - case 'a': - { - daemon_local->flags.aflag = 1; - break; - } - case 's': - { - daemon_local->flags.sflag = 1; - break; - } - case 'x': - { - daemon_local->flags.xflag = 1; - break; - } case 'd': { daemon_local->flags.dflag = 1; break; } - case 'l': - { - daemon_local->flags.lflag = 1; - break; - } - case 'r': - { - daemon_local->flags.rflag = 1; - break; - } - case 'm': - { - daemon_local->flags.mflag = 1; - break; - } - case 'n': - { - daemon_local->flags.nflag = 1; - break; - } - case 'f': - { - daemon_local->flags.fvalue = optarg; - break; - } - case 'o': - { - daemon_local->flags.ovalue = optarg; - break; - } - case 'e': - { - daemon_local->flags.evalue = optarg; - break; - } - case 'b': - { - daemon_local->flags.bvalue = optarg; - break; - } - case 'y': - { - daemon_local->flags.yvalue = optarg; - break; - } - case 'u': - { - daemon_local->flags.uvalue = optarg; - break; - } - case 'i': + case 'c': { - daemon_local->flags.ivalue = optarg; + strncpy(daemon_local->flags.cvalue,optarg,sizeof(daemon_local->flags.cvalue)); break; } case 'h': @@ -263,7 +184,7 @@ int option_handling(DltDaemonLocal *daemon_local,int argc, char* argv[]) } case '?': { - if (optopt == 'f' || optopt == 'o' || optopt == 'e' || optopt == 'b' || optopt == 'y' || optopt == 'u') + if (optopt == 'c') { fprintf (stderr, "Option -%c requires an argument.\n", optopt); } @@ -292,6 +213,179 @@ int option_handling(DltDaemonLocal *daemon_local,int argc, char* argv[]) } /* option_handling() */ /** + * Option file parser + */ +int option_file_parser(DltDaemonLocal *daemon_local) +{ + FILE * pFile; + char line[1024]; + char token[1024]; + char value[1024]; + char *pch; + const char *filename; + + /* set default values for configuration */ + daemon_local->flags.sharedMemorySize = DLT_SHM_SIZE; + daemon_local->flags.sendMessageTime = 0; + daemon_local->flags.offlineTraceDirectory[0] = 0; + daemon_local->flags.offlineTraceFileSize = 1000000; + daemon_local->flags.offlineTraceMaxSize = 0; + + /* open configuration file */ + if(daemon_local->flags.cvalue[0]) + filename = daemon_local->flags.cvalue; + else + filename = "/etc/dlt.conf"; + //printf("Load configuration from file: %s\n",filename); + pFile = fopen (filename,"r"); + + if (pFile!=NULL) + { + while(1) + { + /* fetch line from configuration file */ + if ( fgets (line , 1024 , pFile) != NULL ) + { + //printf("Line: %s\n",line); + pch = strtok (line," =\r\n"); + token[0]=0; + value[0]=0; + + while (pch != NULL) + { + if(strcmp(pch,"#")==0) + break; + + if(token[0]==0) + { + strncpy(token,pch,sizeof(token)); + } + else + { + strncpy(value,pch,sizeof(value)); + break; + } + + pch = strtok (NULL, " =\r\n"); + } + + if(token[0] && value[0]) + { + /* parse arguments here */ + if(strcmp(token,"Verbose")==0) + { + daemon_local->flags.vflag = atoi(value); + printf("Option: %s=%s\n",token,value); + } + else if(strcmp(token,"PrintASCII")==0) + { + daemon_local->flags.aflag = atoi(value); + printf("Option: %s=%s\n",token,value); + } + else if(strcmp(token,"PrintHex")==0) + { + daemon_local->flags.xflag = atoi(value); + printf("Option: %s=%s\n",token,value); + } + else if(strcmp(token,"PrintHeadersOnly")==0) + { + daemon_local->flags.sflag = atoi(value); + printf("Option: %s=%s\n",token,value); + } + else if(strcmp(token,"Daemonize")==0) + { + daemon_local->flags.dflag = atoi(value); + printf("Option: %s=%s\n",token,value); + } + else if(strcmp(token,"SendSerialHeader")==0) + { + daemon_local->flags.lflag = atoi(value); + printf("Option: %s=%s\n",token,value); + } + else if(strcmp(token,"SendContextRegistration")==0) + { + daemon_local->flags.rflag = atoi(value); + printf("Option: %s=%s\n",token,value); + } + else if(strcmp(token,"SendMessageTime")==0) + { + daemon_local->flags.sendMessageTime = atoi(value); + printf("Option: %s=%s\n",token,value); + } + else if(strcmp(token,"RS232SyncSerialHeader")==0) + { + daemon_local->flags.mflag = atoi(value); + printf("Option: %s=%s\n",token,value); + } + else if(strcmp(token,"TCPSyncSerialHeader")==0) + { + daemon_local->flags.nflag = atoi(value); + printf("Option: %s=%s\n",token,value); + } + else if(strcmp(token,"RS232DeviceName")==0) + { + strncpy(daemon_local->flags.yvalue,value,sizeof(daemon_local->flags.yvalue)); + printf("Option: %s=%s\n",token,value); + } + else if(strcmp(token,"RS232Baudrate")==0) + { + strncpy(daemon_local->flags.bvalue,value,sizeof(daemon_local->flags.bvalue)); + printf("Option: %s=%s\n",token,value); + } + else if(strcmp(token,"ECUId")==0) + { + strncpy(daemon_local->flags.evalue,value,sizeof(daemon_local->flags.evalue)); + printf("Option: %s=%s\n",token,value); + } + else if(strcmp(token,"PersistanceStoragePath")==0) + { + strncpy(daemon_local->flags.ivalue,value,sizeof(daemon_local->flags.ivalue)); + printf("Option: %s=%s\n",token,value); + } + else if(strcmp(token,"SharedMemorySize")==0) + { + daemon_local->flags.sharedMemorySize = atoi(value); + printf("Option: %s=%s\n",token,value); + } + else if(strcmp(token,"OfflineTraceDirectory")==0) + { + strncpy(daemon_local->flags.offlineTraceDirectory,value,sizeof(daemon_local->flags.offlineTraceDirectory)); + printf("Option: %s=%s\n",token,value); + } + else if(strcmp(token,"OfflineTraceFileSize")==0) + { + daemon_local->flags.offlineTraceFileSize = atoi(value); + printf("Option: %s=%s\n",token,value); + } + else if(strcmp(token,"OfflineTraceMaxSize")==0) + { + daemon_local->flags.offlineTraceMaxSize = atoi(value); + printf("Option: %s=%s\n",token,value); + } + else + { + fprintf(stderr, "Unknown option: %s=%s\n",token,value); + } + } + //printf ("Token: %s\n",pch); + + } + else + { + break; + } + } + fclose (pFile); + } + else + { + fprintf(stderr, "Cannot open configuration file: %s\n",filename); + } + + return 0; +} + +/** * Main function of tool. */ int main(int argc, char* argv[]) @@ -311,6 +405,15 @@ int main(int argc, char* argv[]) return -1; } + /* Configuration file option handling */ + if ((back = option_file_parser(&daemon_local))<0) + { + if(back!=-2) { + fprintf (stderr, "option_file_parser() failed!\n"); + } + return -1; + } + /* Initialize logging facility */ dlt_log_init(daemon_local.flags.dflag); @@ -379,7 +482,7 @@ int main(int argc, char* argv[]) return -1; } } - else if ((i == daemon_local.fdserial) && (daemon_local.flags.yvalue!=0)) + else if ((i == daemon_local.fdserial) && (daemon_local.flags.yvalue[0])) { /* event from serial connection to client received */ if (dlt_daemon_process_client_messages_serial(&daemon, &daemon_local, daemon_local.flags.vflag)==-1) @@ -435,26 +538,6 @@ int dlt_daemon_local_init_p1(DltDaemon *daemon, DltDaemonLocal *daemon_local, in return -1; } - /* first parse filter file if filter parameter is used */ - if (daemon_local->flags.fvalue) - { - if (dlt_filter_load(&(daemon_local->filter),daemon_local->flags.fvalue,daemon_local->flags.vflag)<0) - { - dlt_log(LOG_ERR,"Could not load filters\n"); - /* Return value ignored, dlt daemon will exit */ - dlt_file_free(&(daemon_local->file),daemon_local->flags.vflag); - return -1; - } /* if */ - - if (dlt_file_set_filter(&(daemon_local->file),&(daemon_local->filter),daemon_local->flags.vflag)==-1) - { - dlt_log(LOG_ERR,"Could not apply filters\n"); - /* Return value ignored, dlt daemon will exit */ - dlt_file_free(&(daemon_local->file),daemon_local->flags.vflag); - return -1; - } - } /* if */ - signal(SIGPIPE,SIG_IGN); signal(SIGTERM, dlt_daemon_signal_handler); /* software termination signal from kill */ @@ -462,9 +545,10 @@ int dlt_daemon_local_init_p1(DltDaemon *daemon, DltDaemonLocal *daemon_local, in signal(SIGQUIT, dlt_daemon_signal_handler); signal(SIGINT, dlt_daemon_signal_handler); +#if 0 /* open DLT output file */ daemon_local->ohandle=-1; - if (daemon_local->flags.ovalue) + if (daemon_local->flags.ovalue[0]) { daemon_local->ohandle = open(daemon_local->flags.ovalue,O_WRONLY|O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); /* mode: wb */ if (daemon_local->ohandle == -1) @@ -476,7 +560,17 @@ int dlt_daemon_local_init_p1(DltDaemon *daemon, DltDaemonLocal *daemon_local, in return -1; } /* if */ } /* if */ - +#endif + /* init offline trace */ + if(daemon_local->flags.offlineTraceDirectory[0]) + { + if (dlt_offline_trace_init(&(daemon_local->offlineTrace),daemon_local->flags.offlineTraceDirectory,daemon_local->flags.offlineTraceFileSize,daemon_local->flags.offlineTraceMaxSize)==-1) + { + dlt_log(LOG_ERR,"Could not initialize offline trace\n"); + return -1; + } + } + return 0; } @@ -498,7 +592,7 @@ int dlt_daemon_local_init_p2(DltDaemon *daemon, DltDaemonLocal *daemon_local, in } /* Set ECU id of daemon */ - if (daemon_local->flags.evalue!=0) + if (daemon_local->flags.evalue[0]) { dlt_set_id(daemon->ecuid,daemon_local->flags.evalue); } @@ -510,18 +604,13 @@ int dlt_daemon_local_init_p2(DltDaemon *daemon, DltDaemonLocal *daemon_local, in /* Set flag for optional sending of serial header */ daemon->sendserialheader = daemon_local->flags.lflag; - /* prepare ringbuffer size */ - if (daemon_local->flags.uvalue!=0) - { - daemon_local->ringbufferSize = atoi(daemon_local->flags.uvalue); - } - else - { - daemon_local->ringbufferSize = DLT_DAEMON_RCVBUFSIZE; - } - sprintf(str,"Ringbuffer size: %d bytes\n",daemon_local->ringbufferSize); - dlt_log(LOG_NOTICE, str); - + /* init shared memory */ + if (dlt_shm_init_server(&(daemon_local->dlt_shm),DLT_SHM_KEY,daemon_local->flags.sharedMemorySize)==-1) + { + dlt_log(LOG_ERR,"Could not initialize shared memory\n"); + return -1; + } + /* prepare main loop */ if (dlt_message_init(&(daemon_local->msg),daemon_local->flags.vflag)==-1) { @@ -529,7 +618,7 @@ int dlt_daemon_local_init_p2(DltDaemon *daemon, DltDaemonLocal *daemon_local, in return -1; } - if (dlt_receiver_init(&(daemon_local->receiver),daemon_local->fp,daemon_local->ringbufferSize)==-1) + if (dlt_receiver_init(&(daemon_local->receiver),daemon_local->fp,DLT_DAEMON_RCVBUFSIZE)==-1) { dlt_log(LOG_ERR,"Could not initialize receiver\n"); return -1; @@ -539,8 +628,7 @@ int dlt_daemon_local_init_p2(DltDaemon *daemon, DltDaemonLocal *daemon_local, in dlt_log(LOG_ERR,"Could not initialize receiver for socket\n"); return -1; } - - if (daemon_local->flags.yvalue!=0) + if (daemon_local->flags.yvalue[0]) { if (dlt_receiver_init(&(daemon_local->receiverSerial),daemon_local->fdserial,DLT_DAEMON_RCVBUFSIZESERIAL)==-1) { @@ -561,7 +649,13 @@ int dlt_daemon_local_init_p2(DltDaemon *daemon, DltDaemonLocal *daemon_local, in dlt_log(LOG_WARNING, "Setting of default thread stack size failed!\n"); } } - + + /* configure sending timing packets */ + if (daemon_local->flags.sendMessageTime) + { + daemon->timingpackets = 1; + } + /* Binary semaphore for thread */ if (sem_init(&dlt_daemon_mutex, 0, 1)==-1) { @@ -675,22 +769,22 @@ int dlt_daemon_local_connection_init(DltDaemon *daemon, DltDaemonLocal *daemon_l daemon_local->fdmax = daemon_local->fp; } - if (daemon_local->flags.yvalue!=0) + if (daemon_local->flags.yvalue[0]) { /* create and open serial connection from/to client */ /* open serial connection */ daemon_local->fdserial=open(daemon_local->flags.yvalue,O_RDWR); if (daemon_local->fdserial<0) { - daemon_local->flags.yvalue = 0; sprintf(str,"Failed to open serial device %s\n", daemon_local->flags.yvalue); + daemon_local->flags.yvalue[0] = 0; dlt_log(LOG_ERR, str); return -1; } if (isatty(daemon_local->fdserial)) { - if (daemon_local->flags.bvalue!=0) + if (daemon_local->flags.bvalue[0]) { daemon_local->baudrate = dlt_convert_serial_speed(atoi(daemon_local->flags.bvalue)); } @@ -702,8 +796,8 @@ int dlt_daemon_local_connection_init(DltDaemon *daemon, DltDaemonLocal *daemon_l if (dlt_setup_serial(daemon_local->fdserial,daemon_local->baudrate)<0) { close(daemon_local->fdserial); - daemon_local->flags.yvalue = 0; sprintf(str,"Failed to configure serial device %s (%s) \n", daemon_local->flags.yvalue, strerror(errno)); + daemon_local->flags.yvalue[0] = 0; dlt_log(LOG_ERR, str); return -1; } @@ -723,8 +817,8 @@ int dlt_daemon_local_connection_init(DltDaemon *daemon, DltDaemonLocal *daemon_l else { close(daemon_local->fdserial); - daemon_local->flags.yvalue = 0; fprintf(stderr,"Device is not a serial device, device = %s (%s) \n", daemon_local->flags.yvalue, strerror(errno)); + daemon_local->flags.yvalue[0] = 0; return -1; } } @@ -752,10 +846,15 @@ void dlt_daemon_local_cleanup(DltDaemon *daemon, DltDaemonLocal *daemon_local, i dlt_message_free(&(daemon_local->msg),daemon_local->flags.vflag); close(daemon_local->fp); - if (daemon_local->flags.ovalue) + /* free shared memory */ + if(daemon_local->flags.offlineTraceDirectory[0]) + dlt_offline_trace_free(&(daemon_local->offlineTrace)); +#if 0 + if (daemon_local->flags.ovalue[0]) { close(daemon_local->ohandle); } /* if */ +#endif /* Ignore result */ dlt_file_free(&(daemon_local->file),daemon_local->flags.vflag); @@ -763,6 +862,9 @@ void dlt_daemon_local_cleanup(DltDaemon *daemon, DltDaemonLocal *daemon_local, i /* Try to delete existing pipe, ignore result of unlink() */ unlink(DLT_USER_FIFO); + /* free shared memory */ + dlt_shm_free_server(&(daemon_local->dlt_shm)); + /* Try to delete lock file, ignore result of unlink() */ unlink(DLT_DAEMON_LOCK_FILE); } @@ -912,15 +1014,8 @@ int dlt_daemon_process_client_connect(DltDaemon *daemon, DltDaemonLocal *daemon_ if (daemon_local->client_connections==1) { - if (daemon_local->flags.vflag) - { - dlt_log(LOG_INFO, "Send ring-buffer to client\n"); - } - if (dlt_daemon_send_ringbuffer_to_client(daemon, daemon_local, verbose)==-1) - { - dlt_log(LOG_ERR,"Can't send contents of ringbuffer to clients\n"); - return -1; - } + /* send ringbuffer done in old implementation */ + /* nothing to do with shared memory */ } return 0; @@ -1594,9 +1689,11 @@ int dlt_daemon_process_user_message_unregister_context(DltDaemon *daemon, DltDae int dlt_daemon_process_user_message_log(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose) { - int bytes_to_be_removed; + //int bytes_to_be_removed; int j,sent,third_value; ssize_t ret; + uint8_t rcv_buffer[10000]; + int size; static char text[DLT_DAEMON_TEXTSIZE]; @@ -1608,169 +1705,176 @@ int dlt_daemon_process_user_message_log(DltDaemon *daemon, DltDaemonLocal *daemo return -1; } - if (dlt_message_read(&(daemon_local->msg),(unsigned char*)daemon_local->receiver.buf+sizeof(DltUserHeader),daemon_local->receiver.bytesRcvd-sizeof(DltUserHeader),0,verbose)==0) + //dlt_shm_status(&(daemon_local->dlt_shm)); + while ( (size = dlt_shm_copy(&(daemon_local->dlt_shm),rcv_buffer,10000)) > 0) { - /* set overwrite ecu id */ - if (daemon_local->flags.evalue!=0) - { - /* Set header extra parameters */ - dlt_set_id(daemon_local->msg.headerextra.ecu, daemon->ecuid ); - //msg.headerextra.seid = 0; - if (dlt_message_set_extraparameters(&(daemon_local->msg),0)==-1) - { - dlt_log(LOG_ERR,"Can't set message extra parameters in process user message log\n"); - return -1; - } + if (dlt_message_read(&(daemon_local->msg),rcv_buffer,size,0,verbose)==0) + { + /* set overwrite ecu id */ + if (daemon_local->flags.evalue[0]) + { + /* Set header extra parameters */ + dlt_set_id(daemon_local->msg.headerextra.ecu, daemon->ecuid ); + //msg.headerextra.seid = 0; + if (dlt_message_set_extraparameters(&(daemon_local->msg),0)==-1) + { + dlt_log(LOG_ERR,"Can't set message extra parameters in process user message log\n"); + dlt_shm_remove(&(daemon_local->dlt_shm)); + return -1; + } - /* Correct value of timestamp, this was changed by dlt_message_set_extraparameters() */ - daemon_local->msg.headerextra.tmsp = DLT_BETOH_32(daemon_local->msg.headerextra.tmsp); - } + /* Correct value of timestamp, this was changed by dlt_message_set_extraparameters() */ + daemon_local->msg.headerextra.tmsp = DLT_BETOH_32(daemon_local->msg.headerextra.tmsp); + } - /* prepare storage header */ - if (DLT_IS_HTYP_WEID(daemon_local->msg.standardheader->htyp)) - { - if (dlt_set_storageheader(daemon_local->msg.storageheader,daemon_local->msg.headerextra.ecu)==-1) - { - dlt_log(LOG_ERR,"Can't set storage header in process user message log\n"); - return -1; - } - } - else - { - if (dlt_set_storageheader(daemon_local->msg.storageheader,daemon->ecuid)==-1) - { - dlt_log(LOG_ERR,"Can't set storage header in process user message log\n"); - return -1; - } - } + /* prepare storage header */ + if (DLT_IS_HTYP_WEID(daemon_local->msg.standardheader->htyp)) + { + if (dlt_set_storageheader(daemon_local->msg.storageheader,daemon_local->msg.headerextra.ecu)==-1) + { + dlt_log(LOG_ERR,"Can't set storage header in process user message log\n"); + dlt_shm_remove(&(daemon_local->dlt_shm)); + return -1; + } + } + else + { + if (dlt_set_storageheader(daemon_local->msg.storageheader,daemon->ecuid)==-1) + { + dlt_log(LOG_ERR,"Can't set storage header in process user message log\n"); + dlt_shm_remove(&(daemon_local->dlt_shm)); + return -1; + } + } - if ((daemon_local->flags.fvalue==0) || - (daemon_local->flags.fvalue && (dlt_message_filter_check(&(daemon_local->msg),&(daemon_local->filter),verbose)==1))) - { - /* if no filter set or filter is matching display message */ - if (daemon_local->flags.xflag) - { - if (dlt_message_print_hex(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1) + /* display message */ + if (daemon_local->flags.xflag) + { + if (dlt_message_print_hex(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1) { dlt_log(LOG_ERR,"dlt_message_print_hex() failed!\n"); } - } /* if */ - else if (daemon_local->flags.aflag) - { - if (dlt_message_print_ascii(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1) - { + } /* if */ + else if (daemon_local->flags.aflag) + { + if (dlt_message_print_ascii(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1) + { dlt_log(LOG_ERR,"dlt_message_print_ascii() failed!\n"); } - } /* if */ - else if (daemon_local->flags.sflag) - { - if (dlt_message_print_header(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1) + } /* if */ + else if (daemon_local->flags.sflag) + { + if (dlt_message_print_header(&(daemon_local->msg),text,DLT_DAEMON_TEXTSIZE,verbose)==-1) { dlt_log(LOG_ERR,"dlt_message_print_header() failed!\n"); } - /* print message header only */ - } /* if */ - - /* if file output enabled write message */ - if (daemon_local->flags.ovalue) - { - /* write message to output buffer */ - if (dlt_user_log_out2(daemon_local->ohandle, - daemon_local->msg.headerbuffer, - daemon_local->msg.headersize, - daemon_local->msg.databuffer, - daemon_local->msg.datasize) !=DLT_RETURN_OK) - { - dlt_log(LOG_ERR,"Writing to output file failed!\n"); - } - } /* if */ - - sent=0; - - /* look if TCP connection to client is available */ - for (j = 0; j <= daemon_local->fdmax; j++) - { - /* send to everyone! */ - if (FD_ISSET(j, &(daemon_local->master))) - { - /* except the listener and ourselves */ - if (daemon_local->flags.yvalue!=0) - { - third_value = daemon_local->fdserial; - } - else - { - third_value = daemon_local->sock; - } - - if ((j != daemon_local->fp) && (j != daemon_local->sock) && (j != third_value)) - { - DLT_DAEMON_SEM_LOCK(); - - if (daemon_local->flags.lflag) - { - send(j,dltSerialHeader,sizeof(dltSerialHeader),0); - } + /* print message header only */ + } /* if */ - send(j,daemon_local->msg.headerbuffer+sizeof(DltStorageHeader),daemon_local->msg.headersize-sizeof(DltStorageHeader),0); - send(j,daemon_local->msg.databuffer,daemon_local->msg.datasize,0); - - DLT_DAEMON_SEM_FREE(); - - sent=1; - } /* if */ - else if ((j == daemon_local->fdserial) && (daemon_local->flags.yvalue!=0)) - { - DLT_DAEMON_SEM_LOCK(); - - if (daemon_local->flags.lflag) - { - ret=write(j,dltSerialHeader,sizeof(dltSerialHeader)); - } - - ret=write(j,daemon_local->msg.headerbuffer+sizeof(DltStorageHeader),daemon_local->msg.headersize-sizeof(DltStorageHeader)); - ret=write(j,daemon_local->msg.databuffer,daemon_local->msg.datasize); - - DLT_DAEMON_SEM_FREE(); - - sent=1; - } - } /* if */ - } /* for */ - - /* Message was not sent to client, so store it in client ringbuffer */ - if (sent==0) - { - if (dlt_ringbuffer_put3(&(daemon->client_ringbuffer), - daemon_local->msg.headerbuffer+sizeof(DltStorageHeader),daemon_local->msg.headersize-sizeof(DltStorageHeader), - daemon_local->msg.databuffer,daemon_local->msg.datasize, - 0, 0 - )<0) +#if 0 + /* if file output enabled write message */ + if (daemon_local->flags.ovalue[0]) + { + /* write message to output buffer */ + if (dlt_user_log_out2(daemon_local->ohandle, + daemon_local->msg.headerbuffer, + daemon_local->msg.headersize, + daemon_local->msg.databuffer, + daemon_local->msg.datasize) !=DLT_RETURN_OK) { - dlt_log(LOG_ERR,"Storage of message in history buffer failed! Message discarded.\n"); + dlt_log(LOG_ERR,"Writing to output file failed!\n"); } - } + } /* if */ +#endif + sent=0; - } - /* keep not read data in buffer */ - bytes_to_be_removed = daemon_local->msg.headersize+daemon_local->msg.datasize-sizeof(DltStorageHeader)+sizeof(DltUserHeader); - if (daemon_local->msg.found_serialheader) - { - bytes_to_be_removed += sizeof(dltSerialHeader); - } + /* write message to offline trace */ + if(daemon_local->flags.offlineTraceDirectory[0]) + { + dlt_offline_trace_write(&(daemon_local->offlineTrace),daemon_local->msg.headerbuffer,daemon_local->msg.headersize, + daemon_local->msg.databuffer,daemon_local->msg.datasize,0,0); + sent = 1; + } - if (dlt_receiver_remove(&(daemon_local->receiver),bytes_to_be_removed)==-1) - { - dlt_log(LOG_ERR,"Can't remove bytes from receiver\n"); - return -1; - } - } - else + /* look if TCP connection to client is available */ + for (j = 0; j <= daemon_local->fdmax; j++) + { + /* send to everyone! */ + if (FD_ISSET(j, &(daemon_local->master))) + { + /* except the listener and ourselves */ + if (daemon_local->flags.yvalue!=0) + { + third_value = daemon_local->fdserial; + } + else + { + third_value = daemon_local->sock; + } + + if ((j != daemon_local->fp) && (j != daemon_local->sock) && (j != third_value)) + { + DLT_DAEMON_SEM_LOCK(); + + if (daemon_local->flags.lflag) + { + send(j,dltSerialHeader,sizeof(dltSerialHeader),0); + } + + send(j,daemon_local->msg.headerbuffer+sizeof(DltStorageHeader),daemon_local->msg.headersize-sizeof(DltStorageHeader),0); + send(j,daemon_local->msg.databuffer,daemon_local->msg.datasize,0); + + DLT_DAEMON_SEM_FREE(); + + sent=1; + } /* if */ + else if ((j == daemon_local->fdserial) && (daemon_local->flags.yvalue[0])) + { + DLT_DAEMON_SEM_LOCK(); + + if (daemon_local->flags.lflag) + { + ret=write(j,dltSerialHeader,sizeof(dltSerialHeader)); + } + + ret=write(j,daemon_local->msg.headerbuffer+sizeof(DltStorageHeader),daemon_local->msg.headersize-sizeof(DltStorageHeader)); + ret=write(j,daemon_local->msg.databuffer,daemon_local->msg.datasize); + + DLT_DAEMON_SEM_FREE(); + + sent=1; + } + } /* if */ + } /* for */ + + /* Message was not sent to client, so store it in client ringbuffer */ + if (sent==0) + { + /* dlt message was not sent, keep in buffer */ + break; + + } + else + { + /* dlt message was sent, remove from buffer */ + dlt_shm_remove(&(daemon_local->dlt_shm)); + } + + } + else + { + dlt_log(LOG_ERR,"Can't read messages from receiver\n"); + return -1; + } + } + + /* keep not read data in buffer */ + if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader))==-1) { - dlt_log(LOG_ERR,"Can't read messages from receiver\n"); - return -1; + dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message overflow\n"); + return -1; } - + return 0; } @@ -1844,72 +1948,6 @@ int dlt_daemon_process_user_message_set_app_ll_ts(DltDaemon *daemon, DltDaemonLo return 0; } -int dlt_daemon_send_ringbuffer_to_client(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose) -{ - static uint8_t data[DLT_DAEMON_RINGBUFFER_SIZE]; - size_t length=0; - int j, third_value; - ssize_t ret; - - PRINT_FUNCTION_VERBOSE(verbose); - - if ((daemon==0) || (daemon_local==0)) - { - dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_send_ringbuffer_to_client()\n"); - return -1; - } - - /* Attention: If the message can't be send at this time, it will be silently discarded. */ - while ((dlt_ringbuffer_get(&(daemon->client_ringbuffer), data, &length ))!=-1) - { - /* look if TCP connection to client is available */ - for (j = 0; j <= daemon_local->fdmax; j++) - { - /* send to everyone! */ - if (FD_ISSET(j, &(daemon_local->master))) - { - /* except the listener and ourselves */ - if (daemon_local->flags.yvalue!=0) - { - third_value = daemon_local->fdserial; - } - else - { - third_value = daemon_local->sock; - } - - if ((j != daemon_local->fp) && (j != daemon_local->sock) && (j != third_value)) - { - DLT_DAEMON_SEM_LOCK(); - - if (daemon_local->flags.lflag) - { - send(j,dltSerialHeader,sizeof(dltSerialHeader),0); - } - send(j,data,length,0); - - DLT_DAEMON_SEM_FREE(); - - } /* if */ - else if ((j == daemon_local->fdserial) && (daemon_local->flags.yvalue!=0)) - { - DLT_DAEMON_SEM_LOCK(); - - if (daemon_local->flags.lflag) - { - ret=write(j,dltSerialHeader,sizeof(dltSerialHeader)); - } - ret=write(j,data,length); - - DLT_DAEMON_SEM_LOCK(); - } - } /* if */ - } /* for */ - } - - return 0; -} - void dlt_daemon_timingpacket_thread(void *ptr) { DltDaemonPeriodicData info; diff --git a/src/daemon/dlt-daemon.h b/src/daemon/dlt-daemon.h index 8489ee6..4c8f121 100755 --- a/src/daemon/dlt-daemon.h +++ b/src/daemon/dlt-daemon.h @@ -84,6 +84,8 @@ #include "dlt_user_shared.h"
#include "dlt_user_shared_cfg.h"
+#include <dlt_offline_trace.h>
+
/**
* The flags of a dlt daemon.
*/
@@ -98,13 +100,16 @@ typedef struct int rflag; /**< (Boolean) Send automatic get log info response during context registration */
int mflag; /**< (Boolean) Sync to serial header on serial connection */
int nflag; /**< (Boolean) Sync to serial header on all TCP connections */
- char *ovalue; /**< (String: Filename) Store DLT messages to local log file */
- char *fvalue; /**< (String: Filename) Enable filtering of messages */
- char *evalue; /**< (String: ECU ID) Set ECU ID (Default: ECU1) */
- char *bvalue; /**< (String: Baudrate) Serial device baudrate (Default: 115200) */
- char *yvalue; /**< (String: Devicename) Additional support for serial device */
- char *uvalue; /**< (String: Ringbuffer) Size of the ringbuffer in bytes (Default: 10024) */
- char *ivalue; /**< (String: Directory) Directory where to store the persistant configuration (Default: /tmp) */
+ char evalue[256]; /**< (String: ECU ID) Set ECU ID (Default: ECU1) */
+ char bvalue[256]; /**< (String: Baudrate) Serial device baudrate (Default: 115200) */
+ char yvalue[256]; /**< (String: Devicename) Additional support for serial device */
+ char ivalue[256]; /**< (String: Directory) Directory where to store the persistant configuration (Default: /tmp) */
+ char cvalue[256]; /**< (String: Directory) Filename of DLT configuration file (Default: /etc/dlt.conf) */
+ int sharedMemorySize; /**< (int) Size of shared memory (Default: 100000) */
+ int sendMessageTime; /**< (Boolean) Send periodic Message Time if client is connected (Default: 0) */
+ char offlineTraceDirectory[256]; /**< (String: Directory) Store DLT messages to local directory (Default: /etc/dlt.conf) */
+ int offlineTraceFileSize; /**< (int) Maximum size in bytes of one trace file (Default: 1000000) */
+ int offlineTraceMaxSize; /**< (int) Maximum size of all trace files (Default: 4000000) */
} DltDaemonFlags;
/**
@@ -120,15 +125,15 @@ typedef struct fd_set master; /**< master set of handles */
fd_set read_fds; /**< read set of handles */
DltFile file; /**< struct for file access */
- DltFilter filter; /**< struct for filter access */
- int ohandle; /**< handle to output file */
+ //int ohandle; /**< handle to output file */
DltMessage msg; /**< one dlt message */
DltReceiver receiver; /**< receiver for fifo connection */
DltReceiver receiverSock; /**< receiver for socket connection */
DltReceiver receiverSerial; /**< receiver for serial connection */
int client_connections; /**< counter for nr. of client connections */
size_t baudrate; /**< Baudrate of serial connection */
- size_t ringbufferSize; /**< Size of the ringbuffer */
+ DltShm dlt_shm; /**< Shared memory handling */
+ DltOfflineTrace offlineTrace; /**< Offline trace handling */
} DltDaemonLocal;
typedef struct
@@ -164,7 +169,6 @@ int dlt_daemon_process_user_message_register_context(DltDaemon *daemon, DltDaemo int dlt_daemon_process_user_message_unregister_context(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose);
int dlt_daemon_process_user_message_log(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose);
int dlt_daemon_process_user_message_set_app_ll_ts(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose);
-int dlt_daemon_send_ringbuffer_to_client(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose);
void dlt_daemon_timingpacket_thread(void *ptr);
int dlt_daemon_make_periodic (unsigned int period, DltDaemonPeriodicData *info, int verbose);
diff --git a/src/daemon/dlt_daemon_common.c b/src/daemon/dlt_daemon_common.c index a4d5dba..003dc33 100755 --- a/src/daemon/dlt_daemon_common.c +++ b/src/daemon/dlt_daemon_common.c @@ -154,12 +154,12 @@ int dlt_daemon_init(DltDaemon *daemon,const char *runtime_directory, int verbose daemon->runtime_context_cfg_loaded = 0; /* prepare filenames for configuration */ - if(runtime_directory) + if(runtime_directory[0]) strcpy(daemon->runtime_application_cfg,runtime_directory); else strcpy(daemon->runtime_application_cfg,DLT_RUNTIME_DEFAULT_DIRECTORY); strcat(daemon->runtime_application_cfg,DLT_RUNTIME_APPLICATION_CFG); - if(runtime_directory) + if(runtime_directory[0]) strcpy(daemon->runtime_context_cfg,runtime_directory); else strcpy(daemon->runtime_context_cfg,DLT_RUNTIME_DEFAULT_DIRECTORY); @@ -177,12 +177,6 @@ int dlt_daemon_init(DltDaemon *daemon,const char *runtime_directory, int verbose dlt_set_id(daemon->ecuid,""); - /* initialize ring buffer for client connection */ - if (dlt_ringbuffer_init(&(daemon->client_ringbuffer), DLT_DAEMON_RINGBUFFER_SIZE)==-1) - { - return -1; - } - return 0; } @@ -2002,16 +1996,8 @@ void dlt_daemon_control_send_control_message( int sock, DltDaemon *daemon, DltMe } else { - /* Store message in history buffer */ - if (dlt_ringbuffer_put3(&(daemon->client_ringbuffer), - msg->headerbuffer+sizeof(DltStorageHeader),msg->headersize-sizeof(DltStorageHeader), - msg->databuffer,msg->datasize, - 0, 0 - )<0) - { - dlt_log(LOG_ERR,"Storage of message in history buffer failed! Message discarded.\n"); - return; - } + /* message can not be sent */ + /* in old implementation control message was stored in buffer */ } } diff --git a/src/daemon/dlt_daemon_common.h b/src/daemon/dlt_daemon_common.h index 1d16a85..bdacfd7 100755 --- a/src/daemon/dlt_daemon_common.h +++ b/src/daemon/dlt_daemon_common.h @@ -148,7 +148,6 @@ typedef struct char ecuid[DLT_ID_SIZE]; /**< ECU ID of daemon */
int sendserialheader; /**< 1: send serial header; 0 don't send serial header */
int timingpackets; /**< 1: send continous timing packets; 0 don't send continous timing packets */
- DltRingBuffer client_ringbuffer; /**< Ring-buffer for storing received logs while no client connection is available */
char runtime_application_cfg[256]; /**< Path and filename of persistent application configuration */
char runtime_context_cfg[256]; /**< Path and filename of persistent context configuration */
} DltDaemon;
diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index 8e81cfb..1d33d21 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 ) +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) add_library(dlt ${dlt_LIB_SRCS}) diff --git a/src/lib/dlt_user.c b/src/lib/dlt_user.c index 0764efc..4bab5fc 100755 --- a/src/lib/dlt_user.c +++ b/src/lib/dlt_user.c @@ -159,9 +159,17 @@ int dlt_init(void) dlt_user.dlt_is_file = 0; dlt_user.overflow = 0; + /* init shared memory */ + if (dlt_shm_init_client(&dlt_user.dlt_shm,DLT_SHM_KEY) < 0) + { + sprintf(str,"Loging disabled, Shared memory %d cannot be created!\n",DLT_SHM_KEY); + dlt_log(LOG_WARNING, str); + return 0; + } + /* create and open DLT user FIFO */ sprintf(filename,"%s/dlt%d",DLT_USER_DIR,getpid()); - + /* Try to delete existing pipe, ignore result of unlink */ unlink(filename); @@ -197,12 +205,18 @@ int dlt_init(void) return -1; } - /* Initialize thread */ + /* Set default thread stack size */ if (pthread_attr_init(&dlt_receiverthread_attr)<0) { - dlt_log(LOG_WARNING, "Initialization of thread failed!\n"); - return -1; - } + dlt_log(LOG_WARNING, "Initialization of default thread stack size failed!\n"); + } + else + { + if (pthread_attr_setstacksize(&dlt_receiverthread_attr,DLT_USER_RECEIVERTHREAD_STACKSIZE)<0) + { + dlt_log(LOG_WARNING, "Setting of default thread stack size failed!\n"); + } + } /* Start receiver thread */ if (pthread_create(&(dlt_receiverthread_handle), @@ -302,12 +316,6 @@ int dlt_init_common(void) dlt_user.dlt_ll_ts_max_num_entries = 0; dlt_user.dlt_ll_ts_num_entries = 0; - if (dlt_ringbuffer_init(&(dlt_user.rbuf), DLT_USER_RINGBUFFER_SIZE)==-1) - { - dlt_user_initialised = 0; - return -1; - } - signal(SIGPIPE,SIG_IGN); /* ignore pipe signals */ atexit(dlt_user_atexit_handler); @@ -352,6 +360,9 @@ int dlt_free(void) unlink(filename); } + /* free shared memory */ + dlt_shm_free_client(&dlt_user.dlt_shm); + if (dlt_user.dlt_log_handle!=-1) { /* close log file/output fifo to daemon */ @@ -362,9 +373,6 @@ int dlt_free(void) /* Ignore return value */ dlt_receiver_free(&(dlt_user.receiver)); - /* Ignore return value */ - dlt_ringbuffer_free(&(dlt_user.rbuf)); - if (dlt_user.dlt_ll_ts) { for (i=0;i<dlt_user.dlt_ll_ts_max_num_entries;i++) @@ -846,16 +854,8 @@ int dlt_forward_msg(void *msgdata,size_t size) /* store message in ringbuffer, if an error has occured */ if (ret!=DLT_RETURN_OK) { - DLT_SEM_LOCK(); - - if (dlt_ringbuffer_put3(&(dlt_user.rbuf), - &(userheader), sizeof(DltUserHeader), - msgdata, size, 0, 0)==-1) - { - dlt_log(LOG_ERR,"Storing message to history buffer failed! Message discarded.\n"); - } - - DLT_SEM_FREE(); + /* message could not be sent */ + /* in old implementation messages was saved in ringbuffer */ } switch (ret) @@ -2151,26 +2151,20 @@ int dlt_user_log_send_log(DltContextData *log, int mtype) } } + dlt_shm_push(&dlt_user.dlt_shm,msg.headerbuffer+sizeof(DltStorageHeader), msg.headersize-sizeof(DltStorageHeader), + log->buffer, log->size,0,0); + /* log to FIFO */ ret = dlt_user_log_out3(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), - msg.headerbuffer+sizeof(DltStorageHeader), msg.headersize-sizeof(DltStorageHeader), - log->buffer, log->size); - + 0, 0, + 0, 0); + /* store message in ringbuffer, if an error has occured */ if (ret!=DLT_RETURN_OK) { - DLT_SEM_LOCK(); - - if (dlt_ringbuffer_put3(&(dlt_user.rbuf), - &(userheader), sizeof(DltUserHeader), - msg.headerbuffer+sizeof(DltStorageHeader), msg.headersize-sizeof(DltStorageHeader), - log->buffer, log->size)==-1) - { - dlt_log(LOG_ERR,"Storing message to history buffer failed! Message discarded.\n"); - } - - DLT_SEM_FREE(); + /* in old implementation message was stored in ringbuffer + * if it was not able to be sent. */ } switch (ret) @@ -2666,14 +2660,10 @@ int dlt_user_log_check_user_message(void) void dlt_user_log_reattach_to_daemon(void) { - int num, count, reregistered=0; - - uint8_t buf[DLT_USER_RINGBUFFER_SIZE]; - size_t size; + int num, reregistered=0; DltContext handle; DltContextData log_new; - DltReturnValue ret; if (dlt_user.dlt_log_handle<0) { @@ -2726,43 +2716,8 @@ void dlt_user_log_reattach_to_daemon(void) if (reregistered==1) { - /* Send content of ringbuffer */ - DLT_SEM_LOCK(); - count = dlt_user.rbuf.count; - DLT_SEM_FREE(); - - for (num=0;num<count;num++) - { - - DLT_SEM_LOCK(); - dlt_ringbuffer_get(&(dlt_user.rbuf),buf,&size); - DLT_SEM_FREE(); - - if (size>0) - { - /* log to FIFO */ - ret = dlt_user_log_out3(dlt_user.dlt_log_handle, buf,size,0,0,0,0); - - /* in case of error, push message back to ringbuffer */ - if (ret!=DLT_RETURN_OK) - { - DLT_SEM_LOCK(); - if (dlt_ringbuffer_put(&(dlt_user.rbuf), buf, size)==-1) - { - dlt_log(LOG_ERR,"Error pushing back message to history buffer. Message discarded.\n"); - } - DLT_SEM_FREE(); - - /* In case of: data could not be written, set overflow flag */ - if (ret==DLT_RETURN_PIPE_FULL) - { - dlt_user.overflow = 1; - } - } - } - - } - } + /* In old implementation Send content of ringbuffer */ + } } } } diff --git a/src/lib/dlt_user_cfg.h b/src/lib/dlt_user_cfg.h index 31af24d..419fbc2 100755 --- a/src/lib/dlt_user_cfg.h +++ b/src/lib/dlt_user_cfg.h @@ -87,9 +87,6 @@ /* Size of receive buffer */
#define DLT_USER_RCVBUF_MAX_SIZE 10024
-/* Size of ring buffer */
-#define DLT_USER_RINGBUFFER_SIZE 10024
-
/* Temporary buffer length */
#define DLT_USER_BUFFER_LENGTH 255
@@ -106,6 +103,9 @@ /* Length of buffer for constructing text output */
#define DLT_USER_TEXT_LENGTH 10024
+/* Stack size of receiver thread */
+#define DLT_USER_RECEIVERTHREAD_STACKSIZE 100000
+
/* default value for storage to file, not used in daemon connection */
#define DLT_USER_DEFAULT_ECU_ID "ECU1"
diff --git a/src/shared/dlt_common.c b/src/shared/dlt_common.c index 4ac7dbe..d24527b 100755 --- a/src/shared/dlt_common.c +++ b/src/shared/dlt_common.c @@ -2231,469 +2231,6 @@ int dlt_check_storageheader(DltStorageHeader *storageheader) (storageheader->pattern[3] == 1)); } -int dlt_ringbuffer_init(DltRingBuffer *dltbuf, uint32_t size) -{ - - if (dltbuf==0) - { - return -1; - } - - if (size<=sizeof(uint32_t)) - { - return -1; - } - - dltbuf->buffer=(char*)malloc(size); - if (dltbuf->buffer==0) - { - return -1; - } - - dltbuf->size=size; - - dltbuf->pos_write=0; - dltbuf->pos_read=0; - - dltbuf->count=0; - - return 0; -} - -int dlt_ringbuffer_free(DltRingBuffer *dltbuf) -{ - - if (dltbuf==0) - { - return -1; - } - - if (dltbuf->buffer) - { - free(dltbuf->buffer); - } - - dltbuf->buffer=0; - - dltbuf->size=0; - - dltbuf->pos_write=0; - dltbuf->pos_read=0; - - dltbuf->count=0; - - return 0; -} - -int dlt_ringbuffer_put(DltRingBuffer *dltbuf, void *data, uint32_t size) -{ - uint32_t sui, part1, part2; - - if (dltbuf==0) - { - return -1; - } - - if (dltbuf->buffer==0) - { - return -1; - } - - if (data==0) - { - return -1; - } - - sui = sizeof(uint32_t); - - if ((size+sui)>dltbuf->size) - { - return -1; - } - - dlt_ringbuffer_checkandfreespace(dltbuf, (size+sui)); - - if (dltbuf->pos_write >= dltbuf->size) - { - dltbuf->pos_write = 0; - } - - /* Not enough space for one uint available before end of linear buffer */ - /* Start at begin of linear buffer */ - if ((dltbuf->size - dltbuf->pos_write) < sui) - { - dltbuf->pos_write = 0; - } - - /* Write length of following data to buffer */ - memcpy(&(dltbuf->buffer[dltbuf->pos_write]), &size, sui); - dltbuf->pos_write+=sui; - - if (dltbuf->pos_write >= dltbuf->size) - { - dltbuf->pos_write = 0; - } - - if ((dltbuf->size - dltbuf->pos_write) < size) - { - /* Not enough space til end of linear buffer, */ - /* split up write call */ - part1 = dltbuf->size - dltbuf->pos_write; - part2 = size - part1; - - memcpy(dltbuf->buffer + dltbuf->pos_write, data, part1); - memcpy(dltbuf->buffer, ((char*)data) + part1, part2); - dltbuf->pos_write = part2; - - } - else - { - /* Enough space til end of linear buffer */ - memcpy(&(dltbuf->buffer[dltbuf->pos_write]), data, size); - dltbuf->pos_write+=size; - } - - dltbuf->count++; - - return 0; -} - - -int dlt_ringbuffer_put3(DltRingBuffer *dltbuf, void *data1, uint32_t size1, void *data2, uint32_t size2, void *data3, uint32_t size3) -{ - uint32_t sui, part1, part2; - uint32_t total_size; - - if (dltbuf==0) - { - return -1; - } - - if (dltbuf->buffer==0) - { - return -1; - } - - sui = sizeof(uint32_t); - - total_size = size1+size2+size3; - - if ((total_size+sui)>dltbuf->size) - { - return -1; - } - - dlt_ringbuffer_checkandfreespace(dltbuf, (total_size+sui)); - - if (dltbuf->pos_write >= dltbuf->size) - { - dltbuf->pos_write = 0; - } - - /* Not enough space for one uint available before end of linear buffer */ - /* Start at begin of linear buffer */ - if ((dltbuf->size - dltbuf->pos_write) < sui) - { - dltbuf->pos_write = 0; - } - - /* Write length of following data to buffer */ - memcpy(&(dltbuf->buffer[dltbuf->pos_write]), &total_size, sui); - dltbuf->pos_write+=sui; - - if (dltbuf->pos_write >= dltbuf->size) - { - dltbuf->pos_write = 0; - } - - /* First chunk of data (data1, size1) */ - if ((dltbuf->size - dltbuf->pos_write) < size1) - { - /* Not enough space til end of linear buffer, */ - /* split up write call */ - part1 = dltbuf->size - dltbuf->pos_write; - part2 = size1 - part1; - - memcpy(dltbuf->buffer + dltbuf->pos_write, data1, part1); - memcpy(dltbuf->buffer, ((char*)data1) + part1, part2); - dltbuf->pos_write = part2; - - } - else - { - /* Enough space til end of linear buffer */ - memcpy(&(dltbuf->buffer[dltbuf->pos_write]), data1, size1); - dltbuf->pos_write+=size1; - } - - if (dltbuf->pos_write >= dltbuf->size) - { - dltbuf->pos_write = 0; - } - - /* Second chunk of data (data2, size2) */ - if ((dltbuf->size - dltbuf->pos_write) < size2) - { - /* Not enough space til end of linear buffer, */ - /* split up write call */ - part1 = dltbuf->size - dltbuf->pos_write; - part2 = size2 - part1; - - memcpy(dltbuf->buffer + dltbuf->pos_write, data2, part1); - memcpy(dltbuf->buffer, ((char*)data2) + part1, part2); - dltbuf->pos_write = part2; - - } - else - { - /* Enough space til end of linear buffer */ - memcpy(&(dltbuf->buffer[dltbuf->pos_write]), data2, size2); - dltbuf->pos_write+=size2; - } - - if (dltbuf->pos_write >= dltbuf->size) - { - dltbuf->pos_write = 0; - } - - /* Third chunk of data (data3, size3) */ - if ((dltbuf->size - dltbuf->pos_write) < size3) - { - /* Not enough space til end of linear buffer, */ - /* split up write call */ - part1 = dltbuf->size - dltbuf->pos_write; - part2 = size3 - part1; - - memcpy(dltbuf->buffer + dltbuf->pos_write, data3, part1); - memcpy(dltbuf->buffer, ((char*)data3) + part1, part2); - dltbuf->pos_write = part2; - - } - else - { - /* Enough space til end of linear buffer */ - memcpy(dltbuf->buffer + dltbuf->pos_write, data3, size3); - dltbuf->pos_write+=size3; - } - - dltbuf->count++; - - return 0; -} - -int dlt_ringbuffer_get(DltRingBuffer *dltbuf, void *data, size_t *size) -{ - uint32_t tmpsize=0; - uint32_t sui; - - uint32_t part1, part2; - - if (dltbuf==0) - { - return -1; - } - - if (dltbuf->buffer==0) - { - return -1; - } - - if (dltbuf->count==0) - { - return -1; - } - - sui = sizeof(uint32_t); - - if (dltbuf->pos_read >= dltbuf->size) - { - dltbuf->pos_read = 0; - } - - if ((dltbuf->size - dltbuf->pos_read) < sui) - { - dltbuf->pos_read = 0; - } - - /* printf("Reading at offset: %d\n", dltbuf->pos_read); */ - - memcpy(&tmpsize,&(dltbuf->buffer[dltbuf->pos_read]), sui); - dltbuf->pos_read += sui; - - if (dltbuf->pos_read >= dltbuf->size) - { - dltbuf->pos_read = 0; - } - - if ((tmpsize>0) && ((tmpsize+sizeof(uint32_t))<=dltbuf->size)) - { - if ((dltbuf->size - dltbuf->pos_read) < tmpsize) - { - /* Not enough space til end of linear buffer, */ - /* split up read call */ - part1 = dltbuf->size - dltbuf->pos_read; - part2 = tmpsize - part1; - - memcpy(data, dltbuf->buffer + dltbuf->pos_read, part1); - memcpy(((char*)data)+part1, dltbuf->buffer, part2); - dltbuf->pos_read = part2; - } - else - { - /* Enough space til end of linear buffer */ - /* no split up read call */ - memcpy(data, &(dltbuf->buffer[dltbuf->pos_read]), tmpsize); - dltbuf->pos_read+=tmpsize; - } - *size = tmpsize; - } - else - { - data=0; - *size=0; - } - - dltbuf->count--; - - return 0; -} - -int dlt_ringbuffer_get_skip(DltRingBuffer *dltbuf) -{ - uint32_t tmpsize=0; - uint32_t sui; - - uint32_t part1, part2; - - if (dltbuf==0) - { - return -1; - } - - if (dltbuf->buffer==0) - { - return -1; - } - - if (dltbuf->count==0) - { - return -1; - } - - sui = sizeof(uint32_t); - - if (dltbuf->pos_read >= dltbuf->size) - { - dltbuf->pos_read = 0; - } - - if ((dltbuf->size - dltbuf->pos_read) < sui) - { - dltbuf->pos_read = 0; - } - - memcpy(&tmpsize,&(dltbuf->buffer[dltbuf->pos_read]), sui); - dltbuf->pos_read += sui; - - if (dltbuf->pos_read >= dltbuf->size) - { - dltbuf->pos_read = 0; - } - - if ((tmpsize>0) && ((tmpsize+sui)<=dltbuf->size)) - { - if ((dltbuf->size - dltbuf->pos_read) < tmpsize) - { - /* Not enough space til end of linear buffer */ - part1 = dltbuf->size - dltbuf->pos_read; - part2 = tmpsize - part1; - - dltbuf->pos_read = part2; - } - else - { - /* Enough space til end of linear buffer */ - dltbuf->pos_read+=tmpsize; - } - } - - dltbuf->count--; - - return 0; -} - -int dlt_ringbuffer_freespacewrite(DltRingBuffer *dltbuf, uint32_t *freespace) -{ - if ((dltbuf==0) || (freespace==0)) - { - return -1; - } - - *freespace=0; - - /* Space til pos_read */ - if (dltbuf->pos_read > dltbuf->pos_write) - { - *freespace=(dltbuf->pos_read - dltbuf->pos_write); - return 0; - } - else if (dltbuf->pos_read < dltbuf->pos_write) - { - *freespace=(dltbuf->size - dltbuf->pos_write + dltbuf->pos_read ); - return 0; - } - else - { - if (dltbuf->count) - { - return 0; - } - else - { - *freespace=dltbuf->size; - return 0; - } - } - return 0; -} - -int dlt_ringbuffer_checkandfreespace(DltRingBuffer *dltbuf, uint32_t reqspace) -{ - uint32_t space_left; - - if (dltbuf==0) - { - return -1; - } - - if (dlt_ringbuffer_freespacewrite(dltbuf,&space_left) == -1) - { - return -1; - } - - /* printf("Now reading at: %d, space_left = %d, req = %d, r=%d, w=%d, count=%d \n", - dltbuf->pos_read,space_left, reqspace, dltbuf->pos_read, dltbuf->pos_write, dltbuf->count); */ - - while (space_left<reqspace) - { - /* Overwrite, correct read position */ - - /* Read and skip one element */ - dlt_ringbuffer_get_skip(dltbuf); - - /* Space until pos_read */ - if (dlt_ringbuffer_freespacewrite(dltbuf,&space_left) == -1) - { - return -1; - } - - /* printf("Overwrite: Now reading at: %d, space_left = %d, req = %d, r=%d, w=%d, count=%d \n", - dltbuf->pos_read,space_left, reqspace, dltbuf->pos_read, dltbuf->pos_write, dltbuf->count); */ - } - - return 0; -} - #if !defined (__WIN32__) int dlt_setup_serial(int fd, speed_t speed) diff --git a/src/shared/dlt_shm.c b/src/shared/dlt_shm.c new file mode 100644 index 0000000..e3ec7c6 --- /dev/null +++ b/src/shared/dlt_shm.c @@ -0,0 +1,563 @@ +/* +* 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_shm.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 <sys/types.h> +#include <sys/ipc.h> +#include <sys/shm.h> +#include <sys/sem.h> +#include <sys/stat.h> +#include <stdio.h> +#include <string.h> + +#include <dlt_shm.h> + +void dlt_shm_print_hex(char *ptr,int size) +{ + int num; + + for (num=0;num<size;num++) + { + if((num%16)==15) + printf("%.2x\n",((unsigned char*)ptr)[num]); + else + printf("%.2x ",((unsigned char*)ptr)[num]); + } + printf("\n"); +} + +void dlt_shm_pv(int id,int operation) +{ + static struct sembuf semaphor; + + semaphor.sem_op = operation; + semaphor.sem_flg = SEM_UNDO; + + if(semop(id, &semaphor,1) == -1) { + perror("semop"); + } +} + +int dlt_shm_init_server(DltShm *buf,int key,int size) { + struct shmid_ds shm_buf; + + // Init parameters + buf->shm = NULL; + buf->shmid = 0; + buf->semid = 0; + buf->size = 0; + buf->mem = 0; + + // Create the segment. + if ((buf->shmid = shmget(key, size, IPC_CREAT | 0666)) < 0) { + perror("shmget"); + return -1; /* ERROR */ + } + + // get the size of shm + if (shmctl(buf->shmid, IPC_STAT, &shm_buf)) + { + perror("shmctl"); + return -1; /* ERROR */ + } + + // Now we attach the segment to our data space. + if ((buf->shm = shmat(buf->shmid, NULL, 0)) == (char *) -1) { + perror("shmat"); + return -1; /* ERROR */ + } + + // Init semaphore + if( (buf->semid = semget(DLT_SHM_SEM,1,S_IRWXU|S_IRWXG|IPC_CREAT|IPC_EXCL)) == -1 ) { + if( (buf->semid = semget(DLT_SHM_SEM,1,S_IRWXU|S_IRWXG|IPC_EXCL)) == -1 ) { + perror("semget"); + return -1; /* ERROR */ + } + } + if( semctl(buf->semid,0,SETVAL,(int)1) == -1 ) { + perror("semctl"); + return -1; /* ERROR */ + } + + // Init pointers + ((int*)(buf->shm))[0] = 0; // pointer to write memory + ((int*)(buf->shm))[1] = 0; // pointer to read memory + ((int*)(buf->shm))[2] = 0; // number of packets + buf->mem = (char*)(&(((int*)(buf->shm))[3])); + buf->size = shm_buf.shm_segsz - (buf->mem - buf->shm); + + // clear memory + memset(buf->mem,0,buf->size); + + //dlt_shm_status(buf); + //dlt_shm_info(buf); + printf("SHM: Size %d\n",buf->size); + + return 0; /* OK */ +} + +int dlt_shm_init_client(DltShm *buf,int key) { + struct shmid_ds shm_buf; + + // init parameters + buf->shm = NULL; + buf->shmid = 0; + buf->semid = 0; + buf->size = 0; + buf->mem = 0; + + // Create the segment. + if ((buf->shmid = shmget(key, 0, 0666)) < 0) { + perror("shmget"); + return -1; /* ERROR */ + } + + // get the size of shm + if (shmctl(buf->shmid, IPC_STAT, &shm_buf)) + { + perror("shmctl"); + return -1; /* ERROR */ + } + + // Now we attach the segment to our data space. + if ((buf->shm = shmat(buf->shmid, NULL, 0)) == (char *) -1) { + perror("shmat"); + return -1; /* ERROR */ + } + + // Init semaphore + if( (buf->semid = semget(DLT_SHM_SEM,0,0)) == -1 ) { + perror("semget"); + return -1; /* ERROR */ + } + DLT_SHM_SEM_FREE(buf->semid); + + // Init pointers + buf->mem = (char*)(&(((int*)(buf->shm))[3])); + buf->size = shm_buf.shm_segsz - (buf->mem - buf->shm); + + //dlt_shm_status(buf); + //dlt_shm_info(buf); + + return 0; /* OK */ +} + +void dlt_shm_info(DltShm *buf) +{ + + printf("SHM id: %d\n",buf->shmid); + printf("Available size: %d\n",buf->size); + printf("SHM full start address: %lX\n",(unsigned long)buf->shm); + printf("SHM start address: %lX\n",(unsigned long)buf->mem); + +} + +void dlt_shm_status(DltShm *buf) +{ + int write, read, count; + + write = ((int*)(buf->shm))[0]; + read = ((int*)(buf->shm))[1]; + count = ((int*)(buf->shm))[2]; + + printf("Write: %d\n",write); + printf("Read: %d\n",read); + printf("Count: %d\n",count); + +} + +int dlt_shm_push(DltShm *buf,const unsigned char *data1,unsigned int size1,const unsigned char *data2,unsigned int size2,const unsigned char *data3,unsigned int size3) +{ + int write, read, count; + + if(!buf->mem) { + // shm not initialised + printf("SHM not initialised\n"); + return -1; /* ERROR */ + } + + // get semaphore + DLT_SHM_SEM_GET(buf->semid); + + // get current write pointer + write = ((int*)(buf->shm))[0]; + read = ((int*)(buf->shm))[1]; + count = ((int*)(buf->shm))[2]; + + // check space and write pointer + if(read==write && count) { + // shm buffer is full + DLT_SHM_SEM_FREE(buf->semid); + //printf("SHM is totally full\n"); + return -1; // ERROR + } + else if(write >= buf->size) { + if((size1+size2+size3+sizeof(unsigned char)+sizeof(int)) > read) { + DLT_SHM_SEM_FREE(buf->semid); + //printf("SHM is full at start\n"); + return -1; // ERROR + } + write = 0; + } + else if(read > write) { + if((write + size1+size2+size3+sizeof(unsigned char)+sizeof(int)) > read) { + DLT_SHM_SEM_FREE(buf->semid); + //printf("SHM is full at end\n"); + return -1; // ERROR + } + } + else // read <= write + { + if((write+size1+size2+size3+sizeof(unsigned char)+sizeof(int)) > buf->size) { + // data does not fit at end of buffer + // try write at beginning + if((size1+size2+size3+sizeof(unsigned char)+sizeof(int)) > read) { + DLT_SHM_SEM_FREE(buf->semid); + //printf("SHM is full at start\n"); + return -1; // ERROR + } + // write zero status and size at end if possible + if((write+sizeof(unsigned char)+sizeof(int)) <= buf->size) { + *((unsigned char*)(buf->mem+write)) = 0; // init write status to unused + *((int*)(buf->mem+write+sizeof(unsigned char))) = 0; // init write size to unused + } + + write = 0; + } + } + + // update global shm pointers + ((int*)(buf->shm))[0] = write+sizeof(unsigned char)+sizeof(int)+size1+size2+size3; // set new write pointer + ((int*)(buf->shm))[2] += 1; // increase counter + + // update buffer pointers + *((unsigned char*)(buf->mem+write)) = 1; // set write status + *((int*)(buf->mem+write+sizeof(unsigned char))) = size1+size2+size3; // set write size + + // free semaphore + DLT_SHM_SEM_FREE(buf->semid); + + // write data + if(data1) + memcpy(buf->mem+write+sizeof(unsigned char)+sizeof(int),data1,size1); + if(data2) + memcpy(buf->mem+write+sizeof(unsigned char)+sizeof(int)+size1,data2,size2); + if(data3) + memcpy(buf->mem+write+sizeof(unsigned char)+sizeof(int)+size1+size2,data3,size3); + + // update write status + *((unsigned char*)(buf->mem+write)) = 2; + + return 0; // OK +} + +int dlt_shm_pull(DltShm *buf,unsigned char *data, int max_size) +{ + int write, read, count, size; + unsigned char status; + + if(!buf->mem) { + // shm not initialised + printf("SHM not initialised\n"); + return -1; /* ERROR */ + } + + // get current write pointer + DLT_SHM_SEM_GET(buf->semid); + write = ((int*)(buf->shm))[0]; + read = ((int*)(buf->shm))[1]; + count = ((int*)(buf->shm))[2]; + DLT_SHM_SEM_FREE(buf->semid); + + // check if data is in there + if(count<=0) { + //printf("SHM is empty\n"); + return -1; // ERROR + } + + // check if end of buffer is reached and read status and size + if((read+sizeof(unsigned char)+sizeof(int)) <= buf->size) { + status = *((unsigned char*)(buf->mem+read)); + size = *((int*)(buf->mem+read+sizeof(unsigned char))); + if(status == 0) { + // data fits not end of shm + read = 0; + status = *((unsigned char*)(buf->mem+read)); + size = *((int*)(buf->mem+read+sizeof(unsigned char))); + } + } + else { + read = 0; + status = *((unsigned char*)(buf->mem+read)); + size = *((int*)(buf->mem+read+sizeof(unsigned char))); + } + + // check status + if(status != 2 ) { + //printf("Buffer is not fully written\n"); + return -1; // ERROR + } + + // plausibility check of buffer size + if( (read+size) > buf->size) { + printf("Buffers size bigger than shm buffer\n"); + return -1; // ERROR + } + + // check max read size + if(size > max_size) { + printf("Buffer is bigger than max size\n"); + return -1; // ERROR + } + + // copy data + memcpy(data,buf->mem+read+sizeof(unsigned char)+sizeof(int),size); + + // update buffer pointers + ((int*)(buf->shm))[1] = read+sizeof(unsigned char)+sizeof(int)+size; // set new read pointer + ((int*)(buf->shm))[2] -= 1; // decrease counter + + return size; // OK +} + +int dlt_shm_copy(DltShm *buf,unsigned char *data, int max_size) +{ + int write, read, count, size; + unsigned char status; + + if(!buf->mem) { + // shm not initialised + printf("SHM not initialised\n"); + return -1; /* ERROR */ + } + + // get current write pointer + DLT_SHM_SEM_GET(buf->semid); + write = ((int*)(buf->shm))[0]; + read = ((int*)(buf->shm))[1]; + count = ((int*)(buf->shm))[2]; + DLT_SHM_SEM_FREE(buf->semid); + + // check if data is in there + if(count<=0) { + //printf("SHM is empty\n"); + return -1; // ERROR + } + + // check if end of buffer is reached and read status and size + if((read+sizeof(unsigned char)+sizeof(int)) <= buf->size) { + status = *((unsigned char*)(buf->mem+read)); + size = *((int*)(buf->mem+read+sizeof(unsigned char))); + if(status == 0) { + // data fits not end of shm + read = 0; + status = *((unsigned char*)(buf->mem+read)); + size = *((int*)(buf->mem+read+sizeof(unsigned char))); + } + } + else { + read = 0; + status = *((unsigned char*)(buf->mem+read)); + size = *((int*)(buf->mem+read+sizeof(unsigned char))); + } + + // check status + if(status != 2 ) { + //printf("Buffer is not fully written\n"); + return -1; // ERROR + } + + // plausibility check of buffer size + if( (read+size) > buf->size) { + printf("Buffers size bigger than shm buffer\n"); + return -1; // ERROR + } + + // check max read size + if(size > max_size) { + printf("Buffer is bigger than max size\n"); + return -1; // ERROR + } + + // copy data + memcpy(data,buf->mem+read+sizeof(unsigned char)+sizeof(int),size); + + return size; // OK +} + +int dlt_shm_remove(DltShm *buf) +{ + int write, read, count, size; + unsigned char status; + + if(!buf->mem) { + // shm not initialised + printf("SHM not initialised\n"); + return -1; /* ERROR */ + } + + // get current write pointer + DLT_SHM_SEM_GET(buf->semid); + write = ((int*)(buf->shm))[0]; + read = ((int*)(buf->shm))[1]; + count = ((int*)(buf->shm))[2]; + DLT_SHM_SEM_FREE(buf->semid); + + // check if data is in there + if(count<=0) { + //printf("SHM is empty\n"); + return -1; // ERROR + } + + // check if end of buffer is reached and read status and size + if((read+sizeof(unsigned char)+sizeof(int)) <= buf->size) { + status = *((unsigned char*)(buf->mem+read)); + size = *((int*)(buf->mem+read+sizeof(unsigned char))); + if(status == 0) { + // data fits not end of shm + read = 0; + status = *((unsigned char*)(buf->mem+read)); + size = *((int*)(buf->mem+read+sizeof(unsigned char))); + } + } + else { + read = 0; + status = *((unsigned char*)(buf->mem+read)); + size = *((int*)(buf->mem+read+sizeof(unsigned char))); + } + + // check status + if(status != 2 ) { + //printf("Buffer is not fully written\n"); + return -1; // ERROR + } + + // plausibility check of buffer size + if( (read+size) > buf->size) { + printf("Buffers size bigger than shm buffer\n"); + return -1; // ERROR + } + + // update buffer pointers + ((int*)(buf->shm))[1] = read+sizeof(unsigned char)+sizeof(int)+size; // set new read pointer + ((int*)(buf->shm))[2] -= 1; // decrease counter + + return size; // OK +} + +int dlt_shm_free_server(DltShm *buf) { + + if(!buf->shm) { + printf("Shared memory segment not attached\n"); + return -1; /* ERROR */ + } + + if(shmdt(buf->shm)) { + perror("shmdt"); + return -1; /* ERROR */ + } + + if(shmctl(buf->shmid,IPC_RMID,NULL) == -1) { + perror("shmdt"); + return -1; /* ERROR */ + } + + if(semctl(buf->semid,0,IPC_RMID,(int)0) == -1) { + perror("shmdt"); + return -1; /* ERROR */ + } + + // Reset parameters + buf->shm = NULL; + buf->shmid = 0; + buf->semid = 0; + buf->size = 0; + buf->mem = 0; + + return 0; /* OK */ +} + +int dlt_shm_free_client(DltShm *buf) { + + if(!buf->shm) { + printf("Shared memory segment not attached\n"); + return -1; /* ERROR */ + } + + if(shmdt(buf->shm)) { + perror("shmdt"); + return -1; /* ERROR */ + } + + // Reset parameters + buf->shm = NULL; + buf->shmid = 0; + buf->semid = 0; + buf->size = 0; + buf->mem = 0; + + return 0; /* OK */ +} diff --git a/src/tests/dlt-test-internal.c b/src/tests/dlt-test-internal.c index 00209f1..02142b9 100755 --- a/src/tests/dlt-test-internal.c +++ b/src/tests/dlt-test-internal.c @@ -179,11 +179,6 @@ int main(int argc, char* argv[]) return -1; } - if (test[0]) - { - internal1(); - } - printf("\n"); printf("%d tests passed\n",tests_passed); printf("%d tests failed\n",tests_failed); @@ -191,117 +186,3 @@ int main(int argc, char* argv[]) return 0; } -void internal1(void) -{ - int index,result_index; - unsigned int c; - unsigned int size; - - char buf[1024],result[1024]; - - DltRingBuffer mybuf; - - printf("Test1i: Ringbuffer, writing and reading \n"); - - for (size=8;size<=30;size++) - { - - dlt_ringbuffer_init(&mybuf, size); - - memset(result,0,1024); - - if (vflag) - { - printf("\nRingbuffer Size = %d \n\n",size); - } - - /* Write several times to ringbuffer */ - for (index=0; index<6; index++) - { - memset(buf,0,1024); - - sprintf(buf,"%d",index); - dlt_ringbuffer_put(&mybuf,buf,strlen(buf)); - - if (vflag) - { - printf("W[%d], Bytes = %d, Hex: ", index, strlen(buf)); - dlt_print_hex((uint8_t *)buf, strlen(buf)); - printf("\n"); - } - } - - if (vflag) - { - printf("\nCount=%d, Max. by buffer size %d = %d\n",mybuf.count, size, (int)(size/(strlen(buf)+sizeof(unsigned int)))); - } - - /* Check value of mybuf.count, counting the elements in ringbuffer */ - if (mybuf.count!=(int)(size/(strlen(buf)+sizeof(unsigned int)))) - { - tests_failed++; - printf("Test1i FAILED\n"); - - break; - } - - result_index = 0; - - /* Read several times from ringbuffer */ - for (index=0; index<6; index++) - { - memset(buf,0,1024); - - if (dlt_ringbuffer_get(&mybuf,buf,&c)!=-1) - { - if (vflag) - { - printf("R[%d], Bytes = %d, Hex: ", index, c); - dlt_print_hex((uint8_t *)buf, c); - printf("\n"); - } - - if (c==1) - { - result[result_index] = buf[0]; - } - result_index++; - } - } - - /* Check value of mybuf.count, counting the elements in ringbuffer, must be 0 now */ - if (mybuf.count!=0) - { - tests_failed++; - printf("Test1i FAILED\n"); - - dlt_ringbuffer_free(&mybuf); - return; - } - - /* Check the read elements */ - for (index=0; index<result_index; index++) - { - sprintf(buf,"%d",((6-result_index)+index)); - if (result[index]!=buf[0]) - { - tests_failed++; - printf("Test1i FAILED\n"); - - dlt_ringbuffer_free(&mybuf); - return; - } - } - - if (vflag) - { - printf("\n"); - } - - dlt_ringbuffer_free(&mybuf); - } - - tests_passed++; - printf("Test1i PASSED\n"); -} - diff --git a/src/tests/dlt-test-stress.c b/src/tests/dlt-test-stress.c index ea17857..07b3ae9 100755 --- a/src/tests/dlt-test-stress.c +++ b/src/tests/dlt-test-stress.c @@ -98,7 +98,7 @@ typedef struct } thread_data_t; #define STRESS1_NUM_CONTEXTS 3000 -#define STRESS2_MAX_NUM_THREADS 256 +#define STRESS2_MAX_NUM_THREADS 64 #define STRESS3_MAX_NUM_MESSAGES 512 #define MAX_TESTS 3 @@ -319,10 +319,7 @@ void stress2(void) for (index=0;index<STRESS2_MAX_NUM_THREADS;index++) { - if (thread[index]!=0) - { - pthread_join(thread[index], NULL); - } + pthread_join(thread[index], NULL); } printf("Finished stress test2 \n\n"); @@ -366,7 +363,7 @@ void stress3(void) { buffer[num] = num; DLT_LOG(context_stress3,DLT_LOG_INFO,DLT_INT(num),DLT_RAW(buffer,num)); - usleep(1); + usleep(10000); } printf("Finished stress test3 \n\n"); diff --git a/testscripts/dlt.conf b/testscripts/dlt.conf new file mode 100644 index 0000000..ac4cdf8 --- /dev/null +++ b/testscripts/dlt.conf @@ -0,0 +1,81 @@ +# Configuration file of DLT daemon +# +# Configurations made here will overwrite settings by command line + +######################################################################## +# General configuration # +######################################################################## + +# Start daemon in dubug mode, so that all internal debug information is printed out on the console +# Verbose = 1 + +# Daemonize DLT daemon, if it is started as daemon +# Daemonize = 1 + +# Send DLT messages with serial header +# SendSerialHeader = 1 + +# Send automatic get log info response during context registration +# SendContextRegistration = 1 + +# Send automatic time packets every second if client is connected (Default: 0) +SendMessageTime = 1 + +# Set ECU ID (Default: ECU1) +ECUId = ENAT + +# Size of shared memory (Default: 100000) +SharedMemorySize = 4000000 + +# Directory where to store the persistant configuration (Default: /tmp) +PersistanceStoragePath = /home/alex/tmp + +######################################################################## +# Offline Trace memory # +######################################################################## + +# Store DLT messages to local directory, if not set offline Trace is off (Default: off) +OfflineTraceDirectory = /home/alex/tmp + +# Maximum size in bytes of one trace file (Default: 1000000) +OfflineTraceFileSize = 1000000 + +# Maximum size of all trace files (Default: 4000000) +OfflineTraceMaxSize = 4000000 + +######################################################################## +# Local console output configuration # +######################################################################## + +# Print DLT messages; payload as ASCII +# PrintASCII = 1 + +# Print DLT messages; payload as hex +# PrintHex = 1 + +# Print DLT messages; only headers +# PrintHeadersOnly = 1 + + +######################################################################## +# Client Serial port configuration # +######################################################################## + +# Additional support for serial device +# If a device name is set serial port is enabled. +# RS232DeviceName = /dev/ttyS0 + +# Serial device baudrate (Default: 115200) +# RS232Baudrate = 115200 + +# Sync to serial header on serial connection +# RS232SyncSerialHeader = 1 + +######################################################################## +# TCP Serial port configuration # +######################################################################## + +# Sync to serial header on all TCP connections +# TCPSyncSerialHeader = 1 + + |