diff options
Diffstat (limited to 'src')
48 files changed, 20621 insertions, 0 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100755 index 0000000..28a249a --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,44 @@ +####### +# Dlt - Diagnostic Log and Trace +# @licence make 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@ +######## + +ADD_SUBDIRECTORY( lib ) +ADD_SUBDIRECTORY( console ) +ADD_SUBDIRECTORY( daemon ) +ADD_SUBDIRECTORY( examples ) +ADD_SUBDIRECTORY( adaptor ) +ADD_SUBDIRECTORY( tests ) + diff --git a/src/adaptor/CMakeLists.txt b/src/adaptor/CMakeLists.txt new file mode 100755 index 0000000..8a04377 --- /dev/null +++ b/src/adaptor/CMakeLists.txt @@ -0,0 +1,52 @@ +####### +# Dlt - Diagnostic Log and Trace +# @licence make 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@ +######## + +set(dlt_adaptor_stdin_SRCS dlt-adaptor-stdin) +add_executable(dlt-adaptor-stdin ${dlt_adaptor_stdin_SRCS}) +target_link_libraries(dlt-adaptor-stdin dlt) +set_target_properties(dlt-adaptor-stdin PROPERTIES LINKER_LANGUAGE C) + +set(dlt_adaptor_udp_SRCS dlt-adaptor-udp) +add_executable(dlt-adaptor-udp ${dlt_adaptor_udp_SRCS}) +target_link_libraries(dlt-adaptor-udp dlt) +set_target_properties(dlt-adaptor-udp PROPERTIES LINKER_LANGUAGE C) + +install(TARGETS dlt-adaptor-stdin dlt-adaptor-udp + RUNTIME DESTINATION bin + COMPONENT base) + + diff --git a/src/adaptor/dlt-adaptor-stdin.c b/src/adaptor/dlt-adaptor-stdin.c new file mode 100755 index 0000000..c0d7c0f --- /dev/null +++ b/src/adaptor/dlt-adaptor-stdin.c @@ -0,0 +1,160 @@ +/* + * Dlt Adaptor for forwarding Standard In messages to Dlt + * @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-adaptor-stdin.c ** +** ** +** TARGET : linux ** +** ** +** PROJECT : DLT ** +** ** +** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** +** Markus Klein ** +** ** +** PURPOSE : ** +** ** +** REMARKS : ** +** ** +** PLATFORM DEPENDANT [yes/no]: yes ** +** ** +** TO BE CHANGED BY USER [yes/no]: no ** +** ** +*******************************************************************************/ + +/******************************************************************************* +** Author Identity ** +******************************************************************************** +** ** +** Initials Name Company ** +** -------- ------------------------- ---------------------------------- ** +** aw Alexander Wenzel BMW ** +** mk Markus Klein Fraunhofer ESK ** +*******************************************************************************/ + +/******************************************************************************* +** Revision Control History ** +*******************************************************************************/ + +/* + * $LastChangedRevision: 1670 $ + * $LastChangedDate: 2011-04-08 15:12:06 +0200 (Fr, 08. Apr 2011) $ + * $LastChangedBy$ +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "dlt_common.h" +#include "dlt_user.h" + +#define MAXSTRLEN 1024 + +#define PS_DLT_APP_DESC "stdin adaptor application" +#define PS_DLT_CONTEXT_DESC "stdin adaptor context" + +#define PS_DLT_APP "SINA" +#define PS_DLT_CONTEXT "SINC" + +DLT_DECLARE_CONTEXT(mycontext); + +int main(int argc, char* argv[]) +{ + char str[MAXSTRLEN]; + int opt; + + char apid[DLT_ID_SIZE]; + char ctid[DLT_ID_SIZE]; + char version[255]; + + dlt_set_id(apid, PS_DLT_APP); + dlt_set_id(ctid, PS_DLT_CONTEXT); + + while ((opt = getopt(argc, argv, "a:c:h")) != -1) + { + switch (opt) + { + case 'a': + { + dlt_set_id(apid,optarg); + break; + } + case 'c': + { + dlt_set_id(ctid,optarg); + break; + } + case 'h': + { + dlt_get_version(version); + + printf("Usage: dlt-adaptor-stdin [options]\n"); + printf("Adaptor for forwarding input from stdin to DLT daemon.\n"); + printf("%s \n", version); + printf("Options:\n"); + printf("-a apid - Set application id to apid (default: SINA)\n"); + printf("-c ctid - Set context id to ctid (default: SINC)\n"); + printf("-h - This help\n"); + return 0; + break; + } + default: /* '?' */ + { + fprintf(stderr, "Unknown option '%c'\n", optopt); + return -1; + } + } + } + + DLT_REGISTER_APP(apid,PS_DLT_APP_DESC); + DLT_REGISTER_CONTEXT(mycontext, ctid, PS_DLT_CONTEXT_DESC); + + while (fgets(str, MAXSTRLEN, stdin)) + { + if (strcmp(str,"")!=0) + { + DLT_LOG(mycontext, DLT_LOG_INFO, DLT_STRING(str)); + } + } + + DLT_UNREGISTER_CONTEXT(mycontext); + DLT_UNREGISTER_APP(); + + return 0; +} + diff --git a/src/adaptor/dlt-adaptor-udp.c b/src/adaptor/dlt-adaptor-udp.c new file mode 100755 index 0000000..a86a157 --- /dev/null +++ b/src/adaptor/dlt-adaptor-udp.c @@ -0,0 +1,222 @@ +/* + * Dlt Adaptor for forwarding Syslog messages to Dlt + * @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-adaptor-udp.c ** +** ** +** TARGET : linux ** +** ** +** PROJECT : DLT ** +** ** +** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** +** Markus Klein ** +** ** +** PURPOSE : ** +** ** +** REMARKS : ** +** ** +** PLATFORM DEPENDANT [yes/no]: yes ** +** ** +** TO BE CHANGED BY USER [yes/no]: no ** +** ** +*******************************************************************************/ + +/******************************************************************************* +** Author Identity ** +******************************************************************************** +** ** +** Initials Name Company ** +** -------- ------------------------- ---------------------------------- ** +** aw Alexander Wenzel BMW ** +** mk Markus Klein Fraunhofer ESK ** +*******************************************************************************/ + +/******************************************************************************* +** Revision Control History ** +*******************************************************************************/ + +/* + * $LastChangedRevision: 1670 $ + * $LastChangedDate: 2011-04-08 15:12:06 +0200 (Fr, 08. Apr 2011) $ + * $LastChangedBy$ + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <signal.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <errno.h> + +#include "dlt_common.h" +#include "dlt_user.h" + +/* Port number, to which the syslogd-ng sends its log messages */ +#define RCVPORT 47111 + +#define MAXSTRLEN 1024 + +#define PU_DLT_APP_DESC "udp adaptor application" +#define PU_DLT_CONTEXT_DESC "udp adaptor context" + +#define PU_DLT_APP "UDPA" +#define PU_DLT_CONTEXT "UDPC" + +DLT_DECLARE_CONTEXT(mycontext); + +int main(int argc, char* argv[]) +{ + int sock; + int bytes_read; + socklen_t addr_len; + int opt, port; + char recv_data[MAXSTRLEN]; + struct sockaddr_in client_addr, server_addr; + + char apid[DLT_ID_SIZE]; + char ctid[DLT_ID_SIZE]; + char version[255]; + + dlt_set_id(apid, PU_DLT_APP); + dlt_set_id(ctid, PU_DLT_CONTEXT); + + port = RCVPORT; + + while ((opt = getopt(argc, argv, "a:c:hp:")) != -1) + { + switch (opt) + { + case 'a': + { + dlt_set_id(apid,optarg); + break; + } + case 'c': + { + dlt_set_id(ctid,optarg); + break; + } + case 'h': + { + dlt_get_version(version); + + printf("Usage: dlt-adaptor-udp [options]\n"); + printf("Adaptor for forwarding received UDP messages to DLT daemon.\n"); + printf("%s \n", version); + printf("Options:\n"); + printf("-a apid - Set application id to apid (default: UDPA)\n"); + printf("-c ctid - Set context id to ctid (default: UDPC)\n"); + printf("-p - Set receive port number for UDP messages (default: %d) \n", port); + printf("-h - This help\n"); + return 0; + break; + } + case 'p': + { + port = atoi(optarg); + break; + } + default: /* '?' */ + { + fprintf(stderr, "Unknown option '%c'\n", optopt); + exit(3); + } + } + } + + if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) + { + perror("Socket"); + exit(1); + } + + server_addr.sin_family = AF_INET; + server_addr.sin_port = htons(port); + server_addr.sin_addr.s_addr = INADDR_ANY; + bzero(&(server_addr.sin_zero), 8); + + + if (bind(sock, (struct sockaddr *)&server_addr, + sizeof(struct sockaddr)) == -1) + { + perror("Bind"); + return -1; + } + + addr_len = sizeof(struct sockaddr); + + DLT_REGISTER_APP(apid,PU_DLT_APP_DESC); + DLT_REGISTER_CONTEXT(mycontext,ctid,PU_DLT_CONTEXT_DESC); + + while (1) + { + bytes_read = 0; + + bytes_read = recvfrom(sock, recv_data, MAXSTRLEN, 0, + (struct sockaddr *)&client_addr, &addr_len); + + if (bytes_read == -1) + { + if (errno == EINTR) + { + continue; + } + else + { + DLT_UNREGISTER_CONTEXT(mycontext); + DLT_UNREGISTER_APP(); + exit(1); + } + } + + recv_data[bytes_read] = '\0'; + + if (bytes_read != 0) + { + DLT_LOG(mycontext, DLT_LOG_INFO, DLT_STRING(recv_data)); + } + } + + DLT_UNREGISTER_CONTEXT(mycontext); + DLT_UNREGISTER_APP(); + + return 0; +} diff --git a/src/console/CMakeLists.txt b/src/console/CMakeLists.txt new file mode 100755 index 0000000..6cc03ac --- /dev/null +++ b/src/console/CMakeLists.txt @@ -0,0 +1,51 @@ +####### +# Dlt - Diagnostic Log and Trace +# @licence make 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@ +######## + +set(dlt_convert_SRCS dlt-convert) +add_executable(dlt-convert ${dlt_convert_SRCS} ${dlt_most_SRCS}) +target_link_libraries(dlt-convert dlt ${EXPAT_LIBRARIES}) +set_target_properties(dlt-convert PROPERTIES LINKER_LANGUAGE C) + +set(dlt_receive_SRCS dlt-receive) +add_executable(dlt-receive ${dlt_receive_SRCS} ${dlt_most_SRCS}) +target_link_libraries(dlt-receive dlt ${EXPAT_LIBRARIES}) +set_target_properties(dlt-receive PROPERTIES LINKER_LANGUAGE C) + +install(TARGETS dlt-convert dlt-receive + RUNTIME DESTINATION bin + COMPONENT base) + diff --git a/src/console/dlt-convert.c b/src/console/dlt-convert.c new file mode 100755 index 0000000..e86912a --- /dev/null +++ b/src/console/dlt-convert.c @@ -0,0 +1,417 @@ +/* + * Dlt Client console utilities - Diagnostic Log and Trace + * @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-convert.cpp ** +** ** +** TARGET : linux ** +** ** +** PROJECT : DLT ** +** ** +** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** +** Markus Klein ** +** ** +** PURPOSE : ** +** ** +** REMARKS : ** +** ** +** PLATFORM DEPENDANT [yes/no]: yes ** +** ** +** TO BE CHANGED BY USER [yes/no]: no ** +** ** +*******************************************************************************/ + +/******************************************************************************* +** Author Identity ** +******************************************************************************** +** ** +** Initials Name Company ** +** -------- ------------------------- ---------------------------------- ** +** aw Alexander Wenzel BMW ** +** mk Markus Klein Fraunhofer ESK ** +*******************************************************************************/ + +/******************************************************************************* +** Author Identity ** +******************************************************************************** +** ** +** Initials Name Company ** +** -------- ------------------------- ---------------------------------- ** +** aw Alexander Wenzel BMW ** +*******************************************************************************/ + +/******************************************************************************* +** Revision Control History ** +*******************************************************************************/ + +/* + * $LastChangedRevision: 1670 $ + * $LastChangedDate: 2011-04-08 15:12:06 +0200 (Fr, 08. Apr 2011) $ + * $LastChangedBy$ + Initials Date Comment + aw 13.01.2010 initial + */ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <ctype.h> + +#include <sys/stat.h> +#include <fcntl.h> + +#include <sys/uio.h> /* writev() */ + +#include "dlt_common.h" + +#define DLT_CONVERT_TEXTBUFSIZE 10024 /* Size of buffer for text output */ + +/** + * Print usage information of tool. + */ +void usage() +{ + char version[DLT_CONVERT_TEXTBUFSIZE]; + + dlt_get_version(version); + + printf("Usage: dlt-convert [options] [commands] file1 [file2]\n"); + printf("Read DLT files, print DLT messages as ASCII and store the messages again.\n"); + printf("Use filters to filter DLT messages.\n"); + printf("Use Ranges and Output file to cut DLT files.\n"); + printf("Use two files and Output file to join DLT files.\n"); + printf("%s \n", version); + printf("Commands:\n"); + printf(" -h Usage\n"); + printf(" -a Print DLT file; payload as ASCII\n"); + printf(" -x Print DLT file; payload as hex\n"); + printf(" -m Print DLT file; payload as hex and ASCII\n"); + printf(" -s Print DLT file; only headers\n"); + printf(" -o filename Output messages in new DLT file\n"); + printf("Options:\n"); + printf(" -v Verbose mode\n"); + printf(" -c Count number of messages\n"); + printf(" -f filename Enable filtering of messages\n"); + printf(" -b number First messages to be handled\n"); + printf(" -e number Last message to be handled\n"); + printf(" -w Follow dlt file while file is increasing\n"); +} + +/** + * Main function of tool. + */ +int main(int argc, char* argv[]) +{ + int vflag = 0; + int cflag = 0; + int aflag = 0; + int sflag = 0; + int xflag = 0; + int mflag = 0; + int wflag = 0; + char *fvalue = 0; + char *bvalue = 0; + char *evalue = 0; + char *ovalue = 0; + + int index; + int c; + + DltFile file; + DltFilter filter; + + int ohandle=-1; + + int num, begin, end; + + char text[DLT_CONVERT_TEXTBUFSIZE]; + + struct iovec iov[2]; + int bytes_written; + + opterr = 0; + + while ((c = getopt (argc, argv, "vcashxmwf:b:e:o:")) != -1) + switch (c) + { + case 'v': + { + vflag = 1; + break; + } + case 'c': + { + cflag = 1; + break; + } + case 'a': + { + aflag = 1; + break; + } + case 's': + { + sflag = 1; + break; + } + case 'x': + { + xflag = 1; + break; + } + case 'm': + { + mflag = 1; + break; + } + case 'w': + { + wflag = 1; + break; + } + case 'h': + { + usage(); + return -1; + } + case 'f': + { + fvalue = optarg; + break; + } + case 'b': + { + bvalue = optarg; + break; + } + case 'e': + { + evalue = optarg; + break; + } + case 'o': + { + ovalue = optarg; + break; + } + case '?': + { + if (optopt == 'f' || optopt == 'b' || optopt == 'e' || optopt == 'o') + { + fprintf (stderr, "Option -%c requires an argument.\n", optopt); + } + else if (isprint (optopt)) + { + fprintf (stderr, "Unknown option `-%c'.\n", optopt); + } + else + { + fprintf (stderr, "Unknown option character `\\x%x'.\n",optopt); + } + /* unknown or wrong option used, show usage information and terminate */ + usage(); + return -1; + } + default: + { + abort(); + } + } + + /* initialise structure to use DLT file */ + dlt_file_init(&file,vflag); + + /* first parse filter file if filter parameter is used */ + if (fvalue) + { + if (dlt_filter_load(&filter,fvalue,vflag)<0) + { + dlt_file_free(&file,vflag); + return -1; + } + + dlt_file_set_filter(&file,&filter,vflag); + } + + if (ovalue) + { + ohandle = open(ovalue,O_WRONLY|O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); /* mode: wb */ + if (ohandle == -1) + { + dlt_file_free(&file,vflag); + fprintf(stderr,"ERROR: Output file %s cannot be opened!\n",ovalue); + return -1; + } + + } + + for (index = optind; index < argc; index++) + { + /* load, analyse data file and create index list */ + if (dlt_file_open(&file,argv[index],vflag)>=0) + { + while (dlt_file_read(&file,vflag)>=0) + { + } + } + + if (aflag || sflag || xflag || mflag || ovalue) + { + if (bvalue) + { + begin = atoi(bvalue); + } + else + { + begin = 0; + } + + if (evalue && (wflag==0)) + { + end = atoi(evalue); + } + else + { + end = file.counter-1; + } + + if (begin<0 || begin>=file.counter) + { + fprintf(stderr,"ERROR: Selected first message %d is out of range!\n",begin); + return -1; + } + if (end<0 || end>=file.counter || end<begin) + { + fprintf(stderr,"ERROR: Selected end message %d is out of range!\n",end); + return -1; + } + for (num = begin; num <= end ;num++) + { + dlt_file_message(&file,num,vflag); + + if (xflag) + { + printf("%d ",num); + dlt_message_print_hex(&(file.msg),text,DLT_CONVERT_TEXTBUFSIZE,vflag); + } + else if (aflag) + { + printf("%d ",num); + + dlt_message_header(&(file.msg),text,DLT_CONVERT_TEXTBUFSIZE,vflag); + + printf("%s ",text); + + dlt_message_payload(&file.msg,text,DLT_CONVERT_TEXTBUFSIZE,DLT_OUTPUT_ASCII,vflag); + + printf("[%s]\n",text); + } + else if (mflag) + { + printf("%d ",num); + dlt_message_print_mixed_plain(&(file.msg),text,DLT_CONVERT_TEXTBUFSIZE,vflag); + } + else if (sflag) + { + printf("%d ",num); + + dlt_message_header(&(file.msg),text,DLT_CONVERT_TEXTBUFSIZE,vflag); + + printf("%s \n",text); + } + + /* if file output enabled write message */ + if (ovalue) + { + iov[0].iov_base = file.msg.headerbuffer; + iov[0].iov_len = file.msg.headersize; + iov[1].iov_base = file.msg.databuffer; + iov[1].iov_len = file.msg.datasize; + + bytes_written = writev(ohandle, iov, 2); + } + + /* check for new messages if follow flag set */ + if (wflag && num==end) + { + while (1) + { + while (dlt_file_read(&file,0)>=0) + { + } + if (end == (file.counter-1)) + { + /* Sleep if no new message was received */ + sleep(1); + } + else + { + /* set new end of log file and continue reading */ + end = file.counter-1; + break; + } + } + } + } + } + if (cflag) + { + printf("Total number of messages: %d\n",file.counter_total); + if (file.filter) + { + printf("Filtered number of messages: %d\n",file.counter); + } + } + } + if (ovalue) + { + close(ohandle); + } + if (index == optind) + { + /* no file selected, show usage and terminate */ + fprintf(stderr,"ERROR: No file selected\n"); + usage(); + return -1; + } + + dlt_file_free(&file,vflag); + + return 0; +} diff --git a/src/console/dlt-receive.c b/src/console/dlt-receive.c new file mode 100755 index 0000000..e078d7d --- /dev/null +++ b/src/console/dlt-receive.c @@ -0,0 +1,423 @@ +/* + * Dlt Client console utilities - Diagnostic Log and Trace + * @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-receive.cpp ** +** ** +** TARGET : linux ** +** ** +** PROJECT : DLT ** +** ** +** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** +** Markus Klein ** +** ** +** PURPOSE : ** +** ** +** REMARKS : ** +** ** +** PLATFORM DEPENDANT [yes/no]: yes ** +** ** +** TO BE CHANGED BY USER [yes/no]: no ** +** ** +*******************************************************************************/ + +/******************************************************************************* +** Author Identity ** +******************************************************************************** +** ** +** Initials Name Company ** +** -------- ------------------------- ---------------------------------- ** +** aw Alexander Wenzel BMW ** +** mk Markus Klein Fraunhofer ESK ** +*******************************************************************************/ + +/******************************************************************************* +** Revision Control History ** +*******************************************************************************/ + +/* + * $LastChangedRevision: 1670 $ + * $LastChangedDate: 2011-04-08 15:12:06 +0200 (Fr, 08. Apr 2011) $ + * $LastChangedBy$ + Initials Date Comment + aw 13.01.2010 initial + */ + +#include <ctype.h> /* for isprint() */ +#include <stdlib.h> /* for atoi() */ +#include <sys/stat.h> /* for S_IRUSR, S_IWUSR, S_IRGRP, S_IROTH */ +#include <fcntl.h> /* for open() */ +#include <sys/uio.h> /* for writev() */ + +#include "dlt_client.h" + +#define DLT_RECEIVE_TEXTBUFSIZE 10024 /* Size of buffer for text output */ + +#define DLT_RECEIVE_ECU_ID "RECV" + +/* Function prototypes */ +int dlt_receive_message_callback(DltMessage *message, void *data); + +typedef struct { + int aflag; + int sflag; + int xflag; + int mflag; + int vflag; + int yflag; + char *ovalue; + char *fvalue; + char *evalue; + int bvalue; + char ecuid[4]; + int ohandle; + DltFile file; + DltFilter filter; +} DltReceiveData; + +/** + * Print usage information of tool. + */ +void usage() +{ + char version[255]; + + dlt_get_version(version); + + printf("Usage: dlt-receive [options] hostname/serial_device_name\n"); + printf("Receive DLT messages from DLT daemon and print or store the messages.\n"); + printf("Use filters to filter received messages.\n"); + printf("%s \n", version); + printf("Options:\n"); + printf(" -a Print DLT messages; payload as ASCII\n"); + printf(" -x Print DLT messages; payload as hex\n"); + printf(" -m Print DLT messages; payload as hex and ASCII\n"); + printf(" -s Print DLT messages; only headers\n"); + printf(" -v Verbose mode\n"); + printf(" -h Usage\n"); + printf(" -y Serial device mode\n"); + printf(" -b baudrate Serial device baudrate (Default: 115200)\n"); + printf(" -e ecuid Set ECU ID (Default: RECV)\n"); + printf(" -o filename Output messages in new DLT file\n"); + printf(" -f filename Enable filtering of messages\n"); +} + +/** + * Main function of tool. + */ +int main(int argc, char* argv[]) +{ + DltClient dltclient; + DltReceiveData dltdata; + int c; + int index; + + /* Initialize dltdata */ + dltdata.aflag = 0; + dltdata.sflag = 0; + dltdata.xflag = 0; + dltdata.mflag = 0; + dltdata.vflag = 0; + dltdata.yflag = 0; + dltdata.ovalue = 0; + dltdata.fvalue = 0; + dltdata.evalue = 0; + dltdata.bvalue = 0; + dltdata.ohandle=-1; + + /* Fetch command line arguments */ + opterr = 0; + + while ((c = getopt (argc, argv, "vashyxmf:o:e:b:")) != -1) + switch (c) + { + case 'v': + { + dltdata.vflag = 1; + break; + } + case 'a': + { + dltdata.aflag = 1; + break; + } + case 's': + { + dltdata.sflag = 1; + break; + } + case 'x': + { + dltdata.xflag = 1; + break; + } + case 'm': + { + dltdata.mflag = 1; + break; + } + case 'h': + { + usage(); + return -1; + } + case 'y': + { + dltdata.yflag = 1; + break; + } + case 'f': + { + dltdata.fvalue = optarg; + break; + } + case 'o': + { + dltdata.ovalue = optarg; + break; + } + case 'e': + { + dltdata.evalue = optarg; + break; + } + case 'b': + { + dltdata.bvalue = atoi(optarg); + break; + } + case '?': + { + if (optopt == 'o' || optopt == 'f') + { + fprintf (stderr, "Option -%c requires an argument.\n", optopt); + } + else if (isprint (optopt)) + { + fprintf (stderr, "Unknown option `-%c'.\n", optopt); + } + else + { + fprintf (stderr, "Unknown option character `\\x%x'.\n",optopt); + } + /* unknown or wrong option used, show usage information and terminate */ + usage(); + return -1; + } + default: + { + abort (); + } + } + + /* Initialize DLT Client */ + dlt_client_init(&dltclient, dltdata.vflag); + + /* Register callback to be called when message was received */ + dlt_client_register_message_callback(dlt_receive_message_callback); + + /* Setup DLT Client structure */ + dltclient.serial_mode = dltdata.yflag; + + if (dltclient.serial_mode==0) + { + for (index = optind; index < argc; index++) + { + dltclient.servIP = argv[index]; + } + + if (dltclient.servIP == 0) + { + /* no hostname selected, show usage and terminate */ + fprintf(stderr,"ERROR: No hostname selected\n"); + usage(); + dlt_client_cleanup(&dltclient,dltdata.vflag); + return -1; + } + } + else + { + for (index = optind; index < argc; index++) + { + dltclient.serialDevice = argv[index]; + } + + if (dltclient.serialDevice == 0) + { + /* no serial device name selected, show usage and terminate */ + fprintf(stderr,"ERROR: No serial device name specified\n"); + usage(); + return -1; + } + + dlt_client_setbaudrate(&dltclient,dltdata.bvalue); + } + + /* initialise structure to use DLT file */ + dlt_file_init(&(dltdata.file),dltdata.vflag); + + /* first parse filter file if filter parameter is used */ + dlt_filter_init(&(dltdata.filter),dltdata.vflag); + + if (dltdata.fvalue) + { + if (dlt_filter_load(&(dltdata.filter),dltdata.fvalue,dltdata.vflag)<0) + { + dlt_file_free(&(dltdata.file),dltdata.vflag); + return -1; + } + + dlt_file_set_filter(&(dltdata.file),&(dltdata.filter),dltdata.vflag); + } + + /* open DLT output file */ + if (dltdata.ovalue) + { + dltdata.ohandle = open(dltdata.ovalue,O_WRONLY|O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); /* mode: wb */ + + if (dltdata.ohandle == -1) + { + dlt_file_free(&(dltdata.file),dltdata.vflag); + fprintf(stderr,"ERROR: Output file %s cannot be opened!\n",dltdata.ovalue); + return -1; + } + } + + if (dltdata.evalue) + { + dlt_set_id(dltdata.ecuid,dltdata.evalue); + } + else + { + dlt_set_id(dltdata.ecuid,DLT_RECEIVE_ECU_ID); + } + + /* Connect to TCP socket or open serial device */ + if (dlt_client_connect(&dltclient, dltdata.vflag)!=-1) + { + + /* Dlt Client Main Loop */ + dlt_client_main_loop(&dltclient, &dltdata, dltdata.vflag); + + /* Dlt Client Cleanup */ + dlt_client_cleanup(&dltclient,dltdata.vflag); + } + + /* dlt-receive cleanup */ + if (dltdata.ovalue) + { + close(dltdata.ohandle); + } + + dlt_file_free(&(dltdata.file),dltdata.vflag); + + dlt_filter_free(&(dltdata.filter),dltdata.vflag); + + return 0; +} + +int dlt_receive_message_callback(DltMessage *message, void *data) +{ + DltReceiveData *dltdata; + static char text[DLT_RECEIVE_TEXTBUFSIZE]; + + struct iovec iov[2]; + int bytes_written; + + if ((message==0) || (data==0)) + { + return -1; + } + + dltdata = (DltReceiveData*)data; + + /* prepare storage header */ + if (DLT_IS_HTYP_WEID(message->standardheader->htyp)) + { + dlt_set_storageheader(message->storageheader,message->headerextra.ecu); + } + else + { + dlt_set_storageheader(message->storageheader,dltdata->ecuid); + } + + if ((dltdata->fvalue==0) || (dltdata->fvalue && dlt_message_filter_check(message,&(dltdata->filter),dltdata->vflag)==1)) + { + /* if no filter set or filter is matching display message */ + if (dltdata->xflag) + { + dlt_message_print_hex(message,text,DLT_RECEIVE_TEXTBUFSIZE,dltdata->vflag); + } + else if (dltdata->aflag) + { + + dlt_message_header(message,text,DLT_RECEIVE_TEXTBUFSIZE,dltdata->vflag); + + printf("%s ",text); + + dlt_message_payload(message,text,DLT_RECEIVE_TEXTBUFSIZE,DLT_OUTPUT_ASCII,dltdata->vflag); + + printf("[%s]\n",text); + } + else if (dltdata->mflag) + { + dlt_message_print_mixed_plain(message,text,DLT_RECEIVE_TEXTBUFSIZE,dltdata->vflag); + } + else if (dltdata->sflag) + { + + dlt_message_header(message,text,DLT_RECEIVE_TEXTBUFSIZE,dltdata->vflag); + + printf("%s \n",text); + } + + /* if file output enabled write message */ + if (dltdata->ovalue) + { + iov[0].iov_base = message->headerbuffer; + iov[0].iov_len = message->headersize; + iov[1].iov_base = message->databuffer; + iov[1].iov_len = message->datasize; + + bytes_written = writev(dltdata->ohandle, iov, 2); + } + } + + return 0; +} diff --git a/src/console/filter.txt b/src/console/filter.txt new file mode 100755 index 0000000..0086b17 --- /dev/null +++ b/src/console/filter.txt @@ -0,0 +1,3 @@ +ABCD IJKL +TEST LOG + diff --git a/src/daemon/CMakeLists.txt b/src/daemon/CMakeLists.txt new file mode 100755 index 0000000..863036b --- /dev/null +++ b/src/daemon/CMakeLists.txt @@ -0,0 +1,48 @@ +####### +# Dlt - Diagnostic Log and Trace +# @licence make 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@ +######## + +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) +add_executable(dlt-daemon ${dlt_daemon_SRCS}) +target_link_libraries(dlt-daemon rt ${CMAKE_THREAD_LIBS_INIT}) + +install(TARGETS dlt-daemon + RUNTIME DESTINATION bin + PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ + GROUP_EXECUTE GROUP_READ + WORLD_EXECUTE WORLD_READ + COMPONENT base) + diff --git a/src/daemon/dlt-daemon.c b/src/daemon/dlt-daemon.c new file mode 100755 index 0000000..ad2aa9d --- /dev/null +++ b/src/daemon/dlt-daemon.c @@ -0,0 +1,2022 @@ +/* + * Dlt Daemon - Diagnostic Log and Trace + * @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-daemon.c ** +** ** +** TARGET : linux ** +** ** +** PROJECT : DLT ** +** ** +** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** +** Markus Klein ** +** ** +** PURPOSE : ** +** ** +** REMARKS : ** +** ** +** PLATFORM DEPENDANT [yes/no]: yes ** +** ** +** TO BE CHANGED BY USER [yes/no]: no ** +** ** +*******************************************************************************/ + +/******************************************************************************* +** Author Identity ** +******************************************************************************** +** ** +** Initials Name Company ** +** -------- ------------------------- ---------------------------------- ** +** aw Alexander Wenzel BMW ** +** mk Markus Klein Fraunhofer ESK ** +*******************************************************************************/ + +/******************************************************************************* +** Revision Control History ** +*******************************************************************************/ + +/* + * $LastChangedRevision: 1670 $ + * $LastChangedDate: 2011-04-08 15:12:06 +0200 (Fr, 08. Apr 2011) $ + * $LastChangedBy$ + Initials Date Comment + aw 13.01.2010 initial + */ + +#include <netdb.h> +#include <ctype.h> +#include <stdio.h> /* for printf() and fprintf() */ +#include <sys/socket.h> /* for socket(), connect(), (), and recv() */ +#include <arpa/inet.h> /* for sockaddr_in and inet_addr() */ +#include <stdlib.h> /* for atoi() and exit() */ +#include <string.h> /* for memset() */ +#include <unistd.h> /* for close() */ +#include <fcntl.h> +#include <signal.h> +#include <syslog.h> +#include <errno.h> +#include <pthread.h> + +#include <sys/timerfd.h> +#include <sys/stat.h> +#include <sys/time.h> +#include <linux/stat.h> + +#include "version.h" +#include "svnversion.h" + +#include "dlt_types.h" +#include "dlt-daemon.h" +#include "dlt-daemon_cfg.h" + +/** \page Contents + * The package automotive-dlt includes the following items: + * - dlt daemon (dlt-daemon) + * - adptors to to interface the daemon (dlt-adaptor-stdin, dlt-adaptor-udp) + * - dlt client gui (dlt-viewer) + * - dlt console tools (dlt-receive, dlt-convert) + * - examples (dlt-example-user, dlt-example-user-func, dlt-example-ringbuffer) + * - a library including user-application, client and common functions + */ + +/** + \defgroup daemon DLT Daemon + \addtogroup daemon + \{ +*/ + +/** Global text output buffer, mainly used for creation of error/warning strings */ +static char str[DLT_DAEMON_TEXTBUFSIZE]; + +static DltDaemonTimingPacketThreadData dlt_daemon_timingpacket_thread_data; + +static pthread_t dlt_daemon_timingpacket_thread_handle; +static pthread_attr_t dlt_daemon_timingpacket_thread_attr; + +/** + * Print usage information of tool. + */ +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"); +} /* usage() */ + +/** + * Option handling + */ +int option_handling(DltDaemonLocal *daemon_local,int argc, char* argv[]) + { + int c; + + if (daemon_local==0) + { + fprintf (stderr, "Invalid parameter passed to option_handling()\n"); + return -1; + } + + /* Initialize flags */ + memset(daemon_local,0,sizeof(DltDaemonLocal)); + + opterr = 0; + + while ((c = getopt (argc, argv, "hvasxdlrmnf:o:e:b:y:u:")) != -1) + { + switch (c) + { + case 'v': + { + 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 'h': + { + usage(); + return -2; /* return no error */ + } + case '?': + { + if (optopt == 'f' || optopt == 'o' || optopt == 'e' || optopt == 'b' || optopt == 'y' || optopt == 'u') + { + fprintf (stderr, "Option -%c requires an argument.\n", optopt); + } + else if (isprint (optopt)) + { + fprintf (stderr, "Unknown option `-%c'.\n", optopt); + } + else + { + fprintf (stderr, "Unknown option character `\\x%x'.\n",optopt); + } + /* unknown or wrong option used, show usage information and terminate */ + usage(); + return -1; + } + default: + { + fprintf (stderr, "Invalid option, this should never occur!\n"); + return -1; + } + } /* switch() */ + } + + return 0; + + } /* option_handling() */ + +/** + * Main function of tool. + */ +int main(int argc, char* argv[]) +{ + char version[DLT_DAEMON_TEXTBUFSIZE]; + DltDaemonLocal daemon_local; + DltDaemon daemon; + + int i,back; + + /* Command line option handling */ + if ((back = option_handling(&daemon_local,argc,argv))<0) + { + if(back!=-2) { + fprintf (stderr, "option_handling() failed!\n"); + } + return -1; + } + + /* Initialize logging facility */ + dlt_log_init(daemon_local.flags.dflag); + + /* Print version information */ + dlt_get_version(version); + + sprintf(str,"Starting DLT Daemon; %s\n", version ); + dlt_log(LOG_NOTICE, str); + + PRINT_FUNCTION_VERBOSE(daemon_local.flags.vflag); + + /* --- Daemon init phase 1 begin --- */ + if (dlt_daemon_local_init_p1(&daemon, &daemon_local, daemon_local.flags.vflag)==-1) + { + dlt_log(LOG_CRIT,"Initialization of phase 1 failed!\n"); + return -1; + } + /* --- Daemon init phase 1 end --- */ + + /* --- Daemon connection init begin */ + if (dlt_daemon_local_connection_init(&daemon, &daemon_local, daemon_local.flags.vflag)==-1) + { + dlt_log(LOG_CRIT,"Initialization of local connections failed!\n"); + return -1; + } + /* --- Daemon connection init end */ + + /* --- Daemon init phase 2 begin --- */ + if (dlt_daemon_local_init_p2(&daemon, &daemon_local, daemon_local.flags.vflag)==-1) + { + dlt_log(LOG_CRIT,"Initialization of phase 2 failed!\n"); + return -1; + } + /* --- Daemon init phase 2 end --- */ + + while (1) + { + /* wait for events form all FIFO and sockets */ + daemon_local.read_fds = daemon_local.master; + if (select(daemon_local.fdmax+1, &(daemon_local.read_fds), NULL, NULL, NULL) == -1) + { + dlt_log(LOG_CRIT, "select() failed!\n"); + return -1 ; + } /* if */ + + /* run through the existing FIFO and sockets to check for events */ + for (i = 0; i <= daemon_local.fdmax; i++) + { + if (FD_ISSET(i, &(daemon_local.read_fds))) + { + if (i == daemon_local.sock) + { + /* event from TCP server socket, new connection */ + if (dlt_daemon_process_client_connect(&daemon, &daemon_local, daemon_local.flags.vflag)==-1) + { + dlt_log(LOG_CRIT,"Connect to dlt client failed!\n"); + return -1; + } + } + else if (i == daemon_local.fp) + { + /* event from the FIFO happened */ + if (dlt_daemon_process_user_messages(&daemon, &daemon_local, daemon_local.flags.vflag)==-1) + { + dlt_log(LOG_CRIT,"Processing of messages from user connection failed!\n"); + return -1; + } + } + 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) + { + dlt_log(LOG_CRIT,"Processing of messages from serial connection failed!\n"); + return -1; + } + } + else + { + /* event from tcp connection to client received */ + daemon_local.receiverSock.fd = i; + if (dlt_daemon_process_client_messages(&daemon, &daemon_local, daemon_local.flags.vflag)==-1) + { + dlt_log(LOG_CRIT,"Processing of messages from client connection failed!\n"); + return -1; + } + } /* else */ + } /* if */ + } /* for */ + } /* while */ + + dlt_daemon_local_cleanup(&daemon, &daemon_local, daemon_local.flags.vflag); + + dlt_log(LOG_NOTICE, "Leaving DLT daemon\n"); + + return 0; + +} /* main() */ + +int dlt_daemon_local_init_p1(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose) +{ + PRINT_FUNCTION_VERBOSE(verbose); + + if ((daemon==0) || (daemon_local==0)) + { + dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_local_init_p1()\n"); + return -1; + } + + /* Check for daemon mode */ + if (daemon_local->flags.dflag) + { + dlt_daemon_daemonize(daemon_local->flags.vflag); + } + + /* initialise structure to use DLT file */ + if (dlt_file_init(&(daemon_local->file),daemon_local->flags.vflag)==-1) + { + dlt_log(LOG_ERR,"Could not initialize file structure\n"); + /* Return value ignored, dlt daemon will exit */ + dlt_file_free(&(daemon_local->file),daemon_local->flags.vflag); + 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 */ + signal(SIGHUP, dlt_daemon_signal_handler); /* hangup signal */ + signal(SIGQUIT, dlt_daemon_signal_handler); + signal(SIGINT, dlt_daemon_signal_handler); + + /* open DLT output file */ + daemon_local->ohandle=-1; + if (daemon_local->flags.ovalue) + { + 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) + { + /* Return value ignored, dlt daemon will exit */ + dlt_file_free(&(daemon_local->file),daemon_local->flags.vflag); + sprintf(str,"Output file %s cannot be opened!\n",daemon_local->flags.ovalue); + dlt_log(LOG_ERR, str); + return -1; + } /* if */ + } /* if */ + + return 0; +} + +int dlt_daemon_local_init_p2(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose) +{ + PRINT_FUNCTION_VERBOSE(verbose); + + if ((daemon==0) || (daemon_local==0)) + { + dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_local_init_p2()\n"); + return -1; + } + + /* Daemon data */ + if (dlt_daemon_init(daemon,daemon_local->flags.vflag)==-1) + { + dlt_log(LOG_ERR,"Could not initialize daemon data\n"); + return -1; + } + + /* Set ECU id of daemon */ + if (daemon_local->flags.evalue!=0) + { + dlt_set_id(daemon->ecuid,daemon_local->flags.evalue); + } + else + { + dlt_set_id(daemon->ecuid,DLT_DAEMON_ECU_ID); + } + + /* 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); + + /* prepare main loop */ + if (dlt_message_init(&(daemon_local->msg),daemon_local->flags.vflag)==-1) + { + dlt_log(LOG_ERR,"Could not initialize message\n"); + return -1; + } + + if (dlt_receiver_init(&(daemon_local->receiver),daemon_local->fp,daemon_local->ringbufferSize)==-1) + { + dlt_log(LOG_ERR,"Could not initialize receiver\n"); + return -1; + } + if (dlt_receiver_init(&(daemon_local->receiverSock),daemon_local->sock,DLT_DAEMON_RCVBUFSIZESOCK)==-1) + { + dlt_log(LOG_ERR,"Could not initialize receiver for socket\n"); + return -1; + } + + if (daemon_local->flags.yvalue!=0) + { + if (dlt_receiver_init(&(daemon_local->receiverSerial),daemon_local->fdserial,DLT_DAEMON_RCVBUFSIZESERIAL)==-1) + { + dlt_log(LOG_ERR,"Could not initialize receiver for serial connection\n"); + return -1; + } + } + + /* setup period thread for timing packets */ + if (pthread_attr_init(&dlt_daemon_timingpacket_thread_attr)<0) + { + dlt_log(LOG_WARNING, "Initialization of default thread stack size failed!\n"); + } + else + { + if (pthread_attr_setstacksize(&dlt_daemon_timingpacket_thread_attr,DLT_DAEMON_TIMINGPACKET_THREAD_STACKSIZE)<0) + { + dlt_log(LOG_WARNING, "Setting of default thread stack size failed!\n"); + } + } + + /* Binary semaphore for thread */ + if (sem_init(&dlt_daemon_mutex, 0, 1)==-1) + { + dlt_log(LOG_ERR,"Could not initialize binary semaphore\n"); + return -1; + } + + /* start thread */ + dlt_daemon_timingpacket_thread_data.daemon = daemon; + dlt_daemon_timingpacket_thread_data.daemon_local = daemon_local; + + if (pthread_create(&(dlt_daemon_timingpacket_thread_handle), + &dlt_daemon_timingpacket_thread_attr, + (void *) &dlt_daemon_timingpacket_thread, + (void *)&dlt_daemon_timingpacket_thread_data)!=0) + { + dlt_log(LOG_ERR,"Could not initialize timing packet thread\n"); + pthread_attr_destroy(&dlt_daemon_timingpacket_thread_attr); + return -1; + } + + pthread_attr_destroy(&dlt_daemon_timingpacket_thread_attr); + + return 0; +} + +int dlt_daemon_local_connection_init(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose) +{ + int ret; + int yes = 1; + + struct sockaddr_in servAddr; + unsigned int servPort = DLT_DAEMON_TCP_PORT; + + PRINT_FUNCTION_VERBOSE(verbose); + + if ((daemon==0) || (daemon_local==0)) + { + dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_local_connection_init()\n"); + return -1; + } + + /* open named pipe(FIFO) to receive DLT messages from users */ + umask(0); + + /* Try to delete existing pipe, ignore result of unlink */ + unlink(DLT_USER_FIFO); + + ret=mkfifo(DLT_USER_FIFO, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH ); + if (ret==-1) + { + sprintf(str,"FIFO user %s cannot be created!\n",DLT_USER_FIFO); + dlt_log(LOG_ERR, str); + return -1; + } /* if */ + + daemon_local->fp = open(DLT_USER_FIFO, O_RDWR); + if (daemon_local->fp==-1) + { + sprintf(str,"FIFO user %s cannot be opened!\n",DLT_USER_FIFO); + dlt_log(LOG_ERR, str); + return -1; + } /* if */ + + /* create and open socket to receive incoming connections from client */ + if ((daemon_local->sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) + { + dlt_log(LOG_ERR, "socket() failed!\n"); + return -1; + } /* if */ + + setsockopt(daemon_local->sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)); + memset(&servAddr, 0, sizeof(servAddr)); + servAddr.sin_family = AF_INET; + servAddr.sin_addr.s_addr = INADDR_ANY; + servAddr.sin_port = htons(servPort); + + if (bind(daemon_local->sock, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0) + { + dlt_log(LOG_ERR, "bind() failed!\n"); + return -1; + } /* if */ + + if (daemon_local->flags.vflag) + { + dlt_log(LOG_INFO, "Bind succesfull\n"); + } + + if (listen(daemon_local->sock, 3) < 0) + { + dlt_log(LOG_ERR, "listen() failed!\n"); + return -1; + } /* if */ + + if (daemon_local->flags.vflag) + { + dlt_log(LOG_INFO, "Listen succesfull\n"); + } + + /* prepare usage of select(), add FIFO and receiving socket */ + FD_ZERO(&(daemon_local->master)); + FD_ZERO(&(daemon_local->read_fds)); + FD_SET(daemon_local->sock, &(daemon_local->master)); + + daemon_local->fdmax = daemon_local->sock; + + FD_SET(daemon_local->fp, &(daemon_local->master)); + + if (daemon_local->fp > daemon_local->fdmax) + { + daemon_local->fdmax = daemon_local->fp; + } + + 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); + dlt_log(LOG_ERR, str); + return -1; + } + + if (isatty(daemon_local->fdserial)) + { + if (daemon_local->flags.bvalue!=0) + { + daemon_local->baudrate = dlt_convert_serial_speed(atoi(daemon_local->flags.bvalue)); + } + else + { + daemon_local->baudrate = dlt_convert_serial_speed(DLT_DAEMON_SERIAL_DEFAULT_BAUDRATE); + } + + 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)); + dlt_log(LOG_ERR, str); + return -1; + } + + FD_SET(daemon_local->fdserial, &(daemon_local->master)); + + if (daemon_local->fdserial > daemon_local->fdmax) + { + daemon_local->fdmax = daemon_local->fdserial; + } + + if (daemon_local->flags.vflag) + { + dlt_log(LOG_INFO, "Serial init done\n"); + } + } + 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)); + return -1; + } + } + + return 0; +} + + +void dlt_daemon_local_cleanup(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose) +{ + PRINT_FUNCTION_VERBOSE(verbose); + + if ((daemon==0) || (daemon_local==0)) + { + dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_local_cleanup()\n"); + return; + } + + /* Ignore result */ + dlt_receiver_free(&(daemon_local->receiver)); + /* Ignore result */ + dlt_receiver_free(&(daemon_local->receiverSock)); + + /* Ignore result */ + dlt_message_free(&(daemon_local->msg),daemon_local->flags.vflag); + close(daemon_local->fp); + + if (daemon_local->flags.ovalue) + { + close(daemon_local->ohandle); + } /* if */ + + /* Ignore result */ + dlt_file_free(&(daemon_local->file),daemon_local->flags.vflag); + + /* Try to delete existing pipe, ignore result of unlink() */ + unlink(DLT_USER_FIFO); + + /* Try to delete lock file, ignore result of unlink() */ + unlink(DLT_DAEMON_LOCK_FILE); +} + +void dlt_daemon_signal_handler(int sig) +{ + switch (sig) + { + case SIGHUP: + case SIGTERM: + case SIGINT: + case SIGQUIT: + { + /* finalize the server */ + //dlt_log("terminate signal catched"); + dlt_log(LOG_NOTICE, "Exiting DLT daemon\n"); + + /* Try to delete existing pipe, ignore result of unlink() */ + unlink(DLT_USER_FIFO); + + /* Try to delete lock file, ignore result of unlink() */ + unlink(DLT_DAEMON_LOCK_FILE); + + /* Terminate program */ + exit(0); + break; + } + default: + { + /* This case should never occur */ + break; + } + } /* switch */ +} /* dlt_daemon_signal_handler() */ + +void dlt_daemon_daemonize(int verbose) +{ + int i,lfp,bytes_written,ret; + + PRINT_FUNCTION_VERBOSE(verbose); + + dlt_log(LOG_NOTICE, "Daemon mode\n"); + + /* Daemonize */ + i=fork(); + if (i<0) + { + dlt_log(LOG_CRIT, "Unable to fork(), exiting DLT daemon\n"); + exit(-1); /* fork error */ + } + + if (i>0) + { + exit(0); /* parent exits */ + } + /* child (daemon) continues */ + + /* Process independency */ + + /* obtain a new process group */ + if (setsid()==-1) + { + dlt_log(LOG_CRIT, "setsid() failed, exiting DLT daemon\n"); + exit(-1); /* fork error */ + } + + /* Close descriptors */ + for (i=getdtablesize();i>=0;--i) + { + close(i); /* close all descriptors */ + } + + /* Open standard descriptors stdin, stdout, stderr */ + i=open("/dev/null",O_RDWR); /* open stdin */ + ret=dup(i); /* stdout */ + ret=dup(i); /* stderr */ + + /* Set umask */ + umask(DLT_DAEMON_UMASK); + + /* Change to known directory */ + ret=chdir(DLT_USER_DIR); + + /* Ensure single copy of daemon; + run only one instance at a time */ + lfp=open(DLT_DAEMON_LOCK_FILE,O_RDWR|O_CREAT,DLT_DAEMON_LOCK_FILE_PERM); + if (lfp<0) + { + dlt_log(LOG_CRIT, "can't open lock file, exiting DLT daemon\n"); + exit(-1); /* can not open */ + } + if (lockf(lfp,F_TLOCK,0)<0) + { + dlt_log(LOG_CRIT, "can't lock lock file, exiting DLT daemon\n"); + exit(-1); /* can not lock */ + } + /* only first instance continues */ + + sprintf(str,"%d\n",getpid()); + bytes_written=write(lfp,str,strlen(str)); /* record pid to lockfile */ + + /* Catch signals */ + signal(SIGCHLD,SIG_IGN); /* ignore child */ + signal(SIGTSTP,SIG_IGN); /* ignore tty signals */ + signal(SIGTTOU,SIG_IGN); + signal(SIGTTIN,SIG_IGN); + +} /* dlt_daemon_daemonize() */ + +int dlt_daemon_process_client_connect(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose) +{ + socklen_t cli_size; + struct sockaddr cli; + + int in_sock = -1; + + PRINT_FUNCTION_VERBOSE(verbose); + + if ((daemon==0) || (daemon_local==0)) + { + dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_client_connect()\n"); + return -1; + } + + /* event from TCP server socket, new connection */ + cli_size = sizeof(cli); + if ((in_sock = accept(daemon_local->sock,&cli, &cli_size)) < 0) + { + dlt_log(LOG_ERR, "accept() failed!\n"); + return -1 ; + } + //sprintf("str,"Client Connection from %s\n", inet_ntoa(cli.sin_addr)); + //dlt_log(str); + FD_SET(in_sock, &(daemon_local->master)); /* add to master set */ + if (in_sock > daemon_local->fdmax) + { + /* keep track of the maximum */ + daemon_local->fdmax = in_sock; + } /* if */ + + daemon_local->client_connections++; + if (daemon_local->flags.vflag) + { + sprintf(str, "New connection to client established, #connections: %d\n",daemon_local->client_connections); + dlt_log(LOG_INFO, str); + } + + 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; + } + } + + return 0; +} + +int dlt_daemon_process_client_messages(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose) +{ + int bytes_to_be_removed=0; + + PRINT_FUNCTION_VERBOSE(verbose); + + if ((daemon==0) || (daemon_local==0)) + { + dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_client_messages()\n"); + return -1; + } + + if (dlt_receiver_receive_socket(&(daemon_local->receiverSock))<=0) + { + close(daemon_local->receiverSock.fd); + FD_CLR(daemon_local->receiverSock.fd, &(daemon_local->master)); + + if (daemon_local->client_connections) + { + daemon_local->client_connections--; + } + + if (daemon_local->flags.vflag) + { + sprintf(str, "Connection to client lost, #connections: %d\n",daemon_local->client_connections); + dlt_log(LOG_INFO, str); + } + + /* check: return 0; */ + } + + /* Process all received messages */ + while (dlt_message_read(&(daemon_local->msg),(uint8_t*)daemon_local->receiverSock.buf,daemon_local->receiverSock.bytesRcvd,daemon_local->flags.nflag,daemon_local->flags.vflag)==0) + { + /* Check for control message */ + if (DLT_MSG_IS_CONTROL_REQUEST(&(daemon_local->msg))) + { + dlt_daemon_control_process_control(daemon_local->receiverSock.fd, daemon, &(daemon_local->msg), daemon_local->flags.vflag); + } + + bytes_to_be_removed = daemon_local->msg.headersize+daemon_local->msg.datasize-sizeof(DltStorageHeader); + if (daemon_local->msg.found_serialheader) + { + bytes_to_be_removed += sizeof(dltSerialHeader); + } + if (daemon_local->msg.resync_offset) + { + bytes_to_be_removed += daemon_local->msg.resync_offset; + } + + if (dlt_receiver_remove(&(daemon_local->receiverSock),bytes_to_be_removed)==-1) + { + dlt_log(LOG_ERR,"Can't remove bytes from receiver for sockets\n"); + return -1; + } + + } /* while */ + + + if (dlt_receiver_move_to_begin(&(daemon_local->receiverSock))==-1) + { + dlt_log(LOG_ERR,"Can't move bytes to beginning of receiver buffer for sockets\n"); + return -1; + } + + return 0; +} + +int dlt_daemon_process_client_messages_serial(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose) +{ + int bytes_to_be_removed=0; + + PRINT_FUNCTION_VERBOSE(verbose); + + if ((daemon==0) || (daemon_local==0)) + { + dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_client_messages_serial()\n"); + return -1; + } + + if (dlt_receiver_receive_fd(&(daemon_local->receiverSerial))<=0) + { + dlt_log(LOG_ERR, "dlt_receiver_receive_fd() for messages from serial interface failed!\n"); + return -1; + } + + /* Process all received messages */ + while (dlt_message_read(&(daemon_local->msg),(uint8_t*)daemon_local->receiverSerial.buf,daemon_local->receiverSerial.bytesRcvd,daemon_local->flags.mflag,daemon_local->flags.vflag)==0) + { + /* Check for control message */ + if (DLT_MSG_IS_CONTROL_REQUEST(&(daemon_local->msg))) + { + if (dlt_daemon_control_process_control(daemon_local->receiverSerial.fd, daemon, &(daemon_local->msg), daemon_local->flags.vflag)==-1) + { + dlt_log(LOG_ERR,"Can't process control messages\n"); + return -1; + } + } + + bytes_to_be_removed = daemon_local->msg.headersize+daemon_local->msg.datasize-sizeof(DltStorageHeader); + if (daemon_local->msg.found_serialheader) + { + bytes_to_be_removed += sizeof(dltSerialHeader); + } + if (daemon_local->msg.resync_offset) + { + bytes_to_be_removed += daemon_local->msg.resync_offset; + } + + if (dlt_receiver_remove(&(daemon_local->receiverSerial),bytes_to_be_removed)==-1) + { + dlt_log(LOG_ERR,"Can't remove bytes from receiver for serial connection\n"); + return -1; + } + + } /* while */ + + + if (dlt_receiver_move_to_begin(&(daemon_local->receiverSerial))==-1) + { + dlt_log(LOG_ERR,"Can't move bytes to beginning of receiver buffer for serial connection\n"); + return -1; + } + + return 0; +} + +int dlt_daemon_process_user_messages(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose) +{ + int offset=0; + int run_loop=1; + DltUserHeader *userheader; + + PRINT_FUNCTION_VERBOSE(verbose); + + if ((daemon==0) || (daemon_local==0)) + { + dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_messages()\n"); + return -1; + } + + /* read data from FIFO */ + if (dlt_receiver_receive_fd(&(daemon_local->receiver))<=0) + { + dlt_log(LOG_ERR, "dlt_receiver_receive_fd() for user messages failed!\n"); + return -1; + } + + /* look through buffer as long as data is in there */ + do + { + if (daemon_local->receiver.bytesRcvd < sizeof(DltUserHeader)) + { + break; + } + + /* resync if necessary */ + offset=0; + do + { + userheader = (DltUserHeader*) (daemon_local->receiver.buf+offset); + + /* Check for user header pattern */ + if (dlt_user_check_userheader(userheader)) + { + break; + } + + offset++; + + } + while ((sizeof(DltUserHeader)+offset)<=daemon_local->receiver.bytesRcvd); + + /* Check for user header pattern */ + if (dlt_user_check_userheader(userheader)==0) + { + break; + } + + /* Set new start offset */ + if (offset>0) + { + daemon_local->receiver.buf+=offset; + daemon_local->receiver.bytesRcvd-=offset; + } + + switch (userheader->message) + { + case DLT_USER_MESSAGE_OVERFLOW: + { + if (dlt_daemon_process_user_message_overflow(daemon, daemon_local, daemon_local->flags.vflag)==-1) + { + run_loop=0; + } + break; + } + case DLT_USER_MESSAGE_REGISTER_CONTEXT: + { + if (dlt_daemon_process_user_message_register_context(daemon, daemon_local, daemon_local->flags.vflag)==-1) + { + run_loop=0; + } + break; + } + case DLT_USER_MESSAGE_UNREGISTER_CONTEXT: + { + if (dlt_daemon_process_user_message_unregister_context(daemon, daemon_local, daemon_local->flags.vflag)==-1) + { + run_loop=0; + } + break; + } + case DLT_USER_MESSAGE_LOG: + { + if (dlt_daemon_process_user_message_log(daemon, daemon_local, daemon_local->flags.vflag)==-1) + { + run_loop=0; + } + break; + } + case DLT_USER_MESSAGE_REGISTER_APPLICATION: + { + if (dlt_daemon_process_user_message_register_application(daemon, daemon_local, daemon_local->flags.vflag)==-1) + { + run_loop=0; + } + break; + } + case DLT_USER_MESSAGE_UNREGISTER_APPLICATION: + { + if (dlt_daemon_process_user_message_unregister_application(daemon, daemon_local, daemon_local->flags.vflag)==-1) + { + run_loop=0; + } + break; + } + case DLT_USER_MESSAGE_APP_LL_TS: + { + if (dlt_daemon_process_user_message_set_app_ll_ts(daemon, daemon_local, daemon_local->flags.vflag)==-1) + { + run_loop=0; + } + break; + } + default: + { + dlt_log(LOG_ERR,"(Internal) Invalid user message type received!\n"); + + /* remove user header */ + if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader))==-1) + { + dlt_log(LOG_ERR,"Can't remove bytes from receiver for user messages\n"); + return -1; + } + + /* In next invocation of do-while loop, a resync will be triggered if additional data was received */ + run_loop=0; + + break; + } + } + + } + while (run_loop); + + /* keep not read data in buffer */ + if (dlt_receiver_move_to_begin(&(daemon_local->receiver))==-1) + { + dlt_log(LOG_ERR,"Can't move bytes to beginning of receiver buffer for user messages\n"); + return -1; + } + + return 0; +} + +int dlt_daemon_process_user_message_overflow(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose) +{ + int j, sent; + + PRINT_FUNCTION_VERBOSE(verbose); + + if ((daemon==0) || (daemon_local==0)) + { + dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_overflow()\n"); + return -1; + } + + /* Store in daemon, that a message buffer overflow has occured */ + daemon->message_buffer_overflow = DLT_MESSAGE_BUFFER_OVERFLOW; + + /* look if TCP connection to client is available */ + sent = 0; + + for (j = 0; j <= daemon_local->fdmax; j++) + { + /* send to everyone! */ + if (FD_ISSET(j, &(daemon_local->master))) + { + /* except the listener and ourselves */ + if ((j != daemon_local->fp) && (j != daemon_local->sock)) + { + dlt_daemon_control_message_buffer_overflow(j, daemon, verbose); + sent=1; + /* Reset overflow state */ + daemon->message_buffer_overflow = DLT_MESSAGE_BUFFER_NO_OVERFLOW; + } /* if */ + } /* if */ + } /* for */ + + /* message was not sent, so store it in ringbuffer */ + if (sent==0) + { + dlt_daemon_control_message_buffer_overflow(DLT_DAEMON_STORE_TO_BUFFER, daemon, verbose); + } + + /* keep not read data in buffer */ + if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader))==-1) + { + dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message overflow\n"); + return -1; + } + + return 0; +} + +int dlt_daemon_process_user_message_register_application(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose) +{ + uint32_t len=0; + DltDaemonApplication *application; + char description[DLT_DAEMON_DESCSIZE]; + DltUserControlMsgRegisterApplication *usercontext; + + PRINT_FUNCTION_VERBOSE(verbose); + + if ((daemon==0) || (daemon_local==0)) + { + dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_register_application()\n"); + return -1; + } + + if (daemon_local->receiver.bytesRcvd < (sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterApplication))) + { + /* Not enough bytes received */ + return -1; + } + + usercontext = (DltUserControlMsgRegisterApplication*) (daemon_local->receiver.buf+sizeof(DltUserHeader)); + + memset(description,0,sizeof(description)); + + len=usercontext->description_length; + if ((len>0) && (len<=DLT_DAEMON_DESCSIZE)) + { + /* Read and store application description */ + strncpy(description, (daemon_local->receiver.buf+sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterApplication)), len); + } + + application=dlt_daemon_application_add(daemon,usercontext->apid,usercontext->pid,description,verbose); + + /* keep not read data in buffer */ + if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterApplication)+len)==-1) + { + dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register application\n"); + return -1; + } + + if (application==0) + { + dlt_log(LOG_CRIT,"Can't add application"); + return -1; + } + + return 0; +} + +int dlt_daemon_process_user_message_register_context(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose) +{ + uint32_t len=0; + int8_t loglevel, tracestatus; + DltUserControlMsgRegisterContext *usercontext; + char description[DLT_DAEMON_DESCSIZE]; + DltDaemonApplication *application; + DltDaemonContext *context; + DltServiceGetLogInfoRequest *req; + + DltMessage msg; + int j; + int sent; + + PRINT_FUNCTION_VERBOSE(verbose); + + if ((daemon==0) || (daemon_local==0)) + { + dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_register_context()\n"); + return -1; + } + + if (daemon_local->receiver.bytesRcvd < (sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext))) + { + /* Not enough bytes received */ + return -1; + } + + usercontext = (DltUserControlMsgRegisterContext*) (daemon_local->receiver.buf+sizeof(DltUserHeader)); + + memset(description,0,sizeof(description)); + + len=usercontext->description_length; + if ((len>0) && (len<=DLT_DAEMON_DESCSIZE)) + { + /* Read and store context description */ + strncpy(description, (daemon_local->receiver.buf+sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)), len); + } + + application = dlt_daemon_application_find(daemon,usercontext->apid,verbose); + + if (application==0) + { + dlt_log(LOG_ERR, "Application not found in dlt_daemon_process_user_message_register_context()\n"); + if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)+len)==-1) + { + dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register context\n"); + return -1; + } + return 0; + } + + /* Pre-set loglevel */ + if (usercontext->log_level == DLT_USER_LOG_LEVEL_NOT_SET) + { + loglevel=DLT_LOG_DEFAULT; + } + else + { + loglevel=usercontext->log_level; + /* Plausibility check */ + if ((loglevel<DLT_LOG_DEFAULT) || (loglevel>DLT_LOG_VERBOSE)) + { + if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)+len)==-1) + { + dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register context\n"); + } + return -1; + } + } + + /* Pre-set tracestatus */ + if (usercontext->trace_status == DLT_USER_TRACE_STATUS_NOT_SET) + { + tracestatus=DLT_TRACE_STATUS_DEFAULT; + } + else + { + tracestatus=usercontext->trace_status; + + /* Plausibility check */ + if ((tracestatus<DLT_TRACE_STATUS_DEFAULT) || (tracestatus>DLT_TRACE_STATUS_ON)) + { + if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)+len)==-1) + { + dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register context\n"); + } + return -1; + } + } + + context = dlt_daemon_context_add(daemon,usercontext->apid,usercontext->ctid, loglevel, tracestatus, usercontext->log_level_pos,application->user_handle,description,verbose); + + if (context==0) + { + if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)+len)==-1) + { + dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register context\n"); + } + + dlt_log(LOG_CRIT,"Can't add context"); + return -1; + } + /* Create automatic get log info response for registered context */ + if (daemon_local->flags.rflag) + { + /* Prepare request for get log info with one application and one context */ + if (dlt_message_init(&msg, verbose)==-1) + { + dlt_log(LOG_ERR,"Can't initialize message"); + return -1; + } + + msg.datasize = sizeof(DltServiceGetLogInfoRequest); + if (msg.databuffer) + { + free(msg.databuffer); + } + msg.databuffer = (uint8_t *) malloc(msg.datasize); + if (msg.databuffer==0) + { + dlt_log(LOG_ERR,"Can't allocate buffer for get log info message\n"); + return -1; + } + + req = (DltServiceGetLogInfoRequest*) msg.databuffer; + + req->service_id = DLT_SERVICE_ID_GET_LOG_INFO; + req->options = 7; + dlt_set_id(req->apid, usercontext->apid); + dlt_set_id(req->ctid, usercontext->ctid); + dlt_set_id(req->com,"remo"); + + sent=0; + + /* Send response to get log info request to DLT clients */ + for (j = 0; j <= daemon_local->fdmax; j++) + { + /* send to everyone! */ + if (FD_ISSET(j, &(daemon_local->master))) + { + /* except the listener and ourselves */ + if ((j != daemon_local->fp) && (j != daemon_local->sock)) + { + dlt_daemon_control_get_log_info(j , daemon, &msg, verbose); + sent=1; + } + } + } + + if (sent==0) + { + /* Store to buffer */ + dlt_daemon_control_get_log_info(DLT_DAEMON_STORE_TO_BUFFER , daemon, &msg, verbose); + } + + dlt_message_free(&msg, verbose); + } + + if (context->user_handle!=0) + { + /* This call also replaces the default values with the values defined for default */ + if (dlt_daemon_user_send_log_level(daemon, context, verbose)==-1) + { + dlt_log(LOG_ERR,"Can't send current log level as response to user message register context\n"); + return -1; + } + } + + /* keep not read data in buffer */ + if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgRegisterContext)+len)==-1) + { + dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message register context\n"); + return -1; + } + + return 0; +} + +int dlt_daemon_process_user_message_unregister_application(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose) +{ + DltUserControlMsgUnregisterApplication *usercontext; + DltDaemonApplication *application; + DltDaemonContext *context; + int i, offset_base; + + PRINT_FUNCTION_VERBOSE(verbose); + + if ((daemon==0) || (daemon_local==0)) + { + dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_unregister_application()\n"); + return -1; + } + + if (daemon_local->receiver.bytesRcvd < (sizeof(DltUserHeader)+sizeof(DltUserControlMsgUnregisterApplication))) + { + /* Not enough bytes received */ + return -1; + } + + if (daemon->num_applications>0) + { + usercontext = (DltUserControlMsgUnregisterApplication*) (daemon_local->receiver.buf+sizeof(DltUserHeader)); + + /* Delete this application and all corresponding contexts for this application from internal table */ + application = dlt_daemon_application_find(daemon,usercontext->apid, verbose); + + if (application) + { + /* Calculate start offset within contexts[] */ + offset_base=0; + for (i=0; i<(application-(daemon->applications)); i++) + { + offset_base+=daemon->applications[i].num_contexts; + } + + for (i=application->num_contexts-1; i>=0; i--) + { + context = &(daemon->contexts[offset_base+i]); + if (context) + { + /* Delete context */ + if (dlt_daemon_context_del(daemon, context, verbose)==-1) + { + dlt_log(LOG_ERR,"Can't delete context for user message unregister application\n"); + return -1; + } + } + } + + /* Delete this application entry from internal table*/ + if (dlt_daemon_application_del(daemon, application, verbose)==-1) + { + dlt_log(LOG_ERR,"Can't delete application for user message unregister application\n"); + return -1; + } + } + } + + /* keep not read data in buffer */ + if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgUnregisterApplication))==-1) + { + dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message unregister application\n"); + return -1; + } + + return 0; +} + +int dlt_daemon_process_user_message_unregister_context(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose) +{ + DltUserControlMsgUnregisterContext *usercontext; + DltDaemonContext *context; + + PRINT_FUNCTION_VERBOSE(verbose); + + if ((daemon==0) || (daemon_local==0)) + { + dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_unregister_context()\n"); + return -1; + } + + if (daemon_local->receiver.bytesRcvd < (sizeof(DltUserHeader)+sizeof(DltUserControlMsgUnregisterContext))) + { + /* Not enough bytes received */ + return -1; + } + + usercontext = (DltUserControlMsgUnregisterContext*) (daemon_local->receiver.buf+sizeof(DltUserHeader)); + context = dlt_daemon_context_find(daemon,usercontext->apid, usercontext->ctid, verbose); + + if (context) + { + /* Delete this connection entry from internal table*/ + if (dlt_daemon_context_del(daemon, context, verbose)==-1) + { + dlt_log(LOG_ERR,"Can't delete context for user message unregister context\n"); + return -1; + } + } + + /* keep not read data in buffer */ + if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgUnregisterContext))==-1) + { + dlt_log(LOG_ERR,"Can't remove bytes from receiver for user message unregister context\n"); + return -1; + } + + return 0; +} + +int dlt_daemon_process_user_message_log(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose) +{ + int bytes_to_be_removed; + int j,sent,third_value; + ssize_t ret; + + static char text[DLT_DAEMON_TEXTSIZE]; + + PRINT_FUNCTION_VERBOSE(verbose); + + if ((daemon==0) || (daemon_local==0)) + { + dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_log()\n"); + 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) + { + /* 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; + } + + /* 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; + } + } + + 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) + { + 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) + { + 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) + { + 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); + } + + 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) + { + dlt_log(LOG_ERR,"Storage of message in history buffer failed! Message discarded.\n"); + } + } + + } + /* 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); + } + + 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 + { + dlt_log(LOG_ERR,"Can't read messages from receiver\n"); + return -1; + } + + return 0; +} + +int dlt_daemon_process_user_message_set_app_ll_ts(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose) +{ + DltUserControlMsgAppLogLevelTraceStatus *usercontext; + DltDaemonApplication *application; + DltDaemonContext *context; + int i, offset_base; + int8_t old_log_level, old_trace_status; + + PRINT_FUNCTION_VERBOSE(verbose); + + if ((daemon==0) || (daemon_local==0)) + { + dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_process_user_message_set_app_ll_ts()\n"); + return -1; + } + + if (daemon_local->receiver.bytesRcvd < (sizeof(DltUserHeader)+sizeof(DltUserControlMsgAppLogLevelTraceStatus ))) + { + /* Not enough bytes receeived */ + return -1; + } + + if (daemon->num_applications>0) + { + usercontext = (DltUserControlMsgAppLogLevelTraceStatus*) (daemon_local->receiver.buf+sizeof(DltUserHeader)); + + /* Get all contexts with application id matching the received application id */ + application = dlt_daemon_application_find(daemon, usercontext->apid, verbose); + if (application) + { + /* Calculate start offset within contexts[] */ + offset_base=0; + for (i=0; i<(application-(daemon->applications)); i++) + { + offset_base+=daemon->applications[i].num_contexts; + } + + for (i=0; i < application->num_contexts; i++) + { + context = &(daemon->contexts[offset_base+i]); + if (context) + { + old_log_level = context->log_level; + context->log_level = usercontext->log_level; /* No endianess conversion necessary*/ + + old_trace_status = context->trace_status; + context->trace_status = usercontext->trace_status; /* No endianess conversion necessary */ + + /* The folowing function sends also the trace status */ + if ((context->user_handle==0) || + (dlt_daemon_user_send_log_level(daemon, context, verbose)!=0)) + { + context->log_level = old_log_level; + context->trace_status = old_trace_status; + } + } + } + } + } + + /* keep not read data in buffer */ + if (dlt_receiver_remove(&(daemon_local->receiver),sizeof(DltUserHeader)+sizeof(DltUserControlMsgAppLogLevelTraceStatus))==-1) + { + dlt_log(LOG_ERR,"Can't remove bytes from receiver\n"); + return -1; + } + + 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; + int j; + + DltDaemonTimingPacketThreadData *data; + DltDaemon *daemon; + DltDaemonLocal *daemon_local; + + if (ptr==0) + { + dlt_log(LOG_ERR, "No data pointer passed to timingpacket thread\n"); + return; + } + + data = (DltDaemonTimingPacketThreadData*)ptr; + daemon = data->daemon; + daemon_local = data->daemon_local; + + if ((daemon==0) || (daemon_local==0)) + { + dlt_log(LOG_ERR, "Invalid function parameters used for function dlt_daemon_timingpacket_thread()"); + return; + } + + if (dlt_daemon_make_periodic (1000000, &info, daemon_local->flags.vflag)<0) + { + dlt_log(LOG_CRIT,"Can't initialize thread timer!\n"); + return; + } + + while (1) + { + /* If enabled, send timing packets to all clients */ + if (daemon->timingpackets) + { + for (j = 0; j <= daemon_local->fdmax; j++) + { + /* send to everyone! */ + if (FD_ISSET(j, &(daemon_local->master))) + { + /* except the listener and ourselves */ + if ((j != daemon_local->fp) && (j != daemon_local->sock)) + { + dlt_daemon_control_message_time(j, daemon, daemon_local->flags.vflag); + } + } + } + } + /* Wait for next period */ + dlt_daemon_wait_period (&info, daemon_local->flags.vflag); + } +} + +int dlt_daemon_make_periodic (unsigned int period, DltDaemonPeriodicData *info, int verbose) +{ + int ret; + unsigned int ns; + unsigned int sec; + int fd; + struct itimerspec itval; + + PRINT_FUNCTION_VERBOSE(verbose); + + if (info==0) + { + dlt_log(LOG_ERR,"No data pointer passed!\n"); + return -1; + } + + /* Create the timer */ + fd = timerfd_create (CLOCK_MONOTONIC, 0); + + info->wakeups_missed = 0; + info->timer_fd = fd; + + if (fd == -1) + { + dlt_log(LOG_ERR,"Can't create timer filedescriptor"); + return -1; + } + + /* Make the timer periodic */ + sec = period/1000000; + ns = (period - (sec * 1000000)) * 1000; + itval.it_interval.tv_sec = sec; + itval.it_interval.tv_nsec = ns; + itval.it_value.tv_sec = sec; + itval.it_value.tv_nsec = ns; + + ret = timerfd_settime (fd, 0, &itval, NULL); + + return ret; +} + +void dlt_daemon_wait_period (DltDaemonPeriodicData *info, int verbose) +{ + unsigned long long missed; + int ret; + + PRINT_FUNCTION_VERBOSE(verbose); + + ret = read (info->timer_fd, &missed, sizeof (missed)); + + if (missed > 0) + { + info->wakeups_missed += (missed - 1); + } +} + +/** + \} +*/ diff --git a/src/daemon/dlt-daemon.h b/src/daemon/dlt-daemon.h new file mode 100755 index 0000000..e229df5 --- /dev/null +++ b/src/daemon/dlt-daemon.h @@ -0,0 +1,173 @@ +/*
+ * Dlt- Diagnostic Log and Trace daemon
+ * @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-daemon.h **
+** **
+** TARGET : linux **
+** **
+** PROJECT : DLT **
+** **
+** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de **
+** Markus Klein **
+** **
+** PURPOSE : **
+** **
+** REMARKS : **
+** **
+** PLATFORM DEPENDANT [yes/no]: yes **
+** **
+** TO BE CHANGED BY USER [yes/no]: no **
+** **
+*******************************************************************************/
+
+/*******************************************************************************
+** Author Identity **
+********************************************************************************
+** **
+** Initials Name Company **
+** -------- ------------------------- ---------------------------------- **
+** aw Alexander Wenzel BMW **
+** mk Markus Klein Fraunhofer ESK **
+*******************************************************************************/
+
+/*******************************************************************************
+** Author Identity **
+********************************************************************************
+** **
+** Initials Name Company **
+** -------- ------------------------- ---------------------------------- **
+** aw Alexander Wenzel BMW **
+** mk Markus Klein Fraunhofer ESK **
+*******************************************************************************/
+
+#ifndef DLT_DAEMON_H
+#define DLT_DAEMON_H
+
+#include "dlt_daemon_common.h"
+#include "dlt_user_shared.h"
+#include "dlt_user_shared_cfg.h"
+
+/**
+ * The flags of a dlt daemon.
+ */
+typedef struct
+{
+ int aflag; /**< (Boolean) Print DLT messages; payload as ASCII */
+ int sflag; /**< (Boolean) Print DLT messages; payload as hex */
+ int xflag; /**< (Boolean) Print DLT messages; only headers */
+ int vflag; /**< (Boolean) Verbose mode */
+ int dflag; /**< (Boolean) Daemonize */
+ int lflag; /**< (Boolean) Send DLT messages with serial header */
+ 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) */
+} DltDaemonFlags;
+
+/**
+ * The global parameters of a dlt daemon.
+ */
+typedef struct
+{
+ DltDaemonFlags flags; /**< flags of the daemon */
+ int fp; /**< handle for own fifo */
+ int sock; /**< handle for tcp connection to client */
+ int fdserial; /**< handle for serial connection */
+ int fdmax; /**< highest number of used handles */
+ 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 */
+ 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 */
+} DltDaemonLocal;
+
+typedef struct
+{
+ int timer_fd;
+ unsigned long long wakeups_missed;
+} DltDaemonPeriodicData;
+
+typedef struct
+{
+ DltDaemon *daemon;
+ DltDaemonLocal *daemon_local;
+} DltDaemonTimingPacketThreadData;
+
+/* Function prototypes */
+void dlt_daemon_local_cleanup(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose);
+int dlt_daemon_local_init_p1(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose);
+int dlt_daemon_local_init_p2(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose);
+int dlt_daemon_local_connection_init(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose);
+
+void dlt_daemon_daemonize(int verbose);
+void dlt_daemon_signal_handler(int sig);
+
+int dlt_daemon_process_client_connect(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose);
+int dlt_daemon_process_client_messages(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose);
+int dlt_daemon_process_client_messages_serial(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose);
+int dlt_daemon_process_user_messages(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose);
+
+int dlt_daemon_process_user_message_overflow(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose);
+int dlt_daemon_process_user_message_register_application(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose);
+int dlt_daemon_process_user_message_unregister_application(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose);
+int dlt_daemon_process_user_message_register_context(DltDaemon *daemon, DltDaemonLocal *daemon_local, int verbose);
+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);
+void dlt_daemon_wait_period(DltDaemonPeriodicData *info, int verbose);
+
+#endif /* DLT_DAEMON_H */
+
diff --git a/src/daemon/dlt-daemon_cfg.h b/src/daemon/dlt-daemon_cfg.h new file mode 100755 index 0000000..c69c1a1 --- /dev/null +++ b/src/daemon/dlt-daemon_cfg.h @@ -0,0 +1,125 @@ +/*
+ * Dlt- Diagnostic Log and Trace daemon
+ * @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-daemon-cfg.h **
+** **
+** TARGET : linux **
+** **
+** PROJECT : DLT **
+** **
+** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de **
+** Markus Klein **
+** **
+** PURPOSE : **
+** **
+** REMARKS : **
+** **
+** PLATFORM DEPENDANT [yes/no]: yes **
+** **
+** TO BE CHANGED BY USER [yes/no]: no **
+** **
+*******************************************************************************/
+
+/*******************************************************************************
+** Author Identity **
+********************************************************************************
+** **
+** Initials Name Company **
+** -------- ------------------------- ---------------------------------- **
+** aw Alexander Wenzel BMW **
+** mk Markus Klein Fraunhofer ESK **
+*******************************************************************************/
+
+/*******************************************************************************
+** Author Identity **
+********************************************************************************
+** **
+** Initials Name Company **
+** -------- ------------------------- ---------------------------------- **
+** aw Alexander Wenzel BMW **
+** mk Markus Klein Fraunhofer ESK **
+*******************************************************************************/
+
+#ifndef DLT_DAEMON_CFG_H
+#define DLT_DAEMON_CFG_H
+
+/*************/
+/* Changable */
+/*************/
+
+/* Stack size of timing packet thread */
+#define DLT_DAEMON_TIMINGPACKET_THREAD_STACKSIZE 100000
+
+/* Size of receive buffer for fifo connection (from user application) */
+#define DLT_DAEMON_RCVBUFSIZE 10024
+/* Size of receive buffer for socket connection (from dlt client) */
+#define DLT_DAEMON_RCVBUFSIZESOCK 10024
+/* Size of receive buffer for serial connection (from dlt client) */
+#define DLT_DAEMON_RCVBUFSIZESERIAL 10024
+
+/* Size of buffer for text output */
+#define DLT_DAEMON_TEXTSIZE 10024
+
+/* Size of buffer */
+#define DLT_DAEMON_TEXTBUFSIZE 512
+
+/* Maximum length of a description */
+#define DLT_DAEMON_DESCSIZE 256
+
+/* Name of daemon lock file, contain process id of dlt daemon instance */
+#define DLT_DAEMON_LOCK_FILE "dltd.lock"
+
+/* Umask of daemon, creates files with permission 750 */
+#define DLT_DAEMON_UMASK 027
+/* Permissions of daemon lock file */
+#define DLT_DAEMON_LOCK_FILE_PERM 0640
+
+/* Default ECU ID, used in storage header and transmitted to client*/
+#define DLT_DAEMON_ECU_ID "ECU1"
+
+/* Default baudrate for serial interface */
+#define DLT_DAEMON_SERIAL_DEFAULT_BAUDRATE 115200
+
+/************************/
+/* Don't change please! */
+/************************/
+
+#endif /* DLT_DAEMON_CFG_H */
+
diff --git a/src/daemon/dlt_daemon_common.c b/src/daemon/dlt_daemon_common.c new file mode 100755 index 0000000..4fbfd31 --- /dev/null +++ b/src/daemon/dlt_daemon_common.c @@ -0,0 +1,2196 @@ +/* + * Dlt Daemon - Diagnostic Log and Trace + * @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_daemon_common.c ** +** ** +** TARGET : linux ** +** ** +** PROJECT : DLT ** +** ** +** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** +** Markus Klein ** +** ** +** PURPOSE : ** +** ** +** REMARKS : ** +** ** +** PLATFORM DEPENDANT [yes/no]: yes ** +** ** +** TO BE CHANGED BY USER [yes/no]: no ** +** ** +*******************************************************************************/ + +/******************************************************************************* +** Author Identity ** +******************************************************************************** +** ** +** Initials Name Company ** +** -------- ------------------------- ---------------------------------- ** +** aw Alexander Wenzel BMW ** +** mk Markus Klein Fraunhofer ESK ** +*******************************************************************************/ + +/******************************************************************************* +** Revision Control History ** +*******************************************************************************/ + +/* + * $LastChangedRevision: 1670 $ + * $LastChangedDate: 2011-04-08 15:12:06 +0200 (Fr, 08. Apr 2011) $ + * $LastChangedBy$ + Initials Date Comment + aw 13.01.2010 initial + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <syslog.h> +#include <errno.h> +#include <unistd.h> +#include <fcntl.h> + +#include <sys/types.h> /* send() */ +#include <sys/socket.h> /* send() */ + +#include "dlt_types.h" +#include "dlt_daemon_common.h" +#include "dlt_daemon_common_cfg.h" +#include "dlt_user_shared.h" +#include "dlt_user_shared_cfg.h" + +static char str[DLT_DAEMON_TEXTBUFSIZE]; + +sem_t dlt_daemon_mutex; + +static int dlt_daemon_cmp_apid(const void *m1, const void *m2) +{ + DltDaemonApplication *mi1 = (DltDaemonApplication *) m1; + DltDaemonApplication *mi2 = (DltDaemonApplication *) m2; + + return memcmp(mi1->apid, mi2->apid, DLT_ID_SIZE); +} + +static int dlt_daemon_cmp_apid_ctid(const void *m1, const void *m2) +{ + + int ret, cmp; + DltDaemonContext *mi1 = (DltDaemonContext *) m1; + DltDaemonContext *mi2 = (DltDaemonContext *) m2; + + cmp=memcmp(mi1->apid, mi2->apid, DLT_ID_SIZE); + if (cmp<0) + { + ret=-1; + } + else if (cmp==0) + { + ret=memcmp(mi1->ctid, mi2->ctid, DLT_ID_SIZE); + } + else + { + ret=1; + } + + return ret; +} + +int dlt_daemon_init(DltDaemon *daemon,int verbose) +{ + PRINT_FUNCTION_VERBOSE(verbose); + + if (daemon==0) + { + return -1; + } + + daemon->num_contexts = 0; + daemon->contexts = 0; + + daemon->num_applications = 0; + daemon->applications = 0; + + daemon->default_log_level = DLT_DAEMON_INITIAL_LOG_LEVEL ; + daemon->default_trace_status = DLT_DAEMON_INITIAL_TRACE_STATUS ; + + daemon->message_buffer_overflow = DLT_MESSAGE_BUFFER_NO_OVERFLOW; + + daemon->runtime_context_cfg_loaded = 0; + + /* Check for runtime cfg, if it is loadable, load it! */ + if ((dlt_daemon_applications_load(daemon,DLT_RUNTIME_APPLICATION_CFG, verbose)==0) && + (dlt_daemon_contexts_load(daemon,DLT_RUNTIME_CONTEXT_CFG, verbose)==0)) + { + daemon->runtime_context_cfg_loaded = 1; + } + + daemon->sendserialheader = 0; + daemon->timingpackets = 0; + + 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; +} + +int dlt_daemon_free(DltDaemon *daemon,int verbose) +{ + PRINT_FUNCTION_VERBOSE(verbose); + + if (daemon==0) + { + return -1; + } + + /* Free contexts */ + if (dlt_daemon_contexts_clear(daemon, verbose)==-1) + { + return -1; + } + + /* Free applications */ + if (dlt_daemon_applications_clear(daemon, verbose)==-1) + { + return -1; + } + + return 0; +} + +int dlt_daemon_applications_clear(DltDaemon *daemon,int verbose) +{ + uint32_t i; + + PRINT_FUNCTION_VERBOSE(verbose); + + if (daemon==0) + { + return -1; + } + + for (i=0; i<daemon->num_applications; i++) + { + if (daemon->applications[i].application_description!=0) + { + free(daemon->applications[i].application_description); + daemon->applications[i].application_description = 0; + } + } + + if (daemon->applications) + { + free(daemon->applications); + } + + daemon->applications = 0; + daemon->num_applications = 0; + + return 0; +} + +DltDaemonApplication* dlt_daemon_application_add(DltDaemon *daemon,char *apid,pid_t pid,char *description, int verbose) +{ + DltDaemonApplication *application; + DltDaemonApplication *old; + int new_application; + int dlt_user_handle; + char filename[DLT_DAEMON_TEXTBUFSIZE]; + + if ((daemon==0) || (apid==0) || (apid[0]=='\0')) + { + return (DltDaemonApplication*) 0; + } + + if (daemon->applications == 0) + { + daemon->applications = (DltDaemonApplication*) malloc(sizeof(DltDaemonApplication)*DLT_DAEMON_APPL_ALLOC_SIZE); + if (daemon->applications==0) + { + return (DltDaemonApplication*) 0; + } + } + + new_application=0; + + /* Check if application [apid] is already available */ + application = dlt_daemon_application_find(daemon, apid, verbose); + if (application==0) + { + daemon->num_applications += 1; + + if (daemon->num_applications!=0) + { + if ((daemon->num_applications%DLT_DAEMON_APPL_ALLOC_SIZE)==0) + { + /* allocate memory in steps of DLT_DAEMON_APPL_ALLOC_SIZE, e.g. 100 */ + old = daemon->applications; + daemon->applications = (DltDaemonApplication*) malloc(sizeof(DltDaemonApplication)* + ((daemon->num_applications/DLT_DAEMON_APPL_ALLOC_SIZE)+1)*DLT_DAEMON_APPL_ALLOC_SIZE); + if (daemon->applications==0) + { + daemon->applications = old; + return (DltDaemonApplication*) 0; + } + memcpy(daemon->applications,old,sizeof(DltDaemonApplication)*daemon->num_applications); + free(old); + } + } + + application = &(daemon->applications[daemon->num_applications-1]); + + dlt_set_id(application->apid,apid); + application->application_description = 0; + application->num_contexts = 0; + + new_application = 1; + } + + /* Store application description and pid of application */ + if (application->application_description) + { + free(application->application_description); + } + + application->application_description=0; + + if (description) + { + application->application_description = malloc(strlen(description)+1); + if (application->application_description) + { + strncpy(application->application_description,description,strlen(description)+1); + application->application_description[strlen(description)]='\0'; + } + } + + application->pid = pid; + + application->user_handle = -1; + + if (pid) + { + sprintf(filename,"%s/dlt%d",DLT_USER_DIR,application->pid); + + dlt_user_handle = open(filename, O_WRONLY|O_NONBLOCK); + if (dlt_user_handle <0) + { + sprintf(str,"open() failed to %s, errno=%d (%s)!\n",filename,errno,strerror(errno)); /* errno 2: ENOENT - No such file or directory */ + dlt_log(LOG_ERR, str); + } /* if */ + + application->user_handle = dlt_user_handle; + } + + /* Sort */ + if (new_application) + { + qsort(daemon->applications,daemon->num_applications,sizeof(DltDaemonApplication),dlt_daemon_cmp_apid); + + /* Find new position of application with apid*/ + application = dlt_daemon_application_find(daemon, apid, verbose); + } + + return application; +} + +int dlt_daemon_application_del(DltDaemon *daemon, DltDaemonApplication *application, int verbose) +{ + int pos; + + PRINT_FUNCTION_VERBOSE(verbose); + + if ((daemon==0) || (application==0)) + { + return -1; + } + + if (daemon->num_applications>0) + { + /* Check if user handle is open; if yes, close it */ + if (application->user_handle!=-1) + { + close(application->user_handle); + application->user_handle=-1; + } + + /* Free description of application to be deleted */ + if (application->application_description) + { + free(application->application_description); + application->application_description = 0; + } + + pos = application-(daemon->applications); + + /* move all applications above pos to pos */ + memmove(&(daemon->applications[pos]),&(daemon->applications[pos+1]), sizeof(DltDaemonApplication)*((daemon->num_applications-1)-pos)); + + /* Clear last application */ + memset(&(daemon->applications[daemon->num_applications-1]),0,sizeof(DltDaemonApplication)); + + daemon->num_applications--; + + } + + return 0; +} + +DltDaemonApplication* dlt_daemon_application_find(DltDaemon *daemon,char *apid,int verbose) +{ + DltDaemonApplication application; + + PRINT_FUNCTION_VERBOSE(verbose); + + if ((daemon==0) || (apid==0) || (apid[0]=='\0') || (daemon->num_applications==0)) + { + return (DltDaemonApplication*) 0; + } + + /* Check, if apid is smaller than smallest apid or greater than greatest apid */ + if ((memcmp(apid,daemon->applications[0].apid,DLT_ID_SIZE)<0) || + (memcmp(apid,daemon->applications[daemon->num_applications-1].apid,DLT_ID_SIZE)>0)) + { + return (DltDaemonApplication*) 0; + } + + dlt_set_id(application.apid,apid); + return (DltDaemonApplication*)bsearch(&application,daemon->applications,daemon->num_applications,sizeof(DltDaemonApplication),dlt_daemon_cmp_apid); +} + +int dlt_daemon_applications_load(DltDaemon *daemon,const char *filename, int verbose) +{ + FILE *fd; + ID4 apid; + char buf[DLT_DAEMON_TEXTBUFSIZE]; + char *ret; + char *pb; + + PRINT_FUNCTION_VERBOSE(verbose); + + if ((daemon==0) || (filename==0) || (filename[0]=='\0')) + { + return -1; + } + + fd=fopen(filename, "r"); + + if (fd==0) + { + return -1; + } + + while (!feof(fd)) + { + /* Clear buf */ + memset(buf, 0, sizeof(buf)); + + /* Get line */ + ret=fgets(buf,sizeof(buf),fd); + + if (strcmp(buf,"")!=0) + { + /* Split line */ + pb=strtok(buf,":"); + dlt_set_id(apid,pb); + pb=strtok(NULL,":"); + /* pb contains now the description */ + + /* pid is unknown at loading time */ + if (dlt_daemon_application_add(daemon,apid,0,pb,verbose)==0) + { + fclose(fd); + return -1; + } + } + } + fclose(fd); + + return 0; +} + +int dlt_daemon_applications_save(DltDaemon *daemon,const char *filename, int verbose) +{ + FILE *fd; + uint32_t i; + + char apid[DLT_ID_SIZE+1]; /* DLT_ID_SIZE+1, because the 0-termination is required here */ + + PRINT_FUNCTION_VERBOSE(verbose); + + if ((daemon==0) || (filename==0) || (filename[0]=='\0')) + { + return -1; + } + + memset(apid,0, sizeof(apid)); + + if ((daemon->applications) && (daemon->num_applications>0)) + { + fd=fopen(filename, "w"); + if (fd!=0) + { + for (i=0; i<daemon->num_applications; i++) + { + dlt_set_id(apid,daemon->applications[i].apid); + + if ((daemon->applications[i].application_description) && + (daemon->applications[i].application_description!='\0')) + { + fprintf(fd,"%s:%s:\n",apid, daemon->applications[i].application_description); + } + else + { + fprintf(fd,"%s::\n",apid); + } + } + fclose(fd); + } + } + + return 0; +} + +DltDaemonContext* dlt_daemon_context_add(DltDaemon *daemon,char *apid,char *ctid,int8_t log_level,int8_t trace_status,int log_level_pos, int user_handle,char *description,int verbose) +{ + DltDaemonApplication *application; + DltDaemonContext *context; + DltDaemonContext *old; + int new_context=0; + + PRINT_FUNCTION_VERBOSE(verbose); + + if ((daemon==0) || (apid==0) || (apid[0]=='\0') || (ctid==0) || (ctid[0]=='\0')) + { + return (DltDaemonContext*) 0; + } + + if ((log_level<DLT_LOG_DEFAULT) || (log_level>DLT_LOG_VERBOSE)) + { + return (DltDaemonContext*) 0; + } + + if ((trace_status<DLT_TRACE_STATUS_DEFAULT) || (trace_status>DLT_TRACE_STATUS_ON)) + { + return (DltDaemonContext*) 0; + } + + if (daemon->contexts == 0) + { + daemon->contexts = (DltDaemonContext*) malloc(sizeof(DltDaemonContext)*DLT_DAEMON_CONTEXT_ALLOC_SIZE); + if (daemon->contexts==0) + { + return (DltDaemonContext*) 0; + } + } + + /* Check if application [apid] is available */ + application = dlt_daemon_application_find(daemon, apid, verbose); + if (application==0) + { + return (DltDaemonContext*) 0; + } + + /* Check if context [apid, ctid] is already available */ + context = dlt_daemon_context_find(daemon, apid, ctid, verbose); + if (context==0) + { + daemon->num_contexts += 1; + + if (daemon->num_contexts!=0) + { + if ((daemon->num_contexts%DLT_DAEMON_CONTEXT_ALLOC_SIZE)==0) + { + /* allocate memory for context in steps of DLT_DAEMON_CONTEXT_ALLOC_SIZE, e.g 100 */ + old = daemon->contexts; + daemon->contexts = (DltDaemonContext*) malloc(sizeof(DltDaemonContext)* + ((daemon->num_contexts/DLT_DAEMON_CONTEXT_ALLOC_SIZE)+1)*DLT_DAEMON_CONTEXT_ALLOC_SIZE); + if (daemon->contexts==0) + { + daemon->contexts = old; + return (DltDaemonContext*) 0; + } + memcpy(daemon->contexts,old,sizeof(DltDaemonContext)*daemon->num_contexts); + free(old); + } + } + + context = &(daemon->contexts[daemon->num_contexts-1]); + + dlt_set_id(context->apid,apid); + dlt_set_id(context->ctid,ctid); + context->context_description = 0; + + application->num_contexts++; + new_context =1; + } + + /* Set context description */ + if (context->context_description) + { + free(context->context_description); + } + + context->context_description=0; + + if (description) + { + context->context_description = malloc(strlen(description)+1); + + if (context->context_description) + { + strncpy(context->context_description,description,strlen(description)+1); + context->context_description[strlen(description)]='\0'; + } + } + + /* Store log level and trace status, + if this is a new context, or + if this is an old context and the runtime cfg was not loaded */ + + if ((new_context==1) || + ((new_context==0) && (daemon->runtime_context_cfg_loaded==0))) + { + context->log_level = log_level; + context->trace_status = trace_status; + } + + context->log_level_pos = log_level_pos; + context->user_handle = user_handle; + + /* Sort */ + if (new_context) + { + qsort(daemon->contexts,daemon->num_contexts, sizeof(DltDaemonContext),dlt_daemon_cmp_apid_ctid); + + /* Find new position of context with apid, ctid */ + context = dlt_daemon_context_find(daemon, apid, ctid, verbose); + } + + return context; +} + +int dlt_daemon_context_del(DltDaemon *daemon, DltDaemonContext* context, int verbose) +{ + int pos; + DltDaemonApplication *application; + + PRINT_FUNCTION_VERBOSE(verbose); + + if ((daemon==0) || (context==0)) + { + return -1; + } + + if (daemon->num_contexts>0) + { + application = dlt_daemon_application_find(daemon, context->apid, verbose); + + /* Free description of context to be deleted */ + if (context->context_description) + { + free(context->context_description); + context->context_description = 0; + } + + pos = context-(daemon->contexts); + + /* move all contexts above pos to pos */ + memmove(&(daemon->contexts[pos]),&(daemon->contexts[pos+1]), sizeof(DltDaemonContext)*((daemon->num_contexts-1)-pos)); + + /* Clear last context */ + memset(&(daemon->contexts[daemon->num_contexts-1]),0,sizeof(DltDaemonContext)); + + daemon->num_contexts--; + + /* Check if application [apid] is available */ + if (application) + { + application->num_contexts--; + } + } + + return 0; +} + +DltDaemonContext* dlt_daemon_context_find(DltDaemon *daemon,char *apid,char *ctid,int verbose) +{ + DltDaemonContext context; + + PRINT_FUNCTION_VERBOSE(verbose); + + if ((daemon==0) || (apid==0) || (apid[0]=='\0') || (ctid==0) || (ctid[0]=='\0') || (daemon->num_contexts==0)) + { + return (DltDaemonContext*) 0; + } + + /* Check, if apid is smaller than smallest apid or greater than greatest apid */ + if ((memcmp(apid,daemon->contexts[0].apid,DLT_ID_SIZE)<0) || + (memcmp(apid,daemon->contexts[daemon->num_contexts-1].apid,DLT_ID_SIZE)>0)) + { + return (DltDaemonContext*) 0; + } + + dlt_set_id(context.apid,apid); + dlt_set_id(context.ctid,ctid); + + return (DltDaemonContext*)bsearch(&context,daemon->contexts,daemon->num_contexts,sizeof(DltDaemonContext),dlt_daemon_cmp_apid_ctid); +} + +int dlt_daemon_contexts_clear(DltDaemon *daemon,int verbose) +{ + int i; + + PRINT_FUNCTION_VERBOSE(verbose); + + if (daemon==0) + { + return -1; + } + + for (i=0; i<daemon->num_contexts; i++) + { + if (daemon->contexts[i].context_description!=0) + { + free(daemon->contexts[i].context_description); + daemon->contexts[i].context_description = 0; + } + } + + if (daemon->contexts) + { + free(daemon->contexts); + } + + daemon->contexts = 0; + + for (i=0; i<daemon->num_applications; i++) + { + daemon->applications[i].num_contexts = 0; + } + + daemon->num_contexts = 0; + + return 0; +} + +int dlt_daemon_contexts_load(DltDaemon *daemon,const char *filename, int verbose) +{ + FILE *fd; + ID4 apid, ctid; + char buf[DLT_DAEMON_TEXTBUFSIZE]; + char *ret; + char *pb; + int ll, ts; + + PRINT_FUNCTION_VERBOSE(verbose); + + if ((daemon==0) || (filename==0) ||( filename[0]=='\0')) + { + return -1; + } + + fd=fopen(filename, "r"); + + if (fd==0) + { + return -1; + } + + while (!feof(fd)) + { + /* Clear buf */ + memset(buf, 0, sizeof(buf)); + + /* Get line */ + ret=fgets(buf,sizeof(buf),fd); + + if (strcmp(buf,"")!=0) + { + /* Split line */ + pb=strtok(buf,":"); + dlt_set_id(apid,pb); + pb=strtok(NULL,":"); + dlt_set_id(ctid,pb); + pb=strtok(NULL,":"); + sscanf(pb,"%d",&ll); + pb=strtok(NULL,":"); + sscanf(pb,"%d",&ts); + pb=strtok(NULL,":"); + /* pb contains now the description */ + + /* log_level_pos, and user_handle are unknown at loading time */ + if (dlt_daemon_context_add(daemon,apid,ctid,(int8_t)ll,(int8_t)ts,0,0,pb,verbose)==0) + { + fclose(fd); + return -1; + } + } + } + fclose(fd); + + return 0; +} + +int dlt_daemon_contexts_save(DltDaemon *daemon,const char *filename, int verbose) +{ + FILE *fd; + uint32_t i; + + char apid[DLT_ID_SIZE+1], ctid[DLT_ID_SIZE+1]; /* DLT_ID_SIZE+1, because the 0-termination is required here */ + + PRINT_FUNCTION_VERBOSE(verbose); + + if ((daemon==0) || (filename==0) ||( filename[0]=='\0')) + { + return -1; + } + + memset(apid,0, sizeof(apid)); + memset(ctid,0, sizeof(ctid)); + + if ((daemon->contexts) && (daemon->num_contexts>0)) + { + fd=fopen(filename, "w"); + if (fd!=0) + { + for (i=0; i<daemon->num_contexts; i++) + { + dlt_set_id(apid,daemon->contexts[i].apid); + dlt_set_id(ctid,daemon->contexts[i].ctid); + + if ((daemon->contexts[i].context_description) && + (daemon->contexts[i].context_description[0]!='\0')) + { + fprintf(fd,"%s:%s:%d:%d:%s:\n",apid,ctid, + (int)(daemon->contexts[i].log_level), + (int)(daemon->contexts[i].trace_status), + daemon->contexts[i].context_description); + } + else + { + fprintf(fd,"%s:%s:%d:%d::\n",apid,ctid, + (int)(daemon->contexts[i].log_level), + (int)(daemon->contexts[i].trace_status)); + } + } + fclose(fd); + } + } + + return 0; +} + +int dlt_daemon_user_send_log_level(DltDaemon *daemon,DltDaemonContext *context,int verbose) +{ + DltUserHeader userheader; + DltUserControlMsgLogLevel usercontext; + DltReturnValue ret; + + PRINT_FUNCTION_VERBOSE(verbose); + + if ((daemon==0) || (context==0)) + { + return -1; + } + + if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG_LEVEL)==-1) + { + return -1; + } + + usercontext.log_level = ((context->log_level == DLT_LOG_DEFAULT)?daemon->default_log_level:context->log_level); + usercontext.trace_status = ((context->trace_status == DLT_TRACE_STATUS_DEFAULT)?daemon->default_trace_status:context->trace_status); + + usercontext.log_level_pos = context->log_level_pos; + + /* log to FIFO */ + ret = dlt_user_log_out2(context->user_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgLogLevel)); + + if (ret!=DLT_RETURN_OK) + { + if (errno==EPIPE) + { + /* Close connection */ + close(context->user_handle); + context->user_handle=0; + } + } + + return ((ret==DLT_RETURN_OK)?0:-1); +} + +int dlt_daemon_control_process_control(int sock, DltDaemon *daemon, DltMessage *msg, int verbose) +{ + uint32_t id,id_tmp=0; + + PRINT_FUNCTION_VERBOSE(verbose); + + if ((daemon==0) || (msg==0)) + { + return -1; + } + + if (msg->datasize<sizeof(uint32_t)) + { + return -1; + } + + id_tmp = *((uint32_t*)(msg->databuffer)); + id=DLT_ENDIAN_GET_32(msg->standardheader->htyp ,id_tmp); + + if ((id > 0) && (id <= DLT_SERVICE_ID_MESSAGE_BUFFER_OVERFLOW)) + { + /* Control message handling */ + switch (id) + { + case DLT_SERVICE_ID_SET_LOG_LEVEL: + { + dlt_daemon_control_set_log_level(sock, daemon, msg, verbose); + break; + } + case DLT_SERVICE_ID_SET_TRACE_STATUS: + { + dlt_daemon_control_set_trace_status(sock, daemon, msg, verbose); + break; + } + case DLT_SERVICE_ID_GET_LOG_INFO: + { + dlt_daemon_control_get_log_info(sock, daemon, msg, verbose); + break; + } + case DLT_SERVICE_ID_GET_DEFAULT_LOG_LEVEL: + { + dlt_daemon_control_get_default_log_level(sock, daemon, verbose); + break; + } + case DLT_SERVICE_ID_STORE_CONFIG: + { + if (dlt_daemon_applications_save(daemon, DLT_RUNTIME_APPLICATION_CFG, verbose)==0) + { + if (dlt_daemon_contexts_save(daemon, DLT_RUNTIME_CONTEXT_CFG, verbose)==0) + { + dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_OK, verbose); + } + else + { + /* Delete saved files */ + dlt_daemon_control_reset_to_factory_default(daemon, DLT_RUNTIME_APPLICATION_CFG, DLT_RUNTIME_CONTEXT_CFG, verbose); + dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR, verbose); + } + } + else + { + dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR, verbose); + } + break; + } + case DLT_SERVICE_ID_RESET_TO_FACTORY_DEFAULT: + { + dlt_daemon_control_reset_to_factory_default(daemon, DLT_RUNTIME_APPLICATION_CFG, DLT_RUNTIME_CONTEXT_CFG, verbose); + dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_OK, verbose); + break; + } + case DLT_SERVICE_ID_SET_COM_INTERFACE_STATUS: + { + dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose); + break; + } + case DLT_SERVICE_ID_SET_COM_INTERFACE_MAX_BANDWIDTH: + { + dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose); + break; + } + case DLT_SERVICE_ID_SET_VERBOSE_MODE: + { + dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose); + break; + } + case DLT_SERVICE_ID_SET_MESSAGE_FILTERING: + { + dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose); + break; + } + case DLT_SERVICE_ID_SET_TIMING_PACKETS: + { + dlt_daemon_control_set_timing_packets(sock, daemon, msg, verbose); + break; + } + case DLT_SERVICE_ID_GET_LOCAL_TIME: + { + /* Send response with valid timestamp (TMSP) field */ + dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_OK, verbose); + break; + } + case DLT_SERVICE_ID_USE_ECU_ID: + { + dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose); + break; + } + case DLT_SERVICE_ID_USE_SESSION_ID: + { + dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose); + break; + } + case DLT_SERVICE_ID_USE_TIMESTAMP: + { + dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose); + break; + } + case DLT_SERVICE_ID_USE_EXTENDED_HEADER: + { + dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose); + break; + } + case DLT_SERVICE_ID_SET_DEFAULT_LOG_LEVEL: + { + dlt_daemon_control_set_default_log_level(sock, daemon, msg, verbose); + break; + } + case DLT_SERVICE_ID_SET_DEFAULT_TRACE_STATUS: + { + dlt_daemon_control_set_default_trace_status(sock, daemon, msg, verbose); + break; + } + case DLT_SERVICE_ID_GET_SOFTWARE_VERSION: + { + dlt_daemon_control_get_software_version(sock, daemon, verbose); + break; + } + case DLT_SERVICE_ID_MESSAGE_BUFFER_OVERFLOW: + { + dlt_daemon_control_message_buffer_overflow(sock, daemon, verbose); + break; + } + default: + { + dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose); + break; + } + } + } + else + { + /* Injection handling */ + dlt_daemon_control_callsw_cinjection(sock, daemon, msg, verbose); + } + + return 0; +} + +void dlt_daemon_control_callsw_cinjection(int sock, DltDaemon *daemon, DltMessage *msg, int verbose) +{ + char apid[DLT_ID_SIZE],ctid[DLT_ID_SIZE]; + uint32_t id=0,id_tmp=0; + uint8_t *ptr; + DltDaemonContext *context; + uint32_t data_length_inject=0,data_length_inject_tmp=0; + + int32_t datalength; + + DltUserHeader userheader; + DltUserControlMsgInjection usercontext; + uint8_t *userbuffer; + + PRINT_FUNCTION_VERBOSE(verbose); + + if ((daemon==0) || (msg==0)) + { + return; + } + + datalength = msg->datasize; + ptr = msg->databuffer; + + if (ptr==0) + { + return; + } + + DLT_MSG_READ_VALUE(id_tmp,ptr,datalength,uint32_t); /* Get service id */ + id=DLT_ENDIAN_GET_32(msg->standardheader->htyp, id_tmp); + + if ((id>=DLT_DAEMON_INJECTION_MIN) && (id<=DLT_DAEMON_INJECTION_MAX)) + { + /* This a a real SW-C injection call */ + data_length_inject=0; + data_length_inject_tmp=0; + + DLT_MSG_READ_VALUE(data_length_inject_tmp,ptr,datalength,uint32_t); /* Get data length */ + data_length_inject=DLT_ENDIAN_GET_32(msg->standardheader->htyp, data_length_inject_tmp); + + /* Get context handle for apid, ctid (and seid) */ + /* Warning: seid is ignored in this implementation! */ + if (DLT_IS_HTYP_UEH(msg->standardheader->htyp)) + { + dlt_set_id(apid, msg->extendedheader->apid); + dlt_set_id(ctid, msg->extendedheader->ctid); + } + else + { + /* No extended header, and therefore no apid and ctid available */ + dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR, verbose); + return; + } + + /* At this point, apid and ctid is available */ + context=dlt_daemon_context_find(daemon, apid, ctid, verbose); + + if (context==0) + { + // dlt_log(LOG_INFO,"No context found!\n"); + dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR, verbose); + return; + } + + /* Send user message to handle, specified in context */ + if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_INJECTION)==-1) + { + dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR, verbose); + return; + } + + usercontext.log_level_pos = context->log_level_pos; + + userbuffer = malloc(data_length_inject); + + if (userbuffer==0) + { + dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR, verbose); + return; + } + + usercontext.data_length_inject = data_length_inject; + usercontext.service_id = id; + + memcpy(userbuffer,ptr,data_length_inject); /* Copy received injection to send buffer */ + + /* write to FIFO */ + if (dlt_user_log_out3(context->user_handle, &(userheader), sizeof(DltUserHeader), + &(usercontext), sizeof(DltUserControlMsgInjection), + userbuffer, data_length_inject)!=DLT_RETURN_OK) + { + if (errno==EPIPE) + { + /* Close connection */ + close(context->user_handle); + context->user_handle=0; + } + dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR, verbose); + } + else + { + dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_OK, verbose); + } + + free(userbuffer); + userbuffer=0; + + } + else + { + /* Invalid ID */ + dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_NOT_SUPPORTED, verbose); + } +} + +void dlt_daemon_control_set_log_level(int sock, DltDaemon *daemon, DltMessage *msg, int verbose) +{ + PRINT_FUNCTION_VERBOSE(verbose); + + char apid[DLT_ID_SIZE],ctid[DLT_ID_SIZE]; + DltServiceSetLogLevel *req; + DltDaemonContext *context; + int32_t id=DLT_SERVICE_ID_SET_LOG_LEVEL; + + int8_t old_log_level; + + if ((daemon==0) || (msg==0)) + { + return; + } + + req = (DltServiceSetLogLevel*) (msg->databuffer); + + dlt_set_id(apid, req->apid); + dlt_set_id(ctid, req->ctid); + + context=dlt_daemon_context_find(daemon, apid, ctid, verbose); + + /* Set log level */ + if (context!=0) + { + old_log_level = context->log_level; + context->log_level = req->log_level; /* No endianess conversion necessary*/ + + if ((context->user_handle!=0) && + (dlt_daemon_user_send_log_level(daemon, context, verbose)==0)) + { + dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_OK, verbose); + } + else + { + //dlt_log(LOG_ERR, "Log level could not be sent!\n"); + context->log_level = old_log_level; + dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR, verbose); + } + } + else + { + //dlt_log(LOG_ERR, "Context not found!\n"); + dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR, verbose); + } +} + +void dlt_daemon_control_set_trace_status(int sock, DltDaemon *daemon, DltMessage *msg, int verbose) +{ + PRINT_FUNCTION_VERBOSE(verbose); + + char apid[DLT_ID_SIZE],ctid[DLT_ID_SIZE]; + DltServiceSetLogLevel *req; /* request uses same struct as set log level */ + DltDaemonContext *context; + int32_t id=DLT_SERVICE_ID_SET_TRACE_STATUS; + + int8_t old_trace_status; + + if ((daemon==0) || (msg==0)) + { + return; + } + + req = (DltServiceSetLogLevel*) (msg->databuffer); + + dlt_set_id(apid, req->apid); + dlt_set_id(ctid, req->ctid); + + context=dlt_daemon_context_find(daemon, apid, ctid, verbose); + + /* Set log level */ + if (context!=0) + { + old_trace_status = context->trace_status; + context->trace_status = req->log_level; /* No endianess conversion necessary */ + + if ((context->user_handle!=0) && + (dlt_daemon_user_send_log_level(daemon, context, verbose)==0)) + { + dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_OK, verbose); + } + else + { + //dlt_log(LOG_ERR, "Trace Status could not be sent!\n"); + context->trace_status = old_trace_status; + dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR, verbose); + } + } + else + { + //dlt_log(LOG_ERR, "Context not found!\n"); + dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR, verbose); + } +} + +void dlt_daemon_control_set_default_log_level(int sock, DltDaemon *daemon, DltMessage *msg, int verbose) +{ + PRINT_FUNCTION_VERBOSE(verbose); + + DltServiceSetDefaultLogLevel *req; + int32_t id=DLT_SERVICE_ID_SET_DEFAULT_LOG_LEVEL; + + if ((daemon==0) || (msg==0)) + { + return; + } + + req = (DltServiceSetDefaultLogLevel*) (msg->databuffer); + + /* No endianess conversion necessary */ + if ((req->log_level>=0) && + (req->log_level<=DLT_LOG_VERBOSE)) + { + daemon->default_log_level = req->log_level; /* No endianess conversion necessary */ + + /* Send Update to all contexts using the default log level */ + dlt_daemon_user_send_default_update(daemon, verbose); + + dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_OK, verbose); + } + else + { + dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR, verbose); + } +} + +void dlt_daemon_control_set_default_trace_status(int sock, DltDaemon *daemon, DltMessage *msg, int verbose) +{ + PRINT_FUNCTION_VERBOSE(verbose); + + /* Payload of request message */ + DltServiceSetDefaultLogLevel *req; + int32_t id=DLT_SERVICE_ID_SET_DEFAULT_TRACE_STATUS; + + if ((daemon==0) || (msg==0)) + { + return; + } + + req = (DltServiceSetDefaultLogLevel*) (msg->databuffer); + + /* No endianess conversion necessary */ + if ((req->log_level==DLT_TRACE_STATUS_OFF) || + (req->log_level==DLT_TRACE_STATUS_ON)) + { + daemon->default_trace_status = req->log_level; /* No endianess conversion necessary*/ + + /* Send Update to all contexts using the default trace status */ + dlt_daemon_user_send_default_update(daemon, verbose); + + dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_OK, verbose); + } + else + { + dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR, verbose); + } +} + +void dlt_daemon_control_set_timing_packets(int sock, DltDaemon *daemon, DltMessage *msg, int verbose) +{ + PRINT_FUNCTION_VERBOSE(verbose); + + DltServiceSetVerboseMode *req; /* request uses same struct as set verbose mode */ + int32_t id=DLT_SERVICE_ID_SET_TIMING_PACKETS; + + if ((daemon==0) || (msg==0)) + { + return; + } + + req = (DltServiceSetVerboseMode*) (msg->databuffer); + if ((req->new_status==0) || (req->new_status==1)) + { + daemon->timingpackets = req->new_status; + + dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_OK, verbose); + } + else + { + dlt_daemon_control_service_response(sock, daemon, id, DLT_SERVICE_RESPONSE_ERROR, verbose); + } +} + +void dlt_daemon_control_get_software_version(int sock, DltDaemon *daemon, int verbose) +{ + char version[DLT_DAEMON_TEXTBUFSIZE]; + DltMessage msg; + uint32_t len; + DltServiceGetSoftwareVersionResponse *resp; + + PRINT_FUNCTION_VERBOSE(verbose); + + if (daemon==0) + { + return; + } + + /* initialise new message */ + if (dlt_message_init(&msg,0)==-1) + { + dlt_daemon_control_service_response(sock, daemon, DLT_SERVICE_ID_GET_SOFTWARE_VERSION, DLT_SERVICE_RESPONSE_ERROR, verbose); + return; + } + + /* prepare payload of data */ + dlt_get_version(version); + len = strlen(version); + + msg.datasize = sizeof(DltServiceGetSoftwareVersionResponse) + len; + if (msg.databuffer) + { + free(msg.databuffer); + } + msg.databuffer = (uint8_t *) malloc(msg.datasize); + if (msg.databuffer==0) + { + dlt_daemon_control_service_response(sock, daemon, DLT_SERVICE_ID_GET_SOFTWARE_VERSION, DLT_SERVICE_RESPONSE_ERROR, verbose); + return; + } + + resp = (DltServiceGetSoftwareVersionResponse*) msg.databuffer; + resp->service_id = DLT_SERVICE_ID_GET_SOFTWARE_VERSION; + resp->status = DLT_SERVICE_RESPONSE_OK; + resp->length = len; + memcpy(msg.databuffer+sizeof(DltServiceGetSoftwareVersionResponse),version,len); + + /* send message */ + dlt_daemon_control_send_control_message(sock, daemon, &msg,"","", verbose); + + /* free message */ + dlt_message_free(&msg,0); +} + +void dlt_daemon_control_get_default_log_level(int sock, DltDaemon *daemon, int verbose) +{ + DltMessage msg; + DltServiceGetDefaultLogLevelResponse *resp; + + PRINT_FUNCTION_VERBOSE(verbose); + + if (daemon==0) + { + return; + } + + /* initialise new message */ + if (dlt_message_init(&msg,0)==-1) + { + dlt_daemon_control_service_response(sock, daemon, DLT_SERVICE_ID_GET_DEFAULT_LOG_LEVEL, DLT_SERVICE_RESPONSE_ERROR, verbose); + return; + } + + msg.datasize = sizeof(DltServiceGetDefaultLogLevelResponse); + if (msg.databuffer) + { + free(msg.databuffer); + } + msg.databuffer = (uint8_t *) malloc(msg.datasize); + if (msg.databuffer==0) + { + dlt_daemon_control_service_response(sock, daemon, DLT_SERVICE_ID_GET_DEFAULT_LOG_LEVEL, DLT_SERVICE_RESPONSE_ERROR, verbose); + return; + } + + resp = (DltServiceGetDefaultLogLevelResponse*) msg.databuffer; + resp->service_id = DLT_SERVICE_ID_GET_DEFAULT_LOG_LEVEL; + resp->status = DLT_SERVICE_RESPONSE_OK; + resp->log_level = daemon->default_log_level; + + /* send message */ + dlt_daemon_control_send_control_message(sock,daemon,&msg,"","", verbose); + + /* free message */ + dlt_message_free(&msg,0); +} + +void dlt_daemon_control_get_log_info(int sock, DltDaemon *daemon, DltMessage *msg, int verbose) +{ + DltServiceGetLogInfoRequest *req; + DltMessage resp; + DltDaemonContext *context=0; + DltDaemonApplication *application=0; + + int num_applications=0, num_contexts=0; + uint16_t count_app_ids=0, count_con_ids=0; + +#if (DLT_DEBUG_GETLOGINFO==1) + char buf[255]; +#endif + + int32_t i,j,offset=0; + char *apid=0; + int8_t ll,ts; + uint16_t len; + int8_t value; + int32_t sizecont=0; + int offset_base; + + uint32_t sid; + + PRINT_FUNCTION_VERBOSE(verbose); + + if ((daemon==0) || (msg==0)) + { + return; + } + + /* prepare pointer to message request */ + req = (DltServiceGetLogInfoRequest*) (msg->databuffer); + + /* initialise new message */ + if (dlt_message_init(&resp,0)==-1) + { + dlt_daemon_control_service_response(sock, daemon, DLT_SERVICE_ID_GET_LOG_INFO, DLT_SERVICE_RESPONSE_ERROR, verbose); + return; + } + + /* check request */ + if ((req->options < 3 ) || (req->options>7)) + { + dlt_daemon_control_service_response(sock, daemon, DLT_SERVICE_ID_GET_LOG_INFO, DLT_SERVICE_RESPONSE_ERROR, verbose); + return; + } + + if (req->apid[0]!='\0') + { + application = dlt_daemon_application_find(daemon, req->apid, verbose); + if (application) + { + num_applications = 1; + if (req->ctid[0]!='\0') + { + context = dlt_daemon_context_find(daemon, req->apid, req->ctid, verbose); + + num_contexts = ((context)?1:0); + } + else + { + num_contexts = application->num_contexts; + } + } + else + { + num_applications = 0; + num_contexts = 0; + } + } + else + { + /* Request all applications and contexts */ + num_applications = daemon->num_applications; + num_contexts = daemon->num_contexts; + } + + /* prepare payload of data */ + + /* Calculate maximum size for a response */ + resp.datasize = sizeof(uint32_t) /* SID */ + sizeof(int8_t) /* status*/ + sizeof(ID4) /* DLT_DAEMON_REMO_STRING */; + + sizecont = sizeof(uint32_t) /* context_id */; + + /* Add additional size for response of Mode 4, 6, 7 */ + if ((req->options==4) || (req->options==6) || (req->options==7)) + { + sizecont += sizeof(int8_t); /* log level */ + } + + /* Add additional size for response of Mode 5, 6, 7 */ + if ((req->options==5) || (req->options==6) || (req->options==7)) + { + sizecont+= sizeof(int8_t); /* trace status */ + } + + resp.datasize+= (num_applications * (sizeof(uint32_t) /* app_id */ + sizeof(uint16_t) /* count_con_ids */)) + + (num_contexts * sizecont); + + resp.datasize+= sizeof(uint16_t) /* count_app_ids */; + + /* Add additional size for response of Mode 7 */ + if (req->options==7) + { + if (req->apid[0]!='\0') + { + if (req->ctid[0]!='\0') + { + /* One application, one context */ + // context = dlt_daemon_context_find(daemon, req->apid, req->ctid, verbose); + if (context) + { + resp.datasize+=sizeof(uint16_t) /* len_context_description */; + if (context->context_description!=0) + { + resp.datasize+=strlen(context->context_description); /* context_description */ + } + } + } + else + { + /* One application, all contexts */ + if ((daemon->applications) && (application)) + { + /* Calculate start offset within contexts[] */ + offset_base=0; + for (i=0; i<(application-(daemon->applications)); i++) + { + offset_base+=daemon->applications[i].num_contexts; + } + + /* Iterate over all contexts belonging to this application */ + for (j=0;j<application->num_contexts;j++) + { + + context = &(daemon->contexts[offset_base+j]); + if (context) + { + resp.datasize+=sizeof(uint16_t) /* len_context_description */; + if (context->context_description!=0) + { + resp.datasize+=strlen(context->context_description); /* context_description */ + } + } + } + } + } + + /* Space for application description */ + if (application) + { + resp.datasize+=sizeof(uint16_t) /* len_app_description */; + if (application->application_description!=0) + { + resp.datasize+=strlen(application->application_description); /* app_description */ + } + } + } + else + { + /* All applications, all contexts */ + for (i=0;i<daemon->num_contexts;i++) + { + resp.datasize+=sizeof(uint16_t) /* len_context_description */; + if (daemon->contexts[i].context_description!=0) + { + resp.datasize+=strlen(daemon->contexts[i].context_description); /* context_description */ + } + } + + for (i=0;i<daemon->num_applications;i++) + { + resp.datasize+=sizeof(uint16_t) /* len_app_description */; + if (daemon->applications[i].application_description!=0) + { + resp.datasize+=strlen(daemon->applications[i].application_description); /* app_description */ + } + } + } + } + + if (verbose) + { + sprintf(str,"Allocate %d bytes for response msg databuffer\n", resp.datasize); + dlt_log(LOG_INFO, str); + } + + /* Allocate buffer for response message */ + resp.databuffer = (uint8_t *) malloc(resp.datasize); + if (resp.databuffer==0) + { + dlt_daemon_control_service_response(sock, daemon, DLT_SERVICE_ID_GET_LOG_INFO, DLT_SERVICE_RESPONSE_ERROR, verbose); + return; + } + memset(resp.databuffer,0,resp.datasize); + /* Preparation finished */ + + /* Prepare response */ + sid = DLT_SERVICE_ID_GET_LOG_INFO; + memcpy(resp.databuffer,&sid,sizeof(uint32_t)); + offset+=sizeof(uint32_t); + + value = (((num_applications!=0)&&(num_contexts!=0))?req->options:8); /* 8 = no matching context found */ + + memcpy(resp.databuffer+offset,&value,sizeof(int8_t)); + offset+=sizeof(int8_t); + + count_app_ids = num_applications; + + if (count_app_ids!=0) + { + memcpy(resp.databuffer+offset,&count_app_ids,sizeof(uint16_t)); + offset+=sizeof(uint16_t); + +#if (DLT_DEBUG_GETLOGINFO==1) + sprintf(str,"#apid: %d \n", count_app_ids); + dlt_log(LOG_DEBUG, str); +#endif + + for (i=0;i<count_app_ids;i++) + { + if (req->apid[0]!='\0') + { + apid = req->apid; + } + else + { + if (daemon->applications) + { + apid = daemon->applications[i].apid; + } + else + { + /* This should never occur! */ + apid=0; + } + } + + application = dlt_daemon_application_find(daemon, apid, verbose); + + if (application) + { + /* Calculate start offset within contexts[] */ + offset_base=0; + for (j=0; j<(application-(daemon->applications)); j++) + { + offset_base+=daemon->applications[j].num_contexts; + } + + dlt_set_id((char*)(resp.databuffer+offset),apid); + offset+=sizeof(ID4); + +#if (DLT_DEBUG_GETLOGINFO==1) + dlt_print_id(buf, apid); + sprintf(str,"apid: %s\n",buf); + dlt_log(LOG_DEBUG, str); +#endif + + if (req->apid[0]!='\0') + { + count_con_ids = num_contexts; + } + else + { + count_con_ids = application->num_contexts; + } + + memcpy(resp.databuffer+offset,&count_con_ids,sizeof(uint16_t)); + offset+=sizeof(uint16_t); + +#if (DLT_DEBUG_GETLOGINFO==1) + sprintf(str,"#ctid: %d \n", count_con_ids); + dlt_log(LOG_DEBUG, str); +#endif + + for (j=0;j<count_con_ids;j++) + { +#if (DLT_DEBUG_GETLOGINFO==1) + sprintf(str,"j: %d \n",j); + dlt_log(LOG_DEBUG, str); +#endif + if (!((count_con_ids==1) && (req->apid[0]!='\0') && (req->ctid[0]!='\0'))) + { + context = &(daemon->contexts[offset_base+j]); + } + /* else: context was already searched and found + (one application (found) with one context (found))*/ + + if ((context) && + ((req->ctid[0]=='\0') || + ((req->ctid[0]!='\0') && (memcmp(context->ctid,req->ctid,DLT_ID_SIZE)==0))) + ) + { + dlt_set_id((char*)(resp.databuffer+offset),context->ctid); + offset+=sizeof(ID4); + +#if (DLT_DEBUG_GETLOGINFO==1) + dlt_print_id(buf, context->ctid); + sprintf(str,"ctid: %s \n",buf); + dlt_log(LOG_DEBUG, str); +#endif + + /* Mode 4, 6, 7 */ + if ((req->options==4) || (req->options==6) || (req->options==7)) + { + ll=context->log_level; + memcpy(resp.databuffer+offset,&ll,sizeof(int8_t)); + offset+=sizeof(int8_t); + } + + /* Mode 5, 6, 7 */ + if ((req->options==5) || (req->options==6) || (req->options==7)) + { + ts=context->trace_status; + memcpy(resp.databuffer+offset,&ts,sizeof(int8_t)); + offset+=sizeof(int8_t); + } + + /* Mode 7 */ + if (req->options==7) + { + if (context->context_description) + { + len = strlen(context->context_description); + memcpy(resp.databuffer+offset,&len,sizeof(uint16_t)); + offset+=sizeof(uint16_t); + memcpy(resp.databuffer+offset,context->context_description,strlen(context->context_description)); + offset+=strlen(context->context_description); + } + else + { + len = 0; + memcpy(resp.databuffer+offset,&len,sizeof(uint16_t)); + offset+=sizeof(uint16_t); + } + } + +#if (DLT_DEBUG_GETLOGINFO==1) + sprintf(str,"ll=%d ts=%d \n",(int32_t)ll,(int32_t)ts); + dlt_log(LOG_DEBUG, str); +#endif + } + +#if (DLT_DEBUG_GETLOGINFO==1) + dlt_log(LOG_DEBUG,"\n"); +#endif + } + + /* Mode 7 */ + if (req->options==7) + { + if (application->application_description) + { + len = strlen(application->application_description); + memcpy(resp.databuffer+offset,&len,sizeof(uint16_t)); + offset+=sizeof(uint16_t); + memcpy(resp.databuffer+offset,application->application_description,strlen(application->application_description)); + offset+=strlen(application->application_description); + } + else + { + len = 0; + memcpy(resp.databuffer+offset,&len,sizeof(uint16_t)); + offset+=sizeof(uint16_t); + } + } + } /* if (application) */ + } /* for (i=0;i<count_app_ids;i++) */ + } /* if (count_app_ids!=0) */ + + dlt_set_id((char*)(resp.databuffer+offset),DLT_DAEMON_REMO_STRING); + + /* send message */ + dlt_daemon_control_send_control_message(sock,daemon,&resp,"","", verbose); + + /* free message */ + dlt_message_free(&resp,0); +} + +void dlt_daemon_control_message_buffer_overflow(int sock, DltDaemon *daemon, int verbose) +{ + DltMessage msg; + DltServiceMessageBufferOverflowResponse *resp; + + PRINT_FUNCTION_VERBOSE(verbose); + + if (daemon==0) + { + return; + } + + /* initialise new message */ + if (dlt_message_init(&msg,0)==-1) + { + dlt_daemon_control_service_response(sock, daemon, DLT_SERVICE_ID_MESSAGE_BUFFER_OVERFLOW, DLT_SERVICE_RESPONSE_ERROR, verbose); + return; + } + + /* prepare payload of data */ + msg.datasize = sizeof(DltServiceMessageBufferOverflowResponse); + if (msg.databuffer) + { + free(msg.databuffer); + } + msg.databuffer = (uint8_t *) malloc(msg.datasize); + if (msg.databuffer==0) + { + if (sock!=DLT_DAEMON_STORE_TO_BUFFER) + { + dlt_daemon_control_service_response(sock, daemon, DLT_SERVICE_ID_MESSAGE_BUFFER_OVERFLOW, DLT_SERVICE_RESPONSE_ERROR, verbose); + } + return; + } + + resp = (DltServiceMessageBufferOverflowResponse*) msg.databuffer; + resp->service_id = DLT_SERVICE_ID_MESSAGE_BUFFER_OVERFLOW; + resp->status = DLT_SERVICE_RESPONSE_OK; + resp->overflow = daemon->message_buffer_overflow; + + /* send message */ + dlt_daemon_control_send_control_message(sock,daemon,&msg,"","", verbose); + + /* free message */ + dlt_message_free(&msg,0); +} + +void dlt_daemon_control_service_response( int sock, DltDaemon *daemon, uint32_t service_id, int8_t status , int verbose) +{ + DltMessage msg; + DltServiceResponse *resp; + + PRINT_FUNCTION_VERBOSE(verbose); + + if (daemon==0) + { + return; + } + + /* initialise new message */ + if (dlt_message_init(&msg,0)==-1) + { + return; + } + + /* prepare payload of data */ + msg.datasize = sizeof(DltServiceResponse); + if (msg.databuffer) + { + free(msg.databuffer); + } + msg.databuffer = (uint8_t *) malloc(msg.datasize); + if (msg.databuffer==0) + { + return; + } + + resp = (DltServiceResponse*) msg.databuffer; + resp->service_id = service_id; + resp->status = status; + + /* send message */ + dlt_daemon_control_send_control_message(sock,daemon,&msg,"","", verbose); + + /* free message */ + dlt_message_free(&msg,0); +} + +void dlt_daemon_control_send_control_message( int sock, DltDaemon *daemon, DltMessage *msg, char* appid, char* ctid, int verbose) +{ + ssize_t ret; + int32_t len; + + PRINT_FUNCTION_VERBOSE(verbose); + + if ((daemon==0) || (msg==0) || (appid==0) || (ctid==0)) + { + return; + } + + /* prepare storage header */ + msg->storageheader = (DltStorageHeader*)msg->headerbuffer; + + if (dlt_set_storageheader(msg->storageheader,daemon->ecuid)==-1) + { + return; + } + + /* prepare standard header */ + msg->standardheader = (DltStandardHeader*)(msg->headerbuffer + sizeof(DltStorageHeader)); + msg->standardheader->htyp = DLT_HTYP_WEID | DLT_HTYP_WTMS | DLT_HTYP_UEH | DLT_HTYP_PROTOCOL_VERSION1 ; + +#if (BYTE_ORDER==BIG_ENDIAN) + msg->standardheader->htyp = ( msg->standardheader->htyp | DLT_HTYP_MSBF); +#endif + + msg->standardheader->mcnt = 0; + + /* Set header extra parameters */ + dlt_set_id(msg->headerextra.ecu,daemon->ecuid); + + //msg->headerextra.seid = 0; + + msg->headerextra.tmsp = dlt_uptime(); + + dlt_message_set_extraparameters(msg, verbose); + + /* prepare extended header */ + msg->extendedheader = (DltExtendedHeader*)(msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg->standardheader->htyp)); + msg->extendedheader->msin = DLT_MSIN_CONTROL_RESPONSE; + + msg->extendedheader->noar = 1; /* number of arguments */ + if (strcmp(appid,"")==0) + { + dlt_set_id(msg->extendedheader->apid,DLT_DAEMON_CTRL_APID); /* application id */ + } + else + { + dlt_set_id(msg->extendedheader->apid, appid); + } + if (strcmp(ctid,"")==0) + { + dlt_set_id(msg->extendedheader->ctid,DLT_DAEMON_CTRL_CTID); /* context id */ + } + else + { + dlt_set_id(msg->extendedheader->ctid, ctid); + } + + /* prepare length information */ + msg->headersize = sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + sizeof(DltExtendedHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg->standardheader->htyp); + + len=msg->headersize - sizeof(DltStorageHeader) + msg->datasize; + if (len>UINT16_MAX) + { + dlt_log(LOG_CRIT,"Huge control message discarded!\n"); + return; + } + + msg->standardheader->len = DLT_HTOBE_16(((uint16_t)len)); + + if (sock!=DLT_DAEMON_STORE_TO_BUFFER) + { + /* Send message */ + if (isatty(sock)) + { + DLT_DAEMON_SEM_LOCK(); + + /* Optional: Send serial header, if requested */ + if (daemon->sendserialheader) + { + ret=write(sock,dltSerialHeader,sizeof(dltSerialHeader)); + } + + /* Send data */ + ret=write(sock, msg->headerbuffer+sizeof(DltStorageHeader),msg->headersize-sizeof(DltStorageHeader)); + ret=write(sock, msg->databuffer,msg->datasize); + + DLT_DAEMON_SEM_FREE(); + } + else + { + DLT_DAEMON_SEM_LOCK(); + + /* Optional: Send serial header, if requested */ + if (daemon->sendserialheader) + { + send(sock, dltSerialHeader,sizeof(dltSerialHeader),0); + } + + /* Send data */ + send(sock, msg->headerbuffer+sizeof(DltStorageHeader),msg->headersize-sizeof(DltStorageHeader),0); + send(sock, msg->databuffer,msg->datasize,0); + + DLT_DAEMON_SEM_FREE(); + } + } + 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; + } + } +} + +void dlt_daemon_control_reset_to_factory_default(DltDaemon *daemon,const char *filename, const char *filename1, int verbose) +{ + FILE *fd; + + PRINT_FUNCTION_VERBOSE(verbose); + + if ((daemon==0) || (filename==0) || (filename1==0) || (filename[0]=='\0') || (filename1[0]=='\0')) + { + return; + } + + /* Check for runtime cfg file and delete it, if available */ + fd=fopen(filename, "r"); + + if (fd!=0) + { + /* Close and delete file */ + fclose(fd); + unlink(filename); + } + + fd=fopen(filename1, "r"); + + if (fd!=0) + { + /* Close and delete file */ + fclose(fd); + unlink(filename1); + } + + daemon->default_log_level = DLT_DAEMON_INITIAL_LOG_LEVEL ; + daemon->default_trace_status = DLT_DAEMON_INITIAL_TRACE_STATUS ; + + daemon->message_buffer_overflow = DLT_MESSAGE_BUFFER_NO_OVERFLOW; + + /* Reset all other things (log level, trace status, etc. + to default values */ + + /* Inform user libraries about changed default log level/trace status */ + dlt_daemon_user_send_default_update(daemon, verbose); +} + +void dlt_daemon_user_send_default_update(DltDaemon *daemon, int verbose) +{ + int32_t count; + DltDaemonContext *context; + + PRINT_FUNCTION_VERBOSE(verbose); + + if (daemon==0) + { + return; + } + + for (count=0;count<daemon->num_contexts; count ++) + { + context = &(daemon->contexts[count]); + + if (context) + { + if ((context->log_level == DLT_LOG_DEFAULT) || + (context->trace_status == DLT_TRACE_STATUS_DEFAULT)) + { + if (context->user_handle!=0) + { + if (dlt_daemon_user_send_log_level(daemon, context, verbose)==-1) + { + return; + } + } + } + } + } +} + +void dlt_daemon_control_message_time(int sock, DltDaemon *daemon, int verbose) +{ + DltMessage msg; + ssize_t ret; + int32_t len; + + PRINT_FUNCTION_VERBOSE(verbose); + + if (daemon==0) + { + return; + } + + if (sock==DLT_DAEMON_STORE_TO_BUFFER) + { + return; + } + + /* initialise new message */ + if (dlt_message_init(&msg,0)==-1) + { + return; + } + + /* prepare payload of data */ + msg.datasize = 0; + if (msg.databuffer) + { + free(msg.databuffer); + } + msg.databuffer = 0; + + /* send message */ + + /* prepare storage header */ + msg.storageheader = (DltStorageHeader*)msg.headerbuffer; + dlt_set_storageheader(msg.storageheader,daemon->ecuid); + + /* prepare standard header */ + msg.standardheader = (DltStandardHeader*)(msg.headerbuffer + sizeof(DltStorageHeader)); + msg.standardheader->htyp = DLT_HTYP_WEID | DLT_HTYP_WTMS | DLT_HTYP_UEH | DLT_HTYP_PROTOCOL_VERSION1 ; + +#if (BYTE_ORDER==BIG_ENDIAN) + msg.standardheader->htyp = ( msg.standardheader->htyp | DLT_HTYP_MSBF); +#endif + + msg.standardheader->mcnt = 0; + + /* Set header extra parameters */ + dlt_set_id(msg.headerextra.ecu,daemon->ecuid); + msg.headerextra.tmsp = dlt_uptime(); + + dlt_message_set_extraparameters(&msg, verbose); + + /* prepare extended header */ + msg.extendedheader = (DltExtendedHeader*)(msg.headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp)); + msg.extendedheader->msin = DLT_MSIN_CONTROL_TIME; + + msg.extendedheader->noar = 0; /* number of arguments */ + dlt_set_id(msg.extendedheader->apid,""); /* application id */ + dlt_set_id(msg.extendedheader->ctid,""); /* context id */ + + /* prepare length information */ + msg.headersize = sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + sizeof(DltExtendedHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp); + + len=msg.headersize - sizeof(DltStorageHeader) + msg.datasize; + if (len>UINT16_MAX) + { + dlt_log(LOG_CRIT,"Huge control message discarded!\n"); + + /* free message */ + dlt_message_free(&msg,0); + + return; + } + + msg.standardheader->len = DLT_HTOBE_16(((uint16_t)len)); + + /* Send message */ + if (isatty(sock)) + { + DLT_DAEMON_SEM_LOCK(); + + /* Optional: Send serial header, if requested */ + if (daemon->sendserialheader) + { + ret=write(sock,dltSerialHeader,sizeof(dltSerialHeader)); + } + + /* Send data */ + ret=write(sock, msg.headerbuffer+sizeof(DltStorageHeader),msg.headersize-sizeof(DltStorageHeader)); + ret=write(sock, msg.databuffer,msg.datasize); + + DLT_DAEMON_SEM_FREE(); + } + else + { + DLT_DAEMON_SEM_LOCK(); + + /* Optional: Send serial header, if requested */ + if (daemon->sendserialheader) + { + send(sock, dltSerialHeader,sizeof(dltSerialHeader),0); + } + + /* Send data */ + send(sock, msg.headerbuffer+sizeof(DltStorageHeader),msg.headersize-sizeof(DltStorageHeader),0); + send(sock, msg.databuffer,msg.datasize,0); + + DLT_DAEMON_SEM_FREE(); + } + + /* free message */ + dlt_message_free(&msg,0); +} + diff --git a/src/daemon/dlt_daemon_common.h b/src/daemon/dlt_daemon_common.h new file mode 100755 index 0000000..fa0fe53 --- /dev/null +++ b/src/daemon/dlt_daemon_common.h @@ -0,0 +1,420 @@ +/*
+ * Dlt- Diagnostic Log and Trace daemon
+ * @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_daemon_common.h **
+** **
+** TARGET : linux **
+** **
+** PROJECT : DLT **
+** **
+** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de **
+** Markus Klein **
+** **
+** PURPOSE : **
+** **
+** REMARKS : **
+** **
+** PLATFORM DEPENDANT [yes/no]: yes **
+** **
+** TO BE CHANGED BY USER [yes/no]: no **
+** **
+*******************************************************************************/
+
+/*******************************************************************************
+** Author Identity **
+********************************************************************************
+** **
+** Initials Name Company **
+** -------- ------------------------- ---------------------------------- **
+** aw Alexander Wenzel BMW **
+** mk Markus Klein Fraunhofer ESK **
+*******************************************************************************/
+
+/*******************************************************************************
+** Revision Control History **
+*******************************************************************************/
+
+/*
+ * $LastChangedRevision: 1670 $
+ * $LastChangedDate: 2011-04-08 15:12:06 +0200 (Fr, 08. Apr 2011) $
+ * $LastChangedBy$
+ Initials Date Comment
+ aw 15.02.2010 initial
+ */
+
+#ifndef DLT_DAEMON_COMMON_H
+#define DLT_DAEMON_COMMON_H
+
+/**
+ \defgroup daemonapi DLT Daemon API
+ \addtogroup daemonapi
+ \{
+*/
+
+#include <semaphore.h>
+#include "dlt_common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define DLT_DAEMON_RINGBUFFER_SIZE 100000 /**< Ring buffer size for storing log messages while no client is connected */
+
+#define DLT_DAEMON_STORE_TO_BUFFER -2 /**< Constant value to identify the command "store to buffer" */
+
+/* Use a semaphore or mutex from your OS to prevent concurrent access to the DLT buffer. */
+
+#define DLT_DAEMON_SEM_LOCK() { sem_wait(&dlt_daemon_mutex); }
+#define DLT_DAEMON_SEM_FREE() { sem_post(&dlt_daemon_mutex); }
+extern sem_t dlt_daemon_mutex;
+
+
+/**
+ * The parameters of a daemon application.
+ */
+typedef struct
+{
+ char apid[DLT_ID_SIZE]; /**< application id */
+ pid_t pid; /**< process id of user application */
+ int user_handle; /**< connection handle for connection to user application */
+ char *application_description; /**< context description */
+ int num_contexts; /**< number of contexts for this application */
+} DltDaemonApplication;
+
+/**
+ * The parameters of a daemon context.
+ */
+typedef struct
+{
+ char apid[DLT_ID_SIZE]; /**< application id */
+ char ctid[DLT_ID_SIZE]; /**< context id */
+ int8_t log_level; /**< the current log level of the context */
+ int8_t trace_status; /**< the current trace status of the context */
+ int log_level_pos; /**< offset of context in context field on user application */
+ int user_handle; /**< connection handle for connection to user application */
+ char *context_description; /**< context description */
+} DltDaemonContext;
+
+/**
+ * The parameters of a daemon.
+ */
+typedef struct
+{
+ int num_contexts; /**< Total number of all contexts in all applications */
+ DltDaemonContext *contexts; /**< Pointer to contexts */
+ int num_applications; /**< Number of available application */
+ DltDaemonApplication *applications; /**< Pointer to applications */
+ int8_t default_log_level; /**< Default log level (of daemon) */
+ int8_t default_trace_status; /**< Default trace status (of daemon) */
+ int message_buffer_overflow; /**< Set to one, if buffer overflow has occured, zero otherwise */
+ int runtime_context_cfg_loaded; /**< Set to one, if runtime context configuration has been loaded, zero otherwise */
+ 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 */
+} DltDaemon;
+
+/**
+ * Initialise the dlt daemon structure
+ * This function must be called before using further dlt daemon structure
+ * @param daemon pointer to dlt daemon structure
+ * @param verbose if set to true verbose information is printed out.
+ * @return negative value if there was an error
+ */
+int dlt_daemon_init(DltDaemon *daemon,int verbose);
+/**
+ * De-Initialise the dlt daemon structure
+ * @param daemon pointer to dlt daemon structure
+ * @param verbose if set to true verbose information is printed out.
+ * @return negative value if there was an error
+ */
+int dlt_daemon_free(DltDaemon *daemon,int verbose);
+
+/**
+ * Add (new) application to internal application management
+ * @param daemon pointer to dlt daemon structure
+ * @param apid pointer to application id
+ * @param pid process id of user application
+ * @param description description of application
+ * @param verbose if set to true verbose information is printed out.
+ * @return Pointer to added context, null pointer on error
+ */
+DltDaemonApplication* dlt_daemon_application_add(DltDaemon *daemon,char *apid,pid_t pid,char *description, int verbose);
+/**
+ * Delete application from internal application management
+ * @param daemon pointer to dlt daemon structure
+ * @param application pointer to application to be deleted
+ * @param verbose if set to true verbose information is printed out.
+ * @return negative value if there was an error
+ */
+int dlt_daemon_application_del(DltDaemon *daemon, DltDaemonApplication *application, int verbose);
+/**
+ * Find application with specific application id
+ * @param daemon pointer to dlt daemon structure
+ * @param apid pointer to application id
+ * @param verbose if set to true verbose information is printed out.
+ * @return Pointer to application, null pointer on error or not found
+ */
+DltDaemonApplication* dlt_daemon_application_find(DltDaemon *daemon,char *apid,int verbose);
+/**
+ * Load applications from file to internal context management
+ * @param daemon pointer to dlt daemon structure
+ * @param filename name of file to be used for loading
+ * @param verbose if set to true verbose information is printed out.
+ * @return negative value if there was an error
+ */
+int dlt_daemon_applications_load(DltDaemon *daemon,const char *filename, int verbose);
+/**
+ * Save applications from internal context management to file
+ * @param daemon pointer to dlt daemon structure
+ * @param filename name of file to be used for saving
+ * @param verbose if set to true verbose information is printed out.
+ * @return negative value if there was an error
+ */
+int dlt_daemon_applications_save(DltDaemon *daemon,const char *filename, int verbose);
+/**
+ * Clear all applications in internal application management
+ * @param daemon pointer to dlt daemon structure
+ * @param verbose if set to true verbose information is printed out.
+ * @return negative value if there was an error
+ */
+int dlt_daemon_applications_clear(DltDaemon *daemon,int verbose);
+
+/**
+ * Add (new) context to internal context management
+ * @param daemon pointer to dlt daemon structure
+ * @param apid pointer to application id
+ * @param ctid pointer to context id
+ * @param log_level log level of context
+ * @param trace_status trace status of context
+ * @param log_level_pos offset of context in context field on user application
+ * @param user_handle connection handle for connection to user application
+ * @param description description of context
+ * @param verbose if set to true verbose information is printed out.
+ * @return Pointer to added context, null pointer on error
+ */
+DltDaemonContext* dlt_daemon_context_add(DltDaemon *daemon,char *apid,char *ctid,int8_t log_level,int8_t trace_status,int log_level_pos, int user_handle,char *description,int verbose);
+/**
+ * Delete context from internal context management
+ * @param daemon pointer to dlt daemon structure
+ * @param context pointer to context to be deleted
+ * @param verbose if set to true verbose information is printed out.
+ * @return negative value if there was an error
+ */
+int dlt_daemon_context_del(DltDaemon *daemon, DltDaemonContext* context, int verbose);
+/**
+ * Find context with specific application id and context id
+ * @param daemon pointer to dlt daemon structure
+ * @param apid pointer to application id
+ * @param ctid pointer to context id
+ * @param verbose if set to true verbose information is printed out.
+ * @return Pointer to context, null pointer on error or not found
+ */
+DltDaemonContext* dlt_daemon_context_find(DltDaemon *daemon,char *apid,char *ctid,int verbose);
+/**
+ * Clear all contexts in internal context management
+ * @param daemon pointer to dlt daemon structure
+ * @param verbose if set to true verbose information is printed out.
+ * @return negative value if there was an error
+ */
+int dlt_daemon_contexts_clear(DltDaemon *daemon,int verbose);
+/**
+ * Load contexts from file to internal context management
+ * @param daemon pointer to dlt daemon structure
+ * @param filename name of file to be used for loading
+ * @param verbose if set to true verbose information is printed out.
+ * @return negative value if there was an error
+ */
+int dlt_daemon_contexts_load(DltDaemon *daemon,const char *filename, int verbose);
+/**
+ * Save contexts from internal context management to file
+ * @param daemon pointer to dlt daemon structure
+ * @param filename name of file to be used for saving
+ * @param verbose if set to true verbose information is printed out.
+ * @return negative value if there was an error
+ */
+int dlt_daemon_contexts_save(DltDaemon *daemon,const char *filename, int verbose);
+
+/**
+ * Send user message DLT_USER_MESSAGE_LOG_LEVEL to user application
+ * @param daemon pointer to dlt daemon structure
+ * @param context pointer to context for response
+ * @param verbose if set to true verbose information is printed out.
+ * @return negative value if there was an error
+ */
+int dlt_daemon_user_send_log_level(DltDaemon *daemon,DltDaemonContext *context, int verbose);
+/**
+ * Send user messages to all user applications using default context, or trace status
+ * to update those values
+ * @param daemon pointer to dlt daemon structure
+ * @param verbose if set to true verbose information is printed out.
+ */
+void dlt_daemon_user_send_default_update(DltDaemon *daemon, int verbose);
+
+/**
+ * Process received control message from dlt client
+ * @param sock connection handle used for sending response
+ * @param daemon pointer to dlt daemon structure
+ * @param msg pointer to received control message
+ * @param verbose if set to true verbose information is printed out.
+ */
+int dlt_daemon_control_process_control(int sock, DltDaemon *daemon, DltMessage *msg, int verbose);
+/**
+ * Generate response to control message from dlt client
+ * @param sock connection handle used for sending response
+ * @param daemon pointer to dlt daemon structure
+ * @param service_id service id of control message
+ * @param status status of response (e.g. ok, not supported, error)
+ * @param verbose if set to true verbose information is printed out.
+ */
+void dlt_daemon_control_service_response(int sock, DltDaemon *daemon, uint32_t service_id, int8_t status, int verbose);
+/**
+ * Send out response message to dlt client
+ * @param sock connection handle used for sending response
+ * @param daemon pointer to dlt daemon structure
+ * @param msg pointer to response message
+ * @param appid pointer to application id to be used in response message
+ * @param contid pointer to context id to be used in response message
+ * @param verbose if set to true verbose information is printed out.
+ */
+void dlt_daemon_control_send_control_message(int sock, DltDaemon *daemon, DltMessage *msg, char* appid, char* contid, int verbose);
+
+/**
+ * Process and generate response to received sw injection control message
+ * @param sock connection handle used for sending response
+ * @param daemon pointer to dlt daemon structure
+ * @param msg pointer to received sw injection control message
+ * @param verbose if set to true verbose information is printed out.
+ */
+void dlt_daemon_control_callsw_cinjection(int sock, DltDaemon *daemon, DltMessage *msg, int verbose);
+/**
+ * Process and generate response to received set log level control message
+ * @param sock connection handle used for sending response
+ * @param daemon pointer to dlt daemon structure
+ * @param msg pointer to received control message
+ * @param verbose if set to true verbose information is printed out.
+ */
+void dlt_daemon_control_set_log_level(int sock, DltDaemon *daemon, DltMessage *msg, int verbose);
+/**
+ * Process and generate response to received set trace status control message
+ * @param sock connection handle used for sending response
+ * @param daemon pointer to dlt daemon structure
+ * @param msg pointer to received control message
+ * @param verbose if set to true verbose information is printed out.
+ */
+void dlt_daemon_control_set_trace_status(int sock, DltDaemon *daemon, DltMessage *msg, int verbose);
+/**
+ * Process and generate response to received set default log level control message
+ * @param sock connection handle used for sending response
+ * @param daemon pointer to dlt daemon structure
+ * @param msg pointer to received control message
+ * @param verbose if set to true verbose information is printed out.
+ */
+void dlt_daemon_control_set_default_log_level(int sock, DltDaemon *daemon, DltMessage *msg, int verbose);
+/**
+ * Process and generate response to received set default trace status control message
+ * @param sock connection handle used for sending response
+ * @param daemon pointer to dlt daemon structure
+ * @param msg pointer to received control message
+ * @param verbose if set to true verbose information is printed out.
+ */
+void dlt_daemon_control_set_default_trace_status(int sock, DltDaemon *daemon, DltMessage *msg, int verbose);
+/**
+ * Process and generate response to set timing packets control message
+ * @param sock connection handle used for sending response
+ * @param daemon pointer to dlt daemon structure
+ * @param msg pointer to received control message
+ * @param verbose if set to true verbose information is printed out.
+ */
+void dlt_daemon_control_set_timing_packets(int sock, DltDaemon *daemon, DltMessage *msg, int verbose);
+/**
+ * Process and generate response to received get software version control message
+ * @param sock connection handle used for sending response
+ * @param daemon pointer to dlt daemon structure
+ * @param verbose if set to true verbose information is printed out.
+ */
+void dlt_daemon_control_get_software_version(int sock, DltDaemon *daemon, int verbose);
+/**
+ * Process and generate response to received get default log level control message
+ * @param sock connection handle used for sending response
+ * @param daemon pointer to dlt daemon structure
+ * @param verbose if set to true verbose information is printed out.
+ */
+void dlt_daemon_control_get_default_log_level(int sock, DltDaemon *daemon, int verbose);
+/**
+ * Process and generate response to received get log info control message
+ * @param sock connection handle used for sending response
+ * @param daemon pointer to dlt daemon structure
+ * @param msg pointer to received control message
+ * @param verbose if set to true verbose information is printed out.
+ */
+void dlt_daemon_control_get_log_info(int sock, DltDaemon *daemon, DltMessage *msg, int verbose);
+/**
+ * Process and generate response to message buffer overflow control message
+ * @param sock connection handle used for sending response
+ * @param daemon pointer to dlt daemon structure
+ * @param verbose if set to true verbose information is printed out.
+ */
+void dlt_daemon_control_message_buffer_overflow(int sock, DltDaemon *daemon, int verbose);
+/**
+ * Process reset to factory default control message
+ * @param daemon pointer to dlt daemon structure
+ * @param filename name of file containing the runtime defaults for applications
+ * @param filename1 name of file containing the runtime defaults for contexts
+ * @param verbose if set to true verbose information is printed out.
+ */
+void dlt_daemon_control_reset_to_factory_default(DltDaemon *daemon,const char *filename, const char *filename1, int verbose);
+/**
+ * Send time control message
+ * @param sock connection handle used for sending response
+ * @param daemon pointer to dlt daemon structure
+ * @param verbose if set to true verbose information is printed out.
+ */
+void dlt_daemon_control_message_time(int sock, DltDaemon *daemon, int verbose);
+
+#ifdef __cplusplus
+}
+#endif
+
+/**
+ \}
+*/
+
+#endif /* DLT_DAEMON_COMMON_H */
diff --git a/src/daemon/dlt_daemon_common_cfg.h b/src/daemon/dlt_daemon_common_cfg.h new file mode 100755 index 0000000..57db30e --- /dev/null +++ b/src/daemon/dlt_daemon_common_cfg.h @@ -0,0 +1,129 @@ +/*
+ * Dlt- Diagnostic Log and Trace daemon
+ * @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_daemon_common_cfg.h **
+** **
+** TARGET : linux **
+** **
+** PROJECT : DLT **
+** **
+** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de **
+** Markus Klein **
+** **
+** PURPOSE : **
+** **
+** REMARKS : **
+** **
+** PLATFORM DEPENDANT [yes/no]: yes **
+** **
+** TO BE CHANGED BY USER [yes/no]: no **
+** **
+*******************************************************************************/
+
+/*******************************************************************************
+** Author Identity **
+********************************************************************************
+** **
+** Initials Name Company **
+** -------- ------------------------- ---------------------------------- **
+** aw Alexander Wenzel BMW **
+** mk Markus Klein Fraunhofer ESK **
+*******************************************************************************/
+
+/*******************************************************************************
+** Author Identity **
+********************************************************************************
+** **
+** Initials Name Company **
+** -------- ------------------------- ---------------------------------- **
+** aw Alexander Wenzel BMW **
+** mk Markus Klein Fraunhofer ESK **
+*******************************************************************************/
+
+#ifndef DLT_DAEMON_COMMON_CFG_H
+#define DLT_DAEMON_COMMON_CFG_H
+
+/*************/
+/* Changable */
+/*************/
+
+/* Path and filename for runtime configuration (applications) */
+#define DLT_RUNTIME_APPLICATION_CFG "/tmp/dlt-runtime-application.cfg"
+/* Path and filename for runtime configuration (contexts) */
+#define DLT_RUNTIME_CONTEXT_CFG "/tmp/dlt-runtime-context.cfg"
+
+/* Size of text buffer */
+#define DLT_DAEMON_TEXTBUFSIZE 255
+
+/* Initial log level */
+#define DLT_DAEMON_INITIAL_LOG_LEVEL DLT_LOG_INFO
+/* Initial trace status */
+#define DLT_DAEMON_INITIAL_TRACE_STATUS DLT_TRACE_STATUS_OFF
+
+/* Application ID used when the dlt daemon creates a control message */
+#define DLT_DAEMON_CTRL_APID "DA1"
+/* Context ID used when the dlt daemon creates a control message */
+#define DLT_DAEMON_CTRL_CTID "DC1"
+
+/* Number of entries to be allocated at one in application table,
+ when no more entries are available */
+#define DLT_DAEMON_APPL_ALLOC_SIZE 500
+/* Number of entries to be allocated at one in context table,
+ when no more entries are available */
+#define DLT_DAEMON_CONTEXT_ALLOC_SIZE 1000
+
+/* Debug get log info function,
+ set to 1 to enable, 0 to disable debugging */
+#define DLT_DEBUG_GETLOGINFO 0
+
+/************************/
+/* Don't change please! */
+/************************/
+
+/* Minimum ID for an injection message */
+#define DLT_DAEMON_INJECTION_MIN 0xFFF
+/* Maximum ID for an injection message */
+#define DLT_DAEMON_INJECTION_MAX 0xFFFFFFFF
+
+/* Remote interface identifier */
+#define DLT_DAEMON_REMO_STRING "remo"
+
+#endif /* DLT_DAEMON_COMMON_CFG_H */
+
diff --git a/src/examples/CMakeLists.txt b/src/examples/CMakeLists.txt new file mode 100755 index 0000000..cb6fbb2 --- /dev/null +++ b/src/examples/CMakeLists.txt @@ -0,0 +1,51 @@ +####### +# Dlt - Diagnostic Log and Trace +# @licence make 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@ +######## + +set(dlt_example_user_SRCS dlt-example-user) +add_executable(dlt-example-user ${dlt_example_user_SRCS}) +target_link_libraries(dlt-example-user dlt) +set_target_properties(dlt-example-user PROPERTIES LINKER_LANGUAGE C) + +set(dlt_example_user_func_SRCS dlt-example-user-func) +add_executable(dlt-example-user-func ${dlt_example_user_func_SRCS}) +target_link_libraries(dlt-example-user-func dlt) +set_target_properties(dlt-example-user-func PROPERTIES LINKER_LANGUAGE C) + +install(TARGETS dlt-example-user dlt-example-user-func + RUNTIME DESTINATION bin + COMPONENT base) + diff --git a/src/examples/dlt-example-non-verbose-1.xml b/src/examples/dlt-example-non-verbose-1.xml new file mode 100755 index 0000000..7baae8c --- /dev/null +++ b/src/examples/dlt-example-non-verbose-1.xml @@ -0,0 +1,499 @@ +<?xml version="1.0"?>
+<!-- -->
+<!-- DLT example for DLT non-verbose mode -->
+<!-- -->
+<!-- Author: Jens Levihn, -->
+<!-- PEIKER acustic GmbH & Co. KG, Max-Planck-Str. 32, 61381 Friedrichsdorf -->
+<!-- -->
+<!-- -->
+<fx:FIBEX xmlns:fx="http://www.asam.net/xml/fbx" xmlns:ho="http://www.asam.net/xml" xmlns:can="http://www.asam.net/xml/fbx/can" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.asam.net/xml/fbx xml_schema\fibex.xsd http://www.asam.net/xml/fbx/can xml_schema\fibex4can.xsd" VERSION="3.1.0">
+ <fx:PROJECT ID="projectTCB">
+ <ho:SHORT-NAME>projectTCB</ho:SHORT-NAME>
+ </fx:PROJECT>
+ <fx:ELEMENTS>
+ <!--***************************** ECU ***************************-->
+ <fx:ECUS>
+ <fx:ECU ID="TCB">
+ <ho:SHORT-NAME>TCB</ho:SHORT-NAME>
+ <fx:MANUFACTURER-EXTENSION>
+ <SW_VERSION>001.004.062</SW_VERSION>
+ <APPLICATIONS>
+ <APPLICATION>
+ <APPLICATION_ID>APP1</APPLICATION_ID>
+ <APPLICATION_DESCRIPTION>Application 1</APPLICATION_DESCRIPTION>
+ <CONTEXTS>
+ <CONTEXT>
+ <CONTEXT_ID>CON1</CONTEXT_ID>
+ <CONTEXT_DESCRIPTION>Context 1</CONTEXT_DESCRIPTION>
+ </CONTEXT>
+ </CONTEXTS>
+ </APPLICATION>
+ <APPLICATION>
+ <APPLICATION_ID>TEST</APPLICATION_ID>
+ <APPLICATION_DESCRIPTION>Test Application</APPLICATION_DESCRIPTION>
+ <CONTEXTS>
+ <CONTEXT>
+ <CONTEXT_ID>CON1</CONTEXT_ID>
+ <CONTEXT_DESCRIPTION>Context 1</CONTEXT_DESCRIPTION>
+ </CONTEXT>
+ </CONTEXTS>
+ </APPLICATION>
+ <APPLICATION>
+ <APPLICATION_ID>LAT</APPLICATION_ID>
+ <APPLICATION_DESCRIPTION>Log And Trace</APPLICATION_DESCRIPTION>
+ <CONTEXTS>
+ <CONTEXT>
+ <CONTEXT_ID>NV</CONTEXT_ID>
+ <CONTEXT_DESCRIPTION>NV test</CONTEXT_DESCRIPTION>
+ </CONTEXT>
+ </CONTEXTS>
+ </APPLICATION>
+ </APPLICATIONS>
+ </fx:MANUFACTURER-EXTENSION>
+ </fx:ECU>
+ </fx:ECUS>
+ <!--*************************** PDUS ***************************-->
+ <fx:PDUS>
+ <!--=============== Message 10 ==================-->
+ <!--=============== 1. Parameter ==================-->
+ <fx:PDU ID="PDU_10_0">
+ <ho:SHORT-NAME>PDU_10_0</ho:SHORT-NAME>
+ <ho:DESC>DLT non verbose test message.</ho:DESC>
+ <fx:BYTE-LENGTH>0</fx:BYTE-LENGTH>
+ <fx:PDU-TYPE>OTHER</fx:PDU-TYPE>
+ </fx:PDU>
+ <!--=============== Message 11 ==================-->
+ <!--=============== 1. Parameter ==================-->
+ <fx:PDU ID="PDU_11_0">
+ <ho:SHORT-NAME>PDU_11_0</ho:SHORT-NAME>
+ <ho:DESC>Buffer near limit. Free size:</ho:DESC>
+ <fx:BYTE-LENGTH>0</fx:BYTE-LENGTH>
+ <fx:PDU-TYPE>OTHER</fx:PDU-TYPE>
+ </fx:PDU>
+ <!--=============== 2. Parameter ==================-->
+ <fx:PDU ID="PDU_11_1">
+ <ho:SHORT-NAME>PDU_11_1</ho:SHORT-NAME>
+ <fx:BYTE-LENGTH>2</fx:BYTE-LENGTH>
+ <fx:PDU-TYPE>OTHER</fx:PDU-TYPE>
+ <fx:SIGNAL-INSTANCES>
+ <fx:SIGNAL-INSTANCE ID="S_11_1">
+ <fx:SEQUENCE-NUMBER>0</fx:SEQUENCE-NUMBER>
+ <fx:SIGNAL-REF ID-REF="S_UINT16"/>
+ </fx:SIGNAL-INSTANCE>
+ </fx:SIGNAL-INSTANCES>
+ </fx:PDU>
+ <!--=============== Message 12 ==================-->
+ <!--=============== 1. Parameter ==================-->
+ <fx:PDU ID="PDU_12_0">
+ <ho:SHORT-NAME>PDU_12_0</ho:SHORT-NAME>
+ <ho:DESC>Buffer size exceeded.</ho:DESC>
+ <fx:BYTE-LENGTH>0</fx:BYTE-LENGTH>
+ <fx:PDU-TYPE>OTHER</fx:PDU-TYPE>
+ </fx:PDU>
+ <!--=============== 2. Parameter ==================-->
+ <fx:PDU ID="PDU_12_1">
+ <ho:SHORT-NAME>PDU_12_1</ho:SHORT-NAME>
+ <fx:BYTE-LENGTH>4</fx:BYTE-LENGTH>
+ <fx:PDU-TYPE>OTHER</fx:PDU-TYPE>
+ <fx:SIGNAL-INSTANCES>
+ <fx:SIGNAL-INSTANCE ID="S_12_1">
+ <fx:SEQUENCE-NUMBER>0</fx:SEQUENCE-NUMBER>
+ <fx:SIGNAL-REF ID-REF="S_UINT32"/>
+ </fx:SIGNAL-INSTANCE>
+ </fx:SIGNAL-INSTANCES>
+ </fx:PDU>
+ <!--=============== 3. Parameter ==================-->
+ <fx:PDU ID="PDU_12_2">
+ <ho:SHORT-NAME>PDU_12_2</ho:SHORT-NAME>
+ <fx:BYTE-LENGTH>4</fx:BYTE-LENGTH>
+ <fx:PDU-TYPE>OTHER</fx:PDU-TYPE>
+ <fx:SIGNAL-INSTANCES>
+ <fx:SIGNAL-INSTANCE ID="S_12_2">
+ <fx:SEQUENCE-NUMBER>0</fx:SEQUENCE-NUMBER>
+ <fx:SIGNAL-REF ID-REF="S_UINT32"/>
+ </fx:SIGNAL-INSTANCE>
+ </fx:SIGNAL-INSTANCES>
+ </fx:PDU>
+ <!--=============== 4. Parameter ==================-->
+ <fx:PDU ID="PDU_12_3">
+ <ho:SHORT-NAME>PDU_12_3</ho:SHORT-NAME>
+ <ho:DESC>Process terminated.</ho:DESC>
+ <fx:BYTE-LENGTH>0</fx:BYTE-LENGTH>
+ <fx:PDU-TYPE>OTHER</fx:PDU-TYPE>
+ </fx:PDU>
+ <!--=============== Message 13 ==================-->
+ <!--=============== 1. Parameter ==================-->
+ <fx:PDU ID="PDU_13_0">
+ <ho:SHORT-NAME>PDU_13_0</ho:SHORT-NAME>
+ <ho:DESC>Temperature measurement</ho:DESC>
+ <fx:BYTE-LENGTH>0</fx:BYTE-LENGTH>
+ <fx:PDU-TYPE>OTHER</fx:PDU-TYPE>
+ </fx:PDU>
+ <!--=============== 2. Parameter ==================-->
+ <fx:PDU ID="PDU_13_1">
+ <ho:SHORT-NAME>PDU_13_1</ho:SHORT-NAME>
+ <fx:BYTE-LENGTH>1</fx:BYTE-LENGTH>
+ <fx:PDU-TYPE>OTHER</fx:PDU-TYPE>
+ <fx:SIGNAL-INSTANCES>
+ <fx:SIGNAL-INSTANCE ID="S_13_1">
+ <fx:SEQUENCE-NUMBER>0</fx:SEQUENCE-NUMBER>
+ <fx:SIGNAL-REF ID-REF="S_UINT8"/>
+ <fx:MANUFACTURER-EXTENSION>
+ <VARI_NAME>measurement_point</VARI_NAME>
+ <VARI_UNIT></VARI_UNIT>
+ </fx:MANUFACTURER-EXTENSION>
+ </fx:SIGNAL-INSTANCE>
+ </fx:SIGNAL-INSTANCES>
+ </fx:PDU>
+ <!--=============== 3. Parameter ==================-->
+ <fx:PDU ID="PDU_13_2">
+ <ho:SHORT-NAME>PDU_13_2</ho:SHORT-NAME>
+ <fx:BYTE-LENGTH>4</fx:BYTE-LENGTH>
+ <fx:PDU-TYPE>OTHER</fx:PDU-TYPE>
+ <fx:SIGNAL-INSTANCES>
+ <fx:SIGNAL-INSTANCE ID="S_13_2">
+ <fx:SEQUENCE-NUMBER>0</fx:SEQUENCE-NUMBER>
+ <fx:SIGNAL-REF ID-REF="S_FLOA32"/>
+ <fx:MANUFACTURER-EXTENSION>
+ <VARI_NAME>reading</VARI_NAME>
+ <VARI_UNIT>Kelvin</VARI_UNIT>
+ </fx:MANUFACTURER-EXTENSION>
+ </fx:SIGNAL-INSTANCE>
+ </fx:SIGNAL-INSTANCES>
+ </fx:PDU>
+ <!--=============== Message 14 ==================-->
+ <!--=============== 1. Parameter ==================-->
+ <fx:PDU ID="PDU_14_0">
+ <ho:SHORT-NAME>PDU_14_0</ho:SHORT-NAME>
+ <ho:DESC>Build ID:</ho:DESC>
+ <fx:BYTE-LENGTH>0</fx:BYTE-LENGTH>
+ <fx:PDU-TYPE>OTHER</fx:PDU-TYPE>
+ </fx:PDU>
+ <!--=============== 2. Parameter ==================-->
+ <fx:PDU ID="PDU_14_1">
+ <ho:SHORT-NAME>PDU_14_1</ho:SHORT-NAME>
+ <fx:BYTE-LENGTH>0</fx:BYTE-LENGTH>
+ <fx:PDU-TYPE>OTHER</fx:PDU-TYPE>
+ <fx:SIGNAL-INSTANCES>
+ <fx:SIGNAL-INSTANCE ID="S_14_1">
+ <fx:SEQUENCE-NUMBER>0</fx:SEQUENCE-NUMBER>
+ <fx:SIGNAL-REF ID-REF="S_STRG_ASCII"/>
+ </fx:SIGNAL-INSTANCE>
+ </fx:SIGNAL-INSTANCES>
+ </fx:PDU>
+ </fx:PDUS>
+ <!--*************************** FRAMES ***************************-->
+ <fx:FRAMES>
+ <!-- ================== 1. Log and Trace Message ============ -->
+ <fx:FRAME ID="ID_10">
+ <ho:SHORT-NAME>ID_10</ho:SHORT-NAME>
+ <fx:BYTE-LENGTH>0</fx:BYTE-LENGTH>
+ <fx:FRAME-TYPE>OTHER</fx:FRAME-TYPE>
+ <fx:PDU-INSTANCES>
+ <fx:PDU-INSTANCE ID="P_10_0">
+ <fx:PDU-REF ID-REF="PDU_10_0"/>
+ <fx:SEQUENCE-NUMBER>0</fx:SEQUENCE-NUMBER>
+ </fx:PDU-INSTANCE>
+ </fx:PDU-INSTANCES>
+ <fx:MANUFACTURER-EXTENSION>
+ <MESSAGE_TYPE>DLT_TYPE_LOG</MESSAGE_TYPE>
+ <MESSAGE_INFO>DLT_LOG_INFO</MESSAGE_INFO>
+ <APPLICATION_ID>TEST</APPLICATION_ID>
+ <CONTEXT_ID>CON1</CONTEXT_ID>
+ <MESSAGE_SOURCE_FILE>dlt_test.c</MESSAGE_SOURCE_FILE>
+ <MESSAGE_LINE_NUMBER>411</MESSAGE_LINE_NUMBER>
+ </fx:MANUFACTURER-EXTENSION>
+ </fx:FRAME>
+ <!-- ================== 2. Log and Trace Message ============ -->
+ <fx:FRAME ID="ID_11">
+ <ho:SHORT-NAME>ID_1001</ho:SHORT-NAME>
+ <fx:BYTE-LENGTH>2</fx:BYTE-LENGTH>
+ <fx:FRAME-TYPE>OTHER</fx:FRAME-TYPE>
+ <fx:PDU-INSTANCES>
+ <fx:PDU-INSTANCE ID="P_11_0">
+ <fx:PDU-REF ID-REF="PDU_11_0"/>
+ <fx:SEQUENCE-NUMBER>0</fx:SEQUENCE-NUMBER>
+ </fx:PDU-INSTANCE>
+ <fx:PDU-INSTANCE ID="P_1001_1">
+ <fx:PDU-REF ID-REF="PDU_11_1"/>
+ <fx:SEQUENCE-NUMBER>1</fx:SEQUENCE-NUMBER>
+ </fx:PDU-INSTANCE>
+ </fx:PDU-INSTANCES>
+ <fx:MANUFACTURER-EXTENSION>
+ <MESSAGE_TYPE>DLT_TYPE_LOG</MESSAGE_TYPE>
+ <MESSAGE_INFO>DLT_LOG_WARN</MESSAGE_INFO>
+ <APPLICATION_ID>APP1</APPLICATION_ID>
+ <CONTEXT_ID>CON1</CONTEXT_ID>
+ <MESSAGE_SOURCE_FILE>application_file.c</MESSAGE_SOURCE_FILE>
+ <MESSAGE_LINE_NUMBER>955</MESSAGE_LINE_NUMBER>
+ </fx:MANUFACTURER-EXTENSION>
+ </fx:FRAME>
+ <!-- ================== 3. Log and Trace Message ============ -->
+ <fx:FRAME ID="ID_12">
+ <ho:SHORT-NAME>ID_1002</ho:SHORT-NAME>
+ <fx:BYTE-LENGTH>2</fx:BYTE-LENGTH>
+ <fx:FRAME-TYPE>OTHER</fx:FRAME-TYPE>
+ <fx:PDU-INSTANCES>
+ <fx:PDU-INSTANCE ID="P_12_0">
+ <fx:PDU-REF ID-REF="PDU_12_0"/>
+ <fx:SEQUENCE-NUMBER>0</fx:SEQUENCE-NUMBER>
+ </fx:PDU-INSTANCE>
+ <fx:PDU-INSTANCE ID="P_12_1">
+ <fx:PDU-REF ID-REF="PDU_12_1"/>
+ <fx:SEQUENCE-NUMBER>1</fx:SEQUENCE-NUMBER>
+ </fx:PDU-INSTANCE>
+ <fx:PDU-INSTANCE ID="P_12_2">
+ <fx:PDU-REF ID-REF="PDU_12_2"/>
+ <fx:SEQUENCE-NUMBER>2</fx:SEQUENCE-NUMBER>
+ </fx:PDU-INSTANCE>
+ <fx:PDU-INSTANCE ID="P_12_3">
+ <fx:PDU-REF ID-REF="PDU_12_3"/>
+ <fx:SEQUENCE-NUMBER>3</fx:SEQUENCE-NUMBER>
+ </fx:PDU-INSTANCE>
+ </fx:PDU-INSTANCES>
+ <fx:MANUFACTURER-EXTENSION>
+ <MESSAGE_TYPE>DLT_TYPE_LOG</MESSAGE_TYPE>
+ <MESSAGE_INFO>DLT_LOG_ERROR</MESSAGE_INFO>
+ <APPLICATION_ID>APP1</APPLICATION_ID>
+ <CONTEXT_ID>CON1</CONTEXT_ID>
+ <MESSAGE_SOURCE_FILE>application_file.c</MESSAGE_SOURCE_FILE>
+ <MESSAGE_LINE_NUMBER>1058</MESSAGE_LINE_NUMBER>
+ </fx:MANUFACTURER-EXTENSION>
+ </fx:FRAME>
+ <!-- ================== 4. Log and Trace Message ============ -->
+ <fx:FRAME ID="ID_13">
+ <ho:SHORT-NAME>ID_1003</ho:SHORT-NAME>
+ <fx:BYTE-LENGTH>5</fx:BYTE-LENGTH>
+ <fx:FRAME-TYPE>OTHER</fx:FRAME-TYPE>
+ <fx:PDU-INSTANCES>
+ <fx:PDU-INSTANCE ID="P_13_0">
+ <fx:PDU-REF ID-REF="PDU_13_0"/>
+ <fx:SEQUENCE-NUMBER>0</fx:SEQUENCE-NUMBER>
+ </fx:PDU-INSTANCE>
+ <fx:PDU-INSTANCE ID="P_13_1">
+ <fx:PDU-REF ID-REF="PDU_13_1"/>
+ <fx:SEQUENCE-NUMBER>1</fx:SEQUENCE-NUMBER>
+ </fx:PDU-INSTANCE>
+ <fx:PDU-INSTANCE ID="P_13_2">
+ <fx:PDU-REF ID-REF="PDU_13_2"/>
+ <fx:SEQUENCE-NUMBER>2</fx:SEQUENCE-NUMBER>
+ </fx:PDU-INSTANCE>
+ </fx:PDU-INSTANCES>
+ <fx:MANUFACTURER-EXTENSION>
+ <MESSAGE_TYPE>DLT_TYPE_LOG</MESSAGE_TYPE>
+ <MESSAGE_INFO>DLT_LOG_INFO</MESSAGE_INFO>
+ <APPLICATION_ID>APP1</APPLICATION_ID>
+ <CONTEXT_ID>CON1</CONTEXT_ID>
+ <MESSAGE_SOURCE_FILE>temp_meas.c</MESSAGE_SOURCE_FILE>
+ <MESSAGE_LINE_NUMBER>42</MESSAGE_LINE_NUMBER>
+ </fx:MANUFACTURER-EXTENSION>
+ </fx:FRAME>
+ <!-- ================== 5. Log and Trace Message ============ -->
+ <fx:FRAME ID="ID_14">
+ <ho:SHORT-NAME>ID_14</ho:SHORT-NAME>
+ <fx:BYTE-LENGTH>0</fx:BYTE-LENGTH>
+ <fx:FRAME-TYPE>OTHER</fx:FRAME-TYPE>
+ <fx:PDU-INSTANCES>
+ <fx:PDU-INSTANCE ID="P_14_0">
+ <fx:PDU-REF ID-REF="PDU_14_0"/>
+ <fx:SEQUENCE-NUMBER>0</fx:SEQUENCE-NUMBER>
+ </fx:PDU-INSTANCE>
+ <fx:PDU-INSTANCE ID="P_14_1">
+ <fx:PDU-REF ID-REF="PDU_14_1"/>
+ <fx:SEQUENCE-NUMBER>1</fx:SEQUENCE-NUMBER>
+ </fx:PDU-INSTANCE>
+ </fx:PDU-INSTANCES>
+ <fx:MANUFACTURER-EXTENSION>
+ <MESSAGE_TYPE>DLT_TYPE_LOG</MESSAGE_TYPE>
+ <MESSAGE_INFO>DLT_LOG_INFO</MESSAGE_INFO>
+ <APPLICATION_ID>LAT</APPLICATION_ID>
+ <CONTEXT_ID>NV</CONTEXT_ID>
+ <MESSAGE_SOURCE_FILE>latsTask.c</MESSAGE_SOURCE_FILE>
+ <MESSAGE_LINE_NUMBER>421</MESSAGE_LINE_NUMBER>
+ </fx:MANUFACTURER-EXTENSION>
+ </fx:FRAME>
+ </fx:FRAMES>
+
+ <!--*************************** signals **************************-->
+ <fx:SIGNALS>
+ <!--======================= BOOL =====================-->
+ <fx:SIGNAL ID="S_BOOL">
+ <ho:SHORT-NAME>S_BOOL</ho:SHORT-NAME>
+ <fx:CODING-REF ID-REF="BOOL"/>
+ </fx:SIGNAL>
+ <!--======================= SINT8 =====================-->
+ <fx:SIGNAL ID="S_SINT8">
+ <ho:SHORT-NAME>S_SINT8</ho:SHORT-NAME>
+ <fx:CODING-REF ID-REF="SINT8"/>
+ </fx:SIGNAL>
+ <!--======================= UINT8 =====================-->
+ <fx:SIGNAL ID="S_UINT8">
+ <ho:SHORT-NAME>S_UINT8</ho:SHORT-NAME>
+ <fx:CODING-REF ID-REF="UINT8"/>
+ </fx:SIGNAL>
+ <!--======================= SINT16 =====================-->
+ <fx:SIGNAL ID="S_SINT16">
+ <ho:SHORT-NAME>S_SINT16</ho:SHORT-NAME>
+ <fx:CODING-REF ID-REF="SINT16"/>
+ </fx:SIGNAL>
+ <!--======================= UINT16 =====================-->
+ <fx:SIGNAL ID="S_UINT16">
+ <ho:SHORT-NAME>S_UINT16</ho:SHORT-NAME>
+ <fx:CODING-REF ID-REF="UINT16"/>
+ </fx:SIGNAL>
+ <!--======================= SINT32 =====================-->
+ <fx:SIGNAL ID="S_SINT32">
+ <ho:SHORT-NAME>S_SINT32</ho:SHORT-NAME>
+ <fx:CODING-REF ID-REF="SINT32"/>
+ </fx:SIGNAL>
+ <!--======================= UINT32 =====================-->
+ <fx:SIGNAL ID="S_UINT32">
+ <ho:SHORT-NAME>S_UINT32</ho:SHORT-NAME>
+ <fx:CODING-REF ID-REF="UINT32"/>
+ </fx:SIGNAL>
+ <!--======================= SINT64 =====================-->
+ <fx:SIGNAL ID="S_SINT64">
+ <ho:SHORT-NAME>S_SINT64</ho:SHORT-NAME>
+ <fx:CODING-REF ID-REF="SINT64"/>
+ </fx:SIGNAL>
+ <!--======================= UINT64 =====================-->
+ <fx:SIGNAL ID="S_UINT64">
+ <ho:SHORT-NAME>S_UINT64</ho:SHORT-NAME>
+ <fx:CODING-REF ID-REF="UINT64"/>
+ </fx:SIGNAL>
+ <!--======================= FLOA16 =====================-->
+ <fx:SIGNAL ID="S_FLOA16">
+ <ho:SHORT-NAME>S_FLOA16</ho:SHORT-NAME>
+ <fx:CODING-REF ID-REF="FLOA16"/>
+ </fx:SIGNAL>
+ <!--======================= FLOA32 =====================-->
+ <fx:SIGNAL ID="S_FLOA32">
+ <ho:SHORT-NAME>S_FLOA32</ho:SHORT-NAME>
+ <fx:CODING-REF ID-REF="FLOA32"/>
+ </fx:SIGNAL>
+ <!--======================= FLOA64 =====================-->
+ <fx:SIGNAL ID="S_FLOA64">
+ <ho:SHORT-NAME>S_FLOA64</ho:SHORT-NAME>
+ <fx:CODING-REF ID-REF="FLOA64"/>
+ </fx:SIGNAL>
+ <!--======================= STRG_ASCII =====================-->
+ <fx:SIGNAL ID="S_STRG_ASCII">
+ <ho:SHORT-NAME>S_STRG_ASCII</ho:SHORT-NAME>
+ <fx:CODING-REF ID-REF="STRG_ASCII"/>
+ </fx:SIGNAL>
+ <!--======================= STRG_UTF8 =====================-->
+ <fx:SIGNAL ID="S_STRG_UTF8">
+ <ho:SHORT-NAME>S_STRG_UTF8</ho:SHORT-NAME>
+ <fx:CODING-REF ID-REF="STRG_UTF8"/>
+ </fx:SIGNAL>
+ </fx:SIGNALS>
+ </fx:ELEMENTS>
+
+ <!--********************* PROCESSING INFORMATION *********************-->
+
+ <fx:PROCESSING-INFORMATION>
+ <!--*************************** codings ****************************-->
+ <fx:CODINGS>
+ <fx:CODING ID="BOOL">
+ <ho:SHORT-NAME>BOOL</ho:SHORT-NAME>
+ <ho:DESC>Coding for boolean values.</ho:DESC>
+ <ho:CODED-TYPE ho:BASE-DATA-TYPE="A_UINT8" CATEGORY="STANDARD-LENGTH-TYPE" ENCODING="UNSIGNED">
+ <ho:BIT-LENGTH>8</ho:BIT-LENGTH>
+ </ho:CODED-TYPE>
+ </fx:CODING>
+ <fx:CODING ID="SINT8">
+ <ho:SHORT-NAME>SINT8</ho:SHORT-NAME>
+ <ho:DESC>Coding for signel 8bit values.</ho:DESC>
+ <ho:CODED-TYPE ho:BASE-DATA-TYPE="A_INT8" CATEGORY="STANDARD-LENGTH-TYPE" ENCODING="SIGNED">
+ <ho:BIT-LENGTH>8</ho:BIT-LENGTH>
+ </ho:CODED-TYPE>
+ </fx:CODING>
+ <fx:CODING ID="UINT8">
+ <ho:SHORT-NAME>UINT8</ho:SHORT-NAME>
+ <ho:DESC>Coding for unsignel 8bit values.</ho:DESC>
+ <ho:CODED-TYPE ho:BASE-DATA-TYPE="A_UINT8" CATEGORY="STANDARD-LENGTH-TYPE" ENCODING="UNSIGNED">
+ <ho:BIT-LENGTH>8</ho:BIT-LENGTH>
+ </ho:CODED-TYPE>
+ </fx:CODING>
+ <fx:CODING ID="SINT16">
+ <ho:SHORT-NAME>SINT16</ho:SHORT-NAME>
+ <ho:DESC>Coding for signel 16bit values.</ho:DESC>
+ <ho:CODED-TYPE ho:BASE-DATA-TYPE="A_INT16" CATEGORY="STANDARD-LENGTH-TYPE" ENCODING="SIGNED">
+ <ho:BIT-LENGTH>16</ho:BIT-LENGTH>
+ </ho:CODED-TYPE>
+ </fx:CODING>
+ <fx:CODING ID="UINT16">
+ <ho:SHORT-NAME>UINT16</ho:SHORT-NAME>
+ <ho:DESC>Coding for unsignel 16bit values.</ho:DESC>
+ <ho:CODED-TYPE ho:BASE-DATA-TYPE="A_UINT16" CATEGORY="STANDARD-LENGTH-TYPE" ENCODING="UNSIGNED">
+ <ho:BIT-LENGTH>16</ho:BIT-LENGTH>
+ </ho:CODED-TYPE>
+ </fx:CODING>
+ <fx:CODING ID="SINT32">
+ <ho:SHORT-NAME>SINT32</ho:SHORT-NAME>
+ <ho:DESC>Coding for signel 32bit values.</ho:DESC>
+ <ho:CODED-TYPE ho:BASE-DATA-TYPE="A_INT32" CATEGORY="STANDARD-LENGTH-TYPE" ENCODING="SIGNED">
+ <ho:BIT-LENGTH>32</ho:BIT-LENGTH>
+ </ho:CODED-TYPE>
+ </fx:CODING>
+ <fx:CODING ID="UINT32">
+ <ho:SHORT-NAME>UINT32</ho:SHORT-NAME>
+ <ho:DESC>Coding for unsignel 32bit values.</ho:DESC>
+ <ho:CODED-TYPE ho:BASE-DATA-TYPE="A_UINT32" CATEGORY="STANDARD-LENGTH-TYPE" ENCODING="UNSIGNED">
+ <ho:BIT-LENGTH>32</ho:BIT-LENGTH>
+ </ho:CODED-TYPE>
+ </fx:CODING>
+ <fx:CODING ID="SINT64">
+ <ho:SHORT-NAME>SINT64</ho:SHORT-NAME>
+ <ho:DESC>Coding for signel 64bit values.</ho:DESC>
+ <ho:CODED-TYPE ho:BASE-DATA-TYPE="A_INT64" CATEGORY="STANDARD-LENGTH-TYPE" ENCODING="SIGNED">
+ <ho:BIT-LENGTH>64</ho:BIT-LENGTH>
+ </ho:CODED-TYPE>
+ </fx:CODING>
+ <fx:CODING ID="UINT64">
+ <ho:SHORT-NAME>UINT64</ho:SHORT-NAME>
+ <ho:DESC>Coding for unsignel 64bit values.</ho:DESC>
+ <ho:CODED-TYPE ho:BASE-DATA-TYPE="A_UINT64" CATEGORY="STANDARD-LENGTH-TYPE" ENCODING="UNSIGNED">
+ <ho:BIT-LENGTH>64</ho:BIT-LENGTH>
+ </ho:CODED-TYPE>
+ </fx:CODING>
+ <fx:CODING ID="FLOA16">
+ <ho:SHORT-NAME>FLOA16</ho:SHORT-NAME>
+ <ho:DESC>Coding for float 16bit values.</ho:DESC>
+ <ho:CODED-TYPE ho:BASE-DATA-TYPE="A_FLOAT32" CATEGORY="STANDARD-LENGTH-TYPE" ENCODING="IEEE-FLOATING-TYPE">
+ <ho:BIT-LENGTH>16</ho:BIT-LENGTH>
+ </ho:CODED-TYPE>
+ </fx:CODING>
+ <fx:CODING ID="FLOA32">
+ <ho:SHORT-NAME>FLOA32</ho:SHORT-NAME>
+ <ho:DESC>Coding for float 32bit values.</ho:DESC>
+ <ho:CODED-TYPE ho:BASE-DATA-TYPE="A_FLOAT32" CATEGORY="STANDARD-LENGTH-TYPE" ENCODING="IEEE-FLOATING-TYPE">
+ <ho:BIT-LENGTH>32</ho:BIT-LENGTH>
+ </ho:CODED-TYPE>
+ </fx:CODING>
+ <fx:CODING ID="FLOA64">
+ <ho:SHORT-NAME>FLOA64</ho:SHORT-NAME>
+ <ho:DESC>Coding for float 64bit values.</ho:DESC>
+ <ho:CODED-TYPE ho:BASE-DATA-TYPE="A_FLOAT64" CATEGORY="STANDARD-LENGTH-TYPE" ENCODING="IEEE-FLOATING-TYPE">
+ <ho:BIT-LENGTH>64</ho:BIT-LENGTH>
+ </ho:CODED-TYPE>
+ </fx:CODING>
+ <fx:CODING ID="STRG_ASCII">
+ <ho:SHORT-NAME>STRG_ASCII</ho:SHORT-NAME>
+ <ho:DESC>Coding for ASCII string.</ho:DESC>
+ <ho:CODED-TYPE ho:BASE-DATA-TYPE="A_ASCIISTRING" CATEGORY="STANDARD-LENGTH-TYPE" TERMINATION="ZERO">
+ <ho:MIN-LENGTH>0</ho:MIN-LENGTH>
+ <ho:MAX-LENGTH>255</ho:MAX-LENGTH>
+ </ho:CODED-TYPE>
+ </fx:CODING>
+ <fx:CODING ID="STRG_UTF8">
+ <ho:SHORT-NAME>STRG_UTF8</ho:SHORT-NAME>
+ <ho:DESC>Coding for UTF8 string.</ho:DESC>
+ <ho:CODED-TYPE ho:BASE-DATA-TYPE="A_UNICODE2STRING" CATEGORY="STANDARD-LENGTH-TYPE" ENCODING="UTF-8" TERMINATION="ZERO">
+ <ho:MIN-LENGTH>0</ho:MIN-LENGTH>
+ <ho:MAX-LENGTH>255</ho:MAX-LENGTH>
+ </ho:CODED-TYPE>
+ </fx:CODING>
+ </fx:CODINGS>
+ </fx:PROCESSING-INFORMATION>
+</fx:FIBEX>
diff --git a/src/examples/dlt-example-non-verbose.xml b/src/examples/dlt-example-non-verbose.xml new file mode 100755 index 0000000..3b31ed3 --- /dev/null +++ b/src/examples/dlt-example-non-verbose.xml @@ -0,0 +1,425 @@ +<?xml version="1.0"?>
+<!-- -->
+<!-- DLT example for DLT non-verbose mode -->
+<!-- -->
+<!-- Author: Jens Levihn, -->
+<!-- PEIKER acustic GmbH & Co. KG, Max-Planck-Str. 32, 61381 Friedrichsdorf -->
+<!-- -->
+<!-- -->
+<fx:FIBEX xmlns:fx="http://www.asam.net/xml/fbx" xmlns:ho="http://www.asam.net/xml" xmlns:can="http://www.asam.net/xml/fbx/can" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.asam.net/xml/fbx xml_schema\fibex.xsd http://www.asam.net/xml/fbx/can xml_schema\fibex4can.xsd" VERSION="3.1.0">
+ <fx:PROJECT ID="projectTCB">
+ <ho:SHORT-NAME>projectTCB</ho:SHORT-NAME>
+ </fx:PROJECT>
+ <fx:ELEMENTS>
+ <!--***************************** ECU ***************************-->
+ <fx:ECUS>
+ <fx:ECU ID="TCB">
+ <ho:SHORT-NAME>TCB</ho:SHORT-NAME>
+ <fx:MANUFACTURER-EXTENSION>
+ <SW_VERSION>001.004.062</SW_VERSION>
+ </fx:MANUFACTURER-EXTENSION>
+ </fx:ECU>
+ </fx:ECUS>
+ <!--*************************** PDUS ***************************-->
+ <fx:PDUS>
+ <!--=============== Message 10 ==================-->
+ <!--=============== 1. Parameter ==================-->
+ <fx:PDU ID="PDU_10_0">
+ <ho:SHORT-NAME>PDU_10_0</ho:SHORT-NAME>
+ <ho:DESC>DLT non verbose test message.</ho:DESC>
+ <fx:BYTE-LENGTH>0</fx:BYTE-LENGTH>
+ <fx:PDU-TYPE>OTHER</fx:PDU-TYPE>
+ </fx:PDU>
+ <!--=============== Message 11 ==================-->
+ <!--=============== 1. Parameter ==================-->
+ <fx:PDU ID="PDU_11_0">
+ <ho:SHORT-NAME>PDU_11_0</ho:SHORT-NAME>
+ <ho:DESC>Buffer near limit. Free size:</ho:DESC>
+ <fx:BYTE-LENGTH>0</fx:BYTE-LENGTH>
+ <fx:PDU-TYPE>OTHER</fx:PDU-TYPE>
+ </fx:PDU>
+ <!--=============== 2. Parameter ==================-->
+ <fx:PDU ID="PDU_11_1">
+ <ho:SHORT-NAME>PDU_11_1</ho:SHORT-NAME>
+ <fx:BYTE-LENGTH>2</fx:BYTE-LENGTH>
+ <fx:PDU-TYPE>OTHER</fx:PDU-TYPE>
+ <fx:SIGNAL-INSTANCES>
+ <fx:SIGNAL-INSTANCE ID="S_11_1">
+ <fx:SEQUENCE-NUMBER>0</fx:SEQUENCE-NUMBER>
+ <fx:SIGNAL-REF ID-REF="S_UINT16"/>
+ </fx:SIGNAL-INSTANCE>
+ </fx:SIGNAL-INSTANCES>
+ </fx:PDU>
+ <!--=============== Message 12 ==================-->
+ <!--=============== 1. Parameter ==================-->
+ <fx:PDU ID="PDU_12_0">
+ <ho:SHORT-NAME>PDU_12_0</ho:SHORT-NAME>
+ <ho:DESC>Buffer size exceeded.</ho:DESC>
+ <fx:BYTE-LENGTH>0</fx:BYTE-LENGTH>
+ <fx:PDU-TYPE>OTHER</fx:PDU-TYPE>
+ </fx:PDU>
+ <!--=============== 2. Parameter ==================-->
+ <fx:PDU ID="PDU_12_1">
+ <ho:SHORT-NAME>PDU_12_1</ho:SHORT-NAME>
+ <ho:DESC>Requested size:</ho:DESC>
+ <fx:BYTE-LENGTH>4</fx:BYTE-LENGTH>
+ <fx:PDU-TYPE>OTHER</fx:PDU-TYPE>
+ <fx:SIGNAL-INSTANCES>
+ <fx:SIGNAL-INSTANCE ID="S_12_1">
+ <fx:SEQUENCE-NUMBER>0</fx:SEQUENCE-NUMBER>
+ <fx:SIGNAL-REF ID-REF="S_UINT32"/>
+ </fx:SIGNAL-INSTANCE>
+ </fx:SIGNAL-INSTANCES>
+ </fx:PDU>
+ <!--=============== 3. Parameter ==================-->
+ <fx:PDU ID="PDU_12_2">
+ <ho:SHORT-NAME>PDU_12_2</ho:SHORT-NAME>
+ <ho:DESC>Free size:</ho:DESC>
+ <fx:BYTE-LENGTH>4</fx:BYTE-LENGTH>
+ <fx:PDU-TYPE>OTHER</fx:PDU-TYPE>
+ <fx:SIGNAL-INSTANCES>
+ <fx:SIGNAL-INSTANCE ID="S_12_2">
+ <fx:SEQUENCE-NUMBER>0</fx:SEQUENCE-NUMBER>
+ <fx:SIGNAL-REF ID-REF="S_UINT32"/>
+ </fx:SIGNAL-INSTANCE>
+ </fx:SIGNAL-INSTANCES>
+ </fx:PDU>
+ <!--=============== 4. Parameter ==================-->
+ <fx:PDU ID="PDU_12_3">
+ <ho:SHORT-NAME>PDU_12_3</ho:SHORT-NAME>
+ <ho:DESC>Process terminated.</ho:DESC>
+ <fx:BYTE-LENGTH>0</fx:BYTE-LENGTH>
+ <fx:PDU-TYPE>OTHER</fx:PDU-TYPE>
+ </fx:PDU>
+ <!--=============== Message 13 ==================-->
+ <!--=============== 1. Parameter ==================-->
+ <fx:PDU ID="PDU_13_0">
+ <ho:SHORT-NAME>PDU_13_0</ho:SHORT-NAME>
+ <ho:DESC>Temperature measurement</ho:DESC>
+ <fx:BYTE-LENGTH>0</fx:BYTE-LENGTH>
+ <fx:PDU-TYPE>OTHER</fx:PDU-TYPE>
+ </fx:PDU>
+ <!--=============== 2. Parameter ==================-->
+ <fx:PDU ID="PDU_13_1">
+ <ho:SHORT-NAME>PDU_13_1</ho:SHORT-NAME>
+ <fx:BYTE-LENGTH>1</fx:BYTE-LENGTH>
+ <fx:PDU-TYPE>OTHER</fx:PDU-TYPE>
+ <fx:SIGNAL-INSTANCES>
+ <fx:SIGNAL-INSTANCE ID="S_13_1">
+ <fx:SEQUENCE-NUMBER>0</fx:SEQUENCE-NUMBER>
+ <fx:SIGNAL-REF ID-REF="S_UINT8"/>
+ <fx:MANUFACTURER-EXTENSION>
+ <VARI_NAME>measurement_point</VARI_NAME>
+ <VARI_UNIT></VARI_UNIT>
+ </fx:MANUFACTURER-EXTENSION>
+ </fx:SIGNAL-INSTANCE>
+ </fx:SIGNAL-INSTANCES>
+ </fx:PDU>
+ <!--=============== 3. Parameter ==================-->
+ <fx:PDU ID="PDU_13_2">
+ <ho:SHORT-NAME>PDU_13_2</ho:SHORT-NAME>
+ <fx:BYTE-LENGTH>4</fx:BYTE-LENGTH>
+ <fx:PDU-TYPE>OTHER</fx:PDU-TYPE>
+ <fx:SIGNAL-INSTANCES>
+ <fx:SIGNAL-INSTANCE ID="S_13_2">
+ <fx:SEQUENCE-NUMBER>0</fx:SEQUENCE-NUMBER>
+ <fx:SIGNAL-REF ID-REF="S_FLOA32"/>
+ <fx:MANUFACTURER-EXTENSION>
+ <VARI_NAME>reading</VARI_NAME>
+ <VARI_UNIT>Kelvin</VARI_UNIT>
+ </fx:MANUFACTURER-EXTENSION>
+ </fx:SIGNAL-INSTANCE>
+ </fx:SIGNAL-INSTANCES>
+ </fx:PDU>
+ </fx:PDUS>
+ <!--*************************** FRAMES ***************************-->
+ <fx:FRAMES>
+ <!-- ================== 1. Log and Trace Message ============ -->
+ <fx:FRAME ID="ID_10">
+ <ho:SHORT-NAME>ID_10</ho:SHORT-NAME>
+ <fx:BYTE-LENGTH>0</fx:BYTE-LENGTH>
+ <fx:FRAME-TYPE>OTHER</fx:FRAME-TYPE>
+ <fx:PDU-INSTANCES>
+ <fx:PDU-INSTANCE ID="P_10_0">
+ <fx:PDU-REF ID-REF="PDU_10_0"/>
+ <fx:SEQUENCE-NUMBER>0</fx:SEQUENCE-NUMBER>
+ </fx:PDU-INSTANCE>
+ </fx:PDU-INSTANCES>
+ <fx:MANUFACTURER-EXTENSION>
+ <MESSAGE_TYPE>DLT_TYPE_LOG</MESSAGE_TYPE>
+ <MESSAGE_INFO>DLT_LOG_INFO</MESSAGE_INFO>
+ <APPLICATION_ID>TEST</APPLICATION_ID>
+ <CONTEXT_ID>CON1</CONTEXT_ID>
+ <MESSAGE_SOURCE_FILE>dlt_test.c</MESSAGE_SOURCE_FILE>
+ <MESSAGE_LINE_NUMBER>411</MESSAGE_LINE_NUMBER>
+ </fx:MANUFACTURER-EXTENSION>
+ </fx:FRAME>
+ <!-- ================== 2. Log and Trace Message ============ -->
+ <fx:FRAME ID="ID_11">
+ <ho:SHORT-NAME>ID_11</ho:SHORT-NAME>
+ <fx:BYTE-LENGTH>2</fx:BYTE-LENGTH>
+ <fx:FRAME-TYPE>OTHER</fx:FRAME-TYPE>
+ <fx:PDU-INSTANCES>
+ <fx:PDU-INSTANCE ID="P_11_0">
+ <fx:PDU-REF ID-REF="PDU_11_0"/>
+ <fx:SEQUENCE-NUMBER>0</fx:SEQUENCE-NUMBER>
+ </fx:PDU-INSTANCE>
+ <fx:PDU-INSTANCE ID="P_11_1">
+ <fx:PDU-REF ID-REF="PDU_11_1"/>
+ <fx:SEQUENCE-NUMBER>1</fx:SEQUENCE-NUMBER>
+ </fx:PDU-INSTANCE>
+ </fx:PDU-INSTANCES>
+ <fx:MANUFACTURER-EXTENSION>
+ <MESSAGE_TYPE>DLT_TYPE_LOG</MESSAGE_TYPE>
+ <MESSAGE_INFO>DLT_LOG_WARN</MESSAGE_INFO>
+ <APPLICATION_ID>APP1</APPLICATION_ID>
+ <CONTEXT_ID>CON1</CONTEXT_ID>
+ <MESSAGE_SOURCE_FILE>application_file.c</MESSAGE_SOURCE_FILE>
+ <MESSAGE_LINE_NUMBER>955</MESSAGE_LINE_NUMBER>
+ </fx:MANUFACTURER-EXTENSION>
+ </fx:FRAME>
+ <!-- ================== 3. Log and Trace Message ============ -->
+ <fx:FRAME ID="ID_12">
+ <ho:SHORT-NAME>ID_12</ho:SHORT-NAME>
+ <fx:BYTE-LENGTH>8</fx:BYTE-LENGTH>
+ <fx:FRAME-TYPE>OTHER</fx:FRAME-TYPE>
+ <fx:PDU-INSTANCES>
+ <fx:PDU-INSTANCE ID="P_12_0">
+ <fx:PDU-REF ID-REF="PDU_12_0"/>
+ <fx:SEQUENCE-NUMBER>0</fx:SEQUENCE-NUMBER>
+ </fx:PDU-INSTANCE>
+ <fx:PDU-INSTANCE ID="P_12_1">
+ <fx:PDU-REF ID-REF="PDU_12_1"/>
+ <fx:SEQUENCE-NUMBER>1</fx:SEQUENCE-NUMBER>
+ </fx:PDU-INSTANCE>
+ <fx:PDU-INSTANCE ID="P_12_2">
+ <fx:PDU-REF ID-REF="PDU_12_2"/>
+ <fx:SEQUENCE-NUMBER>2</fx:SEQUENCE-NUMBER>
+ </fx:PDU-INSTANCE>
+ <fx:PDU-INSTANCE ID="P_12_3">
+ <fx:PDU-REF ID-REF="PDU_12_3"/>
+ <fx:SEQUENCE-NUMBER>3</fx:SEQUENCE-NUMBER>
+ </fx:PDU-INSTANCE>
+ </fx:PDU-INSTANCES>
+ <fx:MANUFACTURER-EXTENSION>
+ <MESSAGE_TYPE>DLT_TYPE_LOG</MESSAGE_TYPE>
+ <MESSAGE_INFO>DLT_LOG_ERROR</MESSAGE_INFO>
+ <APPLICATION_ID>APP1</APPLICATION_ID>
+ <CONTEXT_ID>CON1</CONTEXT_ID>
+ <MESSAGE_SOURCE_FILE>application_file.c</MESSAGE_SOURCE_FILE>
+ <MESSAGE_LINE_NUMBER>1058</MESSAGE_LINE_NUMBER>
+ </fx:MANUFACTURER-EXTENSION>
+ </fx:FRAME>
+ <!-- ================== 4. Log and Trace Message ============ -->
+ <fx:FRAME ID="ID_13">
+ <ho:SHORT-NAME>ID_13</ho:SHORT-NAME>
+ <fx:BYTE-LENGTH>5</fx:BYTE-LENGTH>
+ <fx:FRAME-TYPE>OTHER</fx:FRAME-TYPE>
+ <fx:PDU-INSTANCES>
+ <fx:PDU-INSTANCE ID="P_13_0">
+ <fx:PDU-REF ID-REF="PDU_13_0"/>
+ <fx:SEQUENCE-NUMBER>0</fx:SEQUENCE-NUMBER>
+ </fx:PDU-INSTANCE>
+ <fx:PDU-INSTANCE ID="P_13_1">
+ <fx:PDU-REF ID-REF="PDU_13_1"/>
+ <fx:SEQUENCE-NUMBER>1</fx:SEQUENCE-NUMBER>
+ </fx:PDU-INSTANCE>
+ <fx:PDU-INSTANCE ID="P_13_2">
+ <fx:PDU-REF ID-REF="PDU_13_2"/>
+ <fx:SEQUENCE-NUMBER>2</fx:SEQUENCE-NUMBER>
+ </fx:PDU-INSTANCE>
+ </fx:PDU-INSTANCES>
+ <fx:MANUFACTURER-EXTENSION>
+ <MESSAGE_TYPE>DLT_TYPE_LOG</MESSAGE_TYPE>
+ <MESSAGE_INFO>DLT_LOG_INFO</MESSAGE_INFO>
+ <APPLICATION_ID>APP1</APPLICATION_ID>
+ <CONTEXT_ID>CON1</CONTEXT_ID>
+ <MESSAGE_SOURCE_FILE>temp_meas.c</MESSAGE_SOURCE_FILE>
+ <MESSAGE_LINE_NUMBER>42</MESSAGE_LINE_NUMBER>
+ </fx:MANUFACTURER-EXTENSION>
+ </fx:FRAME>
+ </fx:FRAMES>
+
+ <!--*************************** signals **************************-->
+ <fx:SIGNALS>
+ <!--======================= BOOL =====================-->
+ <fx:SIGNAL ID="S_BOOL">
+ <ho:SHORT-NAME>S_BOOL</ho:SHORT-NAME>
+ <fx:CODING-REF ID-REF="BOOL"/>
+ </fx:SIGNAL>
+ <!--======================= SINT8 =====================-->
+ <fx:SIGNAL ID="S_SINT8">
+ <ho:SHORT-NAME>S_SINT8</ho:SHORT-NAME>
+ <fx:CODING-REF ID-REF="SINT8"/>
+ </fx:SIGNAL>
+ <!--======================= UINT8 =====================-->
+ <fx:SIGNAL ID="S_UINT8">
+ <ho:SHORT-NAME>S_UINT8</ho:SHORT-NAME>
+ <fx:CODING-REF ID-REF="UINT8"/>
+ </fx:SIGNAL>
+ <!--======================= SINT16 =====================-->
+ <fx:SIGNAL ID="S_SINT16">
+ <ho:SHORT-NAME>S_SINT16</ho:SHORT-NAME>
+ <fx:CODING-REF ID-REF="SINT16"/>
+ </fx:SIGNAL>
+ <!--======================= UINT16 =====================-->
+ <fx:SIGNAL ID="S_UINT16">
+ <ho:SHORT-NAME>S_UINT16</ho:SHORT-NAME>
+ <fx:CODING-REF ID-REF="UINT16"/>
+ </fx:SIGNAL>
+ <!--======================= SINT32 =====================-->
+ <fx:SIGNAL ID="S_SINT32">
+ <ho:SHORT-NAME>S_SINT32</ho:SHORT-NAME>
+ <fx:CODING-REF ID-REF="SINT32"/>
+ </fx:SIGNAL>
+ <!--======================= UINT32 =====================-->
+ <fx:SIGNAL ID="S_UINT32">
+ <ho:SHORT-NAME>S_UINT32</ho:SHORT-NAME>
+ <fx:CODING-REF ID-REF="UINT32"/>
+ </fx:SIGNAL>
+ <!--======================= SINT64 =====================-->
+ <fx:SIGNAL ID="S_SINT64">
+ <ho:SHORT-NAME>S_SINT64</ho:SHORT-NAME>
+ <fx:CODING-REF ID-REF="SINT64"/>
+ </fx:SIGNAL>
+ <!--======================= UINT64 =====================-->
+ <fx:SIGNAL ID="S_UINT64">
+ <ho:SHORT-NAME>S_UINT64</ho:SHORT-NAME>
+ <fx:CODING-REF ID-REF="UINT64"/>
+ </fx:SIGNAL>
+ <!--======================= FLOA16 =====================-->
+ <fx:SIGNAL ID="S_FLOA16">
+ <ho:SHORT-NAME>S_FLOA16</ho:SHORT-NAME>
+ <fx:CODING-REF ID-REF="FLOA16"/>
+ </fx:SIGNAL>
+ <!--======================= FLOA32 =====================-->
+ <fx:SIGNAL ID="S_FLOA32">
+ <ho:SHORT-NAME>S_FLOA32</ho:SHORT-NAME>
+ <fx:CODING-REF ID-REF="FLOA32"/>
+ </fx:SIGNAL>
+ <!--======================= FLOA64 =====================-->
+ <fx:SIGNAL ID="S_FLOA64">
+ <ho:SHORT-NAME>S_FLOA64</ho:SHORT-NAME>
+ <fx:CODING-REF ID-REF="FLOA64"/>
+ </fx:SIGNAL>
+ <!--======================= STRG_ASCII =====================-->
+ <fx:SIGNAL ID="S_STRG_ASCII">
+ <ho:SHORT-NAME>S_STRG_ASCII</ho:SHORT-NAME>
+ <fx:CODING-REF ID-REF="STRG_ASCII"/>
+ </fx:SIGNAL>
+ <!--======================= STRG_UTF8 =====================-->
+ <fx:SIGNAL ID="S_STRG_UTF8">
+ <ho:SHORT-NAME>S_STRG_UTF8</ho:SHORT-NAME>
+ <fx:CODING-REF ID-REF="STRG_UTF8"/>
+ </fx:SIGNAL>
+ </fx:SIGNALS>
+ </fx:ELEMENTS>
+
+ <!--********************* PROCESSING INFORMATION *********************-->
+
+ <fx:PROCESSING-INFORMATION>
+ <!--*************************** codings ****************************-->
+ <fx:CODINGS>
+ <fx:CODING ID="BOOL">
+ <ho:SHORT-NAME>BOOL</ho:SHORT-NAME>
+ <ho:DESC>Coding for boolean values.</ho:DESC>
+ <ho:CODED-TYPE ho:BASE-DATA-TYPE="A_UINT8" CATEGORY="STANDARD-LENGTH-TYPE" ENCODING="UNSIGNED">
+ <ho:BIT-LENGTH>8</ho:BIT-LENGTH>
+ </ho:CODED-TYPE>
+ </fx:CODING>
+ <fx:CODING ID="SINT8">
+ <ho:SHORT-NAME>SINT8</ho:SHORT-NAME>
+ <ho:DESC>Coding for signel 8bit values.</ho:DESC>
+ <ho:CODED-TYPE ho:BASE-DATA-TYPE="A_INT8" CATEGORY="STANDARD-LENGTH-TYPE" ENCODING="SIGNED">
+ <ho:BIT-LENGTH>8</ho:BIT-LENGTH>
+ </ho:CODED-TYPE>
+ </fx:CODING>
+ <fx:CODING ID="UINT8">
+ <ho:SHORT-NAME>UINT8</ho:SHORT-NAME>
+ <ho:DESC>Coding for unsignel 8bit values.</ho:DESC>
+ <ho:CODED-TYPE ho:BASE-DATA-TYPE="A_UINT8" CATEGORY="STANDARD-LENGTH-TYPE" ENCODING="UNSIGNED">
+ <ho:BIT-LENGTH>8</ho:BIT-LENGTH>
+ </ho:CODED-TYPE>
+ </fx:CODING>
+ <fx:CODING ID="SINT16">
+ <ho:SHORT-NAME>SINT16</ho:SHORT-NAME>
+ <ho:DESC>Coding for signel 16bit values.</ho:DESC>
+ <ho:CODED-TYPE ho:BASE-DATA-TYPE="A_INT16" CATEGORY="STANDARD-LENGTH-TYPE" ENCODING="SIGNED">
+ <ho:BIT-LENGTH>16</ho:BIT-LENGTH>
+ </ho:CODED-TYPE>
+ </fx:CODING>
+ <fx:CODING ID="UINT16">
+ <ho:SHORT-NAME>UINT16</ho:SHORT-NAME>
+ <ho:DESC>Coding for unsignel 16bit values.</ho:DESC>
+ <ho:CODED-TYPE ho:BASE-DATA-TYPE="A_UINT16" CATEGORY="STANDARD-LENGTH-TYPE" ENCODING="UNSIGNED">
+ <ho:BIT-LENGTH>16</ho:BIT-LENGTH>
+ </ho:CODED-TYPE>
+ </fx:CODING>
+ <fx:CODING ID="SINT32">
+ <ho:SHORT-NAME>SINT32</ho:SHORT-NAME>
+ <ho:DESC>Coding for signel 32bit values.</ho:DESC>
+ <ho:CODED-TYPE ho:BASE-DATA-TYPE="A_INT32" CATEGORY="STANDARD-LENGTH-TYPE" ENCODING="SIGNED">
+ <ho:BIT-LENGTH>32</ho:BIT-LENGTH>
+ </ho:CODED-TYPE>
+ </fx:CODING>
+ <fx:CODING ID="UINT32">
+ <ho:SHORT-NAME>UINT32</ho:SHORT-NAME>
+ <ho:DESC>Coding for unsignel 32bit values.</ho:DESC>
+ <ho:CODED-TYPE ho:BASE-DATA-TYPE="A_UINT32" CATEGORY="STANDARD-LENGTH-TYPE" ENCODING="UNSIGNED">
+ <ho:BIT-LENGTH>32</ho:BIT-LENGTH>
+ </ho:CODED-TYPE>
+ </fx:CODING>
+ <fx:CODING ID="SINT64">
+ <ho:SHORT-NAME>SINT64</ho:SHORT-NAME>
+ <ho:DESC>Coding for signel 64bit values.</ho:DESC>
+ <ho:CODED-TYPE ho:BASE-DATA-TYPE="A_INT64" CATEGORY="STANDARD-LENGTH-TYPE" ENCODING="SIGNED">
+ <ho:BIT-LENGTH>64</ho:BIT-LENGTH>
+ </ho:CODED-TYPE>
+ </fx:CODING>
+ <fx:CODING ID="UINT64">
+ <ho:SHORT-NAME>UINT64</ho:SHORT-NAME>
+ <ho:DESC>Coding for unsignel 64bit values.</ho:DESC>
+ <ho:CODED-TYPE ho:BASE-DATA-TYPE="A_UINT64" CATEGORY="STANDARD-LENGTH-TYPE" ENCODING="UNSIGNED">
+ <ho:BIT-LENGTH>64</ho:BIT-LENGTH>
+ </ho:CODED-TYPE>
+ </fx:CODING>
+ <fx:CODING ID="FLOA16">
+ <ho:SHORT-NAME>FLOA16</ho:SHORT-NAME>
+ <ho:DESC>Coding for float 16bit values.</ho:DESC>
+ <ho:CODED-TYPE ho:BASE-DATA-TYPE="A_FLOAT32" CATEGORY="STANDARD-LENGTH-TYPE" ENCODING="IEEE-FLOATING-TYPE">
+ <ho:BIT-LENGTH>16</ho:BIT-LENGTH>
+ </ho:CODED-TYPE>
+ </fx:CODING>
+ <fx:CODING ID="FLOA32">
+ <ho:SHORT-NAME>FLOA32</ho:SHORT-NAME>
+ <ho:DESC>Coding for float 32bit values.</ho:DESC>
+ <ho:CODED-TYPE ho:BASE-DATA-TYPE="A_FLOAT32" CATEGORY="STANDARD-LENGTH-TYPE" ENCODING="IEEE-FLOATING-TYPE">
+ <ho:BIT-LENGTH>32</ho:BIT-LENGTH>
+ </ho:CODED-TYPE>
+ </fx:CODING>
+ <fx:CODING ID="FLOA64">
+ <ho:SHORT-NAME>FLOA64</ho:SHORT-NAME>
+ <ho:DESC>Coding for float 64bit values.</ho:DESC>
+ <ho:CODED-TYPE ho:BASE-DATA-TYPE="A_FLOAT64" CATEGORY="STANDARD-LENGTH-TYPE" ENCODING="IEEE-FLOATING-TYPE">
+ <ho:BIT-LENGTH>64</ho:BIT-LENGTH>
+ </ho:CODED-TYPE>
+ </fx:CODING>
+ <fx:CODING ID="STRG_ASCII">
+ <ho:SHORT-NAME>STRG_ASCII</ho:SHORT-NAME>
+ <ho:DESC>Coding for ASCII string.</ho:DESC>
+ <ho:CODED-TYPE ho:BASE-DATA-TYPE="A_ASCIISTRING" CATEGORY="STANDARD-LENGTH-TYPE" TERMINATION="ZERO">
+ <ho:MIN-LENGTH>0</ho:MIN-LENGTH>
+ <ho:MAX-LENGTH>255</ho:MAX-LENGTH>
+ </ho:CODED-TYPE>
+ </fx:CODING>
+ <fx:CODING ID="STRG_UTF8">
+ <ho:SHORT-NAME>STRG_UTF8</ho:SHORT-NAME>
+ <ho:DESC>Coding for UTF8 string.</ho:DESC>
+ <ho:CODED-TYPE ho:BASE-DATA-TYPE="A_UNICODE2STRING" CATEGORY="STANDARD-LENGTH-TYPE" ENCODING="UTF-8" TERMINATION="ZERO">
+ <ho:MIN-LENGTH>0</ho:MIN-LENGTH>
+ <ho:MAX-LENGTH>255</ho:MAX-LENGTH>
+ </ho:CODED-TYPE>
+ </fx:CODING>
+ </fx:CODINGS>
+ </fx:PROCESSING-INFORMATION>
+</fx:FIBEX>
diff --git a/src/examples/dlt-example-user-func.c b/src/examples/dlt-example-user-func.c new file mode 100755 index 0000000..2180a6b --- /dev/null +++ b/src/examples/dlt-example-user-func.c @@ -0,0 +1,339 @@ +/* + * Dlt Client console utilities - Diagnostic Log and Trace + * @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-example-user-func.cpp ** +** ** +** TARGET : linux ** +** ** +** PROJECT : DLT ** +** ** +** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** +** Markus Klein ** +** ** +** PURPOSE : ** +** ** +** REMARKS : ** +** ** +** PLATFORM DEPENDANT [yes/no]: yes ** +** ** +** TO BE CHANGED BY USER [yes/no]: no ** +** ** +*******************************************************************************/ + +/******************************************************************************* +** Author Identity ** +******************************************************************************** +** ** +** Initials Name Company ** +** -------- ------------------------- ---------------------------------- ** +** aw Alexander Wenzel BMW ** +** mk Markus Klein Fraunhofer ESK ** +*******************************************************************************/ + +/******************************************************************************* +** Revision Control History ** +*******************************************************************************/ + +/* + * $LastChangedRevision: 1670 $ + * $LastChangedDate: 2011-04-08 15:12:06 +0200 (Fr, 08. Apr 2011) $ + * $LastChangedBy$ + Initials Date Comment + aw 13.01.2010 initial + */ +#include <netdb.h> +#include <ctype.h> +#include <stdio.h> /* for printf() and fprintf() */ +#include <stdlib.h> /* for atoi() and exit() */ +#include <string.h> /* for memset() */ +#include <unistd.h> /* for close() */ + +#include "dlt.h" +#include "dlt_common.h" /* for dlt_get_version() */ + +int dlt_user_injection_callback(uint32_t service_id, void *data, uint32_t length); + +DltContext mycontext; +DltContextData mycontextdata; + +/** + * Print usage information of tool. + */ +void usage() +{ + char version[255]; + + dlt_get_version(version); + + printf("Usage: dlt-example-user-func [options] message\n"); + printf("Generate DLT messages and store them to file or send them to daemon.\n"); + printf("%s \n", version); + printf("Options:\n"); + printf(" -v Verbose mode\n"); + printf(" -d delay Milliseconds to wait between sending messages (Default: 500)\n"); + printf(" -f filename Use local log file instead of sending to daemon\n"); + printf(" -n count Number of messages to be generated (Default: 10)\n"); + printf(" -g Switch to non-verbose mode (Default: verbose mode)\n"); + printf(" -a Enable local printing of DLT messages (Default: disabled)\n"); +} + +/** + * Main function of tool. + */ +int main(int argc, char* argv[]) +{ + int vflag = 0; + int gflag = 0; + int aflag = 0; + char *dvalue = 0; + char *fvalue = 0; + char *nvalue = 0; + char *message = 0; + + int index; + int c; + char *text; + int num,maxnum; + int delay; + + opterr = 0; + + while ((c = getopt (argc, argv, "vgad:f:n:")) != -1) + { + switch (c) + { + case 'v': + { + vflag = 1; + break; + } + case 'g': + { + gflag = 1; + break; + } + case 'a': + { + aflag = 1; + break; + } + case 'd': + { + dvalue = optarg; + break; + } + case 'f': + { + fvalue = optarg; + break; + } + case 'n': + { + nvalue = optarg; + break; + } + case '?': + { + if (optopt == 'd' || optopt == 'f' || optopt == 'n') + { + fprintf (stderr, "Option -%c requires an argument.\n", optopt); + } + else if (isprint (optopt)) + { + fprintf (stderr, "Unknown option `-%c'.\n", optopt); + } + else + { + fprintf (stderr, "Unknown option character `\\x%x'.\n",optopt); + } + + /* unknown or wrong option used, show usage information and terminate */ + usage(); + return -1; + } + default: + { + abort (); + } + } + } + + for (index = optind; index < argc; index++) + { + message = argv[index]; + } + + if (message == 0) + { + /* no message, show usage and terminate */ + fprintf(stderr,"ERROR: No message selected\n"); + usage(); + return -1; + } + + if (fvalue) + { + /* DLT is intialised automatically, except another output target will be used */ + if (dlt_init_file(fvalue)<0) /* log to file */ + { + return -1; + } + } + + dlt_register_app("LOG","Test Application for Logging"); + + dlt_register_context(&mycontext,"TEST","Test Context for Logging"); + + dlt_register_injection_callback(&mycontext, 0xFFF, dlt_user_injection_callback); + + text = message; + + if (gflag) + { + dlt_nonverbose_mode(); + } + + if (aflag) + { + dlt_enable_local_print(); + } + + if (nvalue) + { + maxnum = atoi(nvalue); + } + else + { + maxnum = 10; + } + + if (dvalue) + { + delay = atoi(dvalue) * 1000; + } + else + { + delay = 500 * 1000; + } + + if (gflag) + { + /* DLT messages to test Fibex non-verbose description: dlt-example-non-verbose.xml */ + if (dlt_user_log_write_start_id(&mycontext,&mycontextdata,DLT_LOG_INFO,10)) + { + dlt_user_log_write_finish(&mycontextdata); + } + if (dlt_user_log_write_start_id(&mycontext,&mycontextdata,DLT_LOG_INFO,11)) + { + dlt_user_log_write_uint16(&mycontextdata,1011); + dlt_user_log_write_finish(&mycontextdata); + } + if (dlt_user_log_write_start_id(&mycontext,&mycontextdata,DLT_LOG_INFO,12)) + { + dlt_user_log_write_uint32(&mycontextdata,1012); + dlt_user_log_write_uint32(&mycontextdata,1013); + dlt_user_log_write_finish(&mycontextdata); + } + if (dlt_user_log_write_start_id(&mycontext,&mycontextdata,DLT_LOG_INFO,13)) + { + dlt_user_log_write_uint8(&mycontextdata,123); + dlt_user_log_write_float32(&mycontextdata,1.12); + dlt_user_log_write_finish(&mycontextdata); + } + if (dlt_user_log_write_start_id(&mycontext,&mycontextdata,DLT_LOG_INFO,14)) + { + dlt_user_log_write_string(&mycontextdata,"DEAD BEEF"); + dlt_user_log_write_finish(&mycontextdata); + } + } + + for (num=0;num<maxnum;num++) + { + printf("Send %d %s\n",num,text); + + if (gflag) + { + /* Non-verbose mode */ + if (dlt_user_log_write_start_id(&mycontext,&mycontextdata,DLT_LOG_WARN,num)) + { + dlt_user_log_write_int(&mycontextdata,num); + dlt_user_log_write_string(&mycontextdata,text); + dlt_user_log_write_finish(&mycontextdata); + } + } + else + { + /* Verbose mode */ + if (dlt_user_log_write_start(&mycontext,&mycontextdata,DLT_LOG_WARN)) + { + dlt_user_log_write_int(&mycontextdata,num); + dlt_user_log_write_string(&mycontextdata,text); + dlt_user_log_write_finish(&mycontextdata); + } + } + + if (delay>0) + { + usleep(delay); + } + } + + dlt_unregister_context(&mycontext); + + dlt_unregister_app(); + + dlt_free(); + + return 0; +} + +int dlt_user_injection_callback(uint32_t service_id, void *data, uint32_t length) +{ + char text[1024]; + + printf("Injection %d, Length=%d \n",service_id,length); + if (length>0) + { + dlt_print_mixed_string(text,1024,data,length,0); + printf("%s \n", text); + } + + return 0; +} diff --git a/src/examples/dlt-example-user.c b/src/examples/dlt-example-user.c new file mode 100755 index 0000000..98d4e3a --- /dev/null +++ b/src/examples/dlt-example-user.c @@ -0,0 +1,312 @@ +/* + * Dlt Client console utilities - Diagnostic Log and Trace + * @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-example-user.c ** +** ** +** TARGET : linux ** +** ** +** PROJECT : DLT ** +** ** +** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** +** Markus Klein ** +** ** +** PURPOSE : ** +** ** +** REMARKS : ** +** ** +** PLATFORM DEPENDANT [yes/no]: yes ** +** ** +** TO BE CHANGED BY USER [yes/no]: no ** +** ** +*******************************************************************************/ + +/******************************************************************************* +** Author Identity ** +******************************************************************************** +** ** +** Initials Name Company ** +** -------- ------------------------- ---------------------------------- ** +** aw Alexander Wenzel BMW ** +** mk Markus Klein Fraunhofer ESK ** +*******************************************************************************/ + +/******************************************************************************* +** Revision Control History ** +*******************************************************************************/ + +/* + * $LastChangedRevision: 1670 $ + * $LastChangedDate: 2011-04-08 15:12:06 +0200 (Fr, 08. Apr 2011) $ + * $LastChangedBy$ + Initials Date Comment + aw 13.01.2010 initial + */ +#include <netdb.h> +#include <ctype.h> +#include <stdio.h> /* for printf() and fprintf() */ +#include <stdlib.h> /* for atoi() and exit() */ +#include <string.h> /* for memset() */ +#include <unistd.h> /* for close() */ + +#include "dlt.h" +#include "dlt_common.h" /* for dlt_get_version() */ + +int dlt_user_injection_callback(uint32_t service_id, void *data, uint32_t length); + +DLT_DECLARE_CONTEXT(mycontext); + +/** + * Print usage information of tool. + */ +void usage() +{ + char version[255]; + + dlt_get_version(version); + + printf("Usage: dlt-example-user [options] message\n"); + printf("Generate DLT messages and store them to file or send them to daemon.\n"); + printf("%s \n", version); + printf("Options:\n"); + printf(" -v Verbose mode\n"); + printf(" -d delay Milliseconds to wait between sending messages (Default: 500)\n"); + printf(" -f filename Use local log file instead of sending to daemon\n"); + printf(" -n count Number of messages to be generated (Default: 10)\n"); + printf(" -g Switch to non-verbose mode (Default: verbose mode)\n"); + printf(" -a Enable local printing of DLT messages (Default: disabled)\n"); +} + +/** + * Main function of tool. + */ +int main(int argc, char* argv[]) +{ + int vflag = 0; + int gflag = 0; + int aflag = 0; + char *dvalue = 0; + char *fvalue = 0; + char *nvalue = 0; + char *message = 0; + + int index; + int c; + + char *text; + int num,maxnum; + int delay; + + opterr = 0; + + while ((c = getopt (argc, argv, "vgad:f:n:")) != -1) + { + switch (c) + { + case 'v': + { + vflag = 1; + break; + } + case 'g': + { + gflag = 1; + break; + } + case 'a': + { + aflag = 1; + break; + } + case 'd': + { + dvalue = optarg; + break; + } + case 'f': + { + fvalue = optarg; + break; + } + case 'n': + { + nvalue = optarg; + break; + } + case '?': + { + if (optopt == 'd' || optopt == 'f' || optopt == 'n') + { + fprintf (stderr, "Option -%c requires an argument.\n", optopt); + } + else if (isprint (optopt)) + { + fprintf (stderr, "Unknown option `-%c'.\n", optopt); + } + else + { + fprintf (stderr, "Unknown option character `\\x%x'.\n",optopt); + } + + /* unknown or wrong option used, show usage information and terminate */ + usage(); + return -1; + } + default: + { + abort (); + } + } + } + + for (index = optind; index < argc; index++) + { + message = argv[index]; + } + + if (message == 0) + { + /* no message, show usage and terminate */ + fprintf(stderr,"ERROR: No message selected\n"); + usage(); + return -1; + } + + if (fvalue) + { + /* DLT is intialised automatically, except another output target will be used */ + if (dlt_init_file(fvalue)<0) /* log to file */ + { + return -1; + } + } + + DLT_REGISTER_APP("LOG","Test Application for Logging"); + DLT_REGISTER_CONTEXT(mycontext,"TEST","Test Context for Logging"); + + DLT_REGISTER_INJECTION_CALLBACK(mycontext, 0xFFF, dlt_user_injection_callback); + + text = message; + + if (gflag) + { + DLT_NONVERBOSE_MODE(); + } + + if (aflag) + { + DLT_ENABLE_LOCAL_PRINT(); + } + + if (nvalue) + { + maxnum = atoi(nvalue); + } + else + { + maxnum = 10; + } + + if (dvalue) + { + delay = atoi(dvalue) * 1000; + } + else + { + delay = 500 * 1000; + } + + if (gflag) + { + /* DLT messages to test Fibex non-verbose description: dlt-example-non-verbose.xml */ + DLT_LOG_ID(mycontext,DLT_LOG_INFO,10); + DLT_LOG_ID(mycontext,DLT_LOG_INFO,11,DLT_UINT16(1011)); + DLT_LOG_ID(mycontext,DLT_LOG_INFO,12,DLT_UINT32(1012),DLT_UINT32(1013)); + DLT_LOG_ID(mycontext,DLT_LOG_INFO,13,DLT_UINT8(123),DLT_FLOAT32(1.12)); + DLT_LOG_ID(mycontext,DLT_LOG_INFO,14,DLT_STRING("DEAD BEEF")); + } + + for (num=0;num<maxnum;num++) + { + printf("Send %d %s\n",num,text); + + + if (gflag) + { + /* Non-verbose mode */ + DLT_LOG_ID(mycontext,DLT_LOG_WARN,num,DLT_INT(num),DLT_STRING(text)); + } + else + { + /* Verbose mode */ + DLT_LOG(mycontext,DLT_LOG_WARN,DLT_INT(num),DLT_STRING(text)); + } + + if (delay>0) + { + usleep(delay); + } + } + + sleep(1); + + DLT_UNREGISTER_CONTEXT(mycontext); + + DLT_UNREGISTER_APP(); + + dlt_free(); + + return 0; + +} + +int dlt_user_injection_callback(uint32_t service_id, void *data, uint32_t length) +{ + char text[1024]; + + printf("Injection %d, Length=%d \n",service_id,length); + if (length>0) + { + dlt_print_mixed_string(text,1024,data,length,0); + printf("%s \n", text); + } + + return 0; +} + diff --git a/src/examples/wintestclient/ReadMe.txt b/src/examples/wintestclient/ReadMe.txt new file mode 100755 index 0000000..07566bd --- /dev/null +++ b/src/examples/wintestclient/ReadMe.txt @@ -0,0 +1,36 @@ +========================================================================
+ KONSOLENANWENDUNG: wintestclient-Projektübersicht
+========================================================================
+
+Diese wintestclient-Anwendung wurde vom Anwendungs-Assistenten
+für Sie erstellt.
+
+Die Datei enthält eine Zusammenfassung des Inhalts der Dateien,
+aus denen die wintestclient-Anwendung besteht.
+
+
+wintestclient.vcproj
+ Dies ist die Hauptprojektdatei für VC++-Projekte, die mit dem Anwendungs-
+ Assistenten generiert werden.
+ Sie enthält Informationen zu der Version von Visual C++, mit der die Datei
+ generiert wurde, sowie Informationen zu Plattformen, Konfigurationen und
+ Projektfeatures, die mit dem dem Anwendungs-Assistenten generiert werden.
+
+wintestclient.cpp
+ Dies ist die Hauptquelldatei der Anwendung.
+
+/////////////////////////////////////////////////////////////////////////////
+Andere Standarddateien:
+
+StdAfx.h, StdAfx.cpp
+ Mit diesen Dateien werden eine vorkompilierte Headerdatei (PCH)
+ mit dem Namen wintestclient.pch sowie eine vorkompilierte
+ Typendatei mit dem Namen StdAfx.obj erstellt.
+
+/////////////////////////////////////////////////////////////////////////////
+Weitere Hinweise:
+
+Der Anwendungs-Assistent verwendet "TODO:"-Kommentare, um die Teile des
+Quellcodes anzugeben, die hinzugefügt oder bearbeitet werden müssen.
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/src/examples/wintestclient/stdafx.cpp b/src/examples/wintestclient/stdafx.cpp new file mode 100755 index 0000000..859a62f --- /dev/null +++ b/src/examples/wintestclient/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : Quelldatei, die nur die Standard-Includes einbindet.
+// wintestclient.pch ist der vorkompilierte Header.
+// stdafx.obj enthält die vorkompilierten Typinformationen.
+
+#include "stdafx.h"
+
+// TODO: Auf zusätzliche Header verweisen, die in STDAFX.H
+// und nicht in dieser Datei erforderlich sind.
diff --git a/src/examples/wintestclient/stdafx.h b/src/examples/wintestclient/stdafx.h new file mode 100755 index 0000000..c2580d9 --- /dev/null +++ b/src/examples/wintestclient/stdafx.h @@ -0,0 +1,15 @@ +// stdafx.h : Includedatei für Standardsystem-Includedateien
+// oder häufig verwendete projektspezifische Includedateien,
+// die nur in unregelmäßigen Abständen geändert werden.
+//
+
+#pragma once
+
+#include "targetver.h"
+
+#include <stdio.h>
+#include <tchar.h>
+
+
+
+// TODO: Hier auf zusätzliche Header, die das Programm erfordert, verweisen.
diff --git a/src/examples/wintestclient/targetver.h b/src/examples/wintestclient/targetver.h new file mode 100755 index 0000000..abf0fc6 --- /dev/null +++ b/src/examples/wintestclient/targetver.h @@ -0,0 +1,13 @@ +#pragma once
+
+// Die folgenden Makros definieren die mindestens erforderliche Plattform. Die mindestens erforderliche Plattform
+// ist die früheste Windows-, Internet Explorer-Version usw., die über die erforderlichen Features zur Ausführung
+// Ihrer Anwendung verfügt. Die Makros aktivieren alle Funktionen, die auf den Plattformversionen bis
+// einschließlich der angegebenen Version verfügbar sind.
+
+// Ändern Sie folgende Definitionen für Plattformen, die älter als die unten angegebenen sind.
+// Unter MSDN finden Sie die neuesten Informationen über die entsprechenden Werte für die unterschiedlichen Plattformen.
+#ifndef _WIN32_WINNT // Gibt an, dass Windows Vista die mindestens erforderliche Plattform ist.
+#define _WIN32_WINNT 0x0600 // Ändern Sie den entsprechenden Wert, um auf andere Versionen von Windows abzuzielen.
+#endif
+
diff --git a/src/examples/wintestclient/wintestclient.cpp b/src/examples/wintestclient/wintestclient.cpp new file mode 100755 index 0000000..78225b2 --- /dev/null +++ b/src/examples/wintestclient/wintestclient.cpp @@ -0,0 +1,65 @@ +/******************************************************************************* +** ** +** SRC-MODULE: wintestclient.cpp ** +** ** +** TARGET : Windows ** +** ** +** PROJECT : DLT ** +** ** +** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** +** Markus Klein ** +** ** +** PURPOSE : ** +** ** +** REMARKS : ** +** ** +** PLATFORM DEPENDANT [yes/no]: yes ** +** ** +** TO BE CHANGED BY USER [yes/no]: no ** +** ** +*******************************************************************************/ + +/******************************************************************************* +** Author Identity ** +******************************************************************************** +** ** +** Initials Name Company ** +** -------- ------------------------- ---------------------------------- ** +** aw Alexander Wenzel BMW ** +** mk Markus Klein Fraunhofer ESK ** +*******************************************************************************/ +
+#include "stdafx.h"
+#include "winclientlib.h"
+
+#include <string.h>
+
+static int counter=0;
+
+int My_message_Callback(DltMessage *message, void *data)
+{
+ counter++;
+
+ printf("Message received, %d\n", counter);
+ return 0;
+}
+
+int _tmain(int argc, _TCHAR* argv[])
+{
+ char text[] = "Hello from WinTestClient";
+
+ printf("WinTestClient\n");
+
+ Dlt_RegisterMessageCallback(My_message_Callback);
+
+ Dlt_StartClient("192.168.56.101");
+
+ Dlt_InjectCall("LOG","TEST",0xFFF,(uint8_t*)text,strlen(text)+1);
+
+ getchar();
+
+ Dlt_ExitClient();
+
+ return 0;
+}
+
diff --git a/src/examples/wintestclient/wintestclient.sln b/src/examples/wintestclient/wintestclient.sln new file mode 100755 index 0000000..a086994 --- /dev/null +++ b/src/examples/wintestclient/wintestclient.sln @@ -0,0 +1,29 @@ +
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual C++ Express 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wintestclient", "wintestclient.vcproj", "{C9C90C2B-DD7F-4EAD-B240-E35860756736}"
+ ProjectSection(ProjectDependencies) = postProject
+ {F3674DAE-F85A-428C-85FE-3529671DF6ED} = {F3674DAE-F85A-428C-85FE-3529671DF6ED}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "winclientlib", "..\..\winclientlib\winclientlib.vcproj", "{F3674DAE-F85A-428C-85FE-3529671DF6ED}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {C9C90C2B-DD7F-4EAD-B240-E35860756736}.Debug|Win32.ActiveCfg = Debug|Win32
+ {C9C90C2B-DD7F-4EAD-B240-E35860756736}.Debug|Win32.Build.0 = Debug|Win32
+ {C9C90C2B-DD7F-4EAD-B240-E35860756736}.Release|Win32.ActiveCfg = Release|Win32
+ {C9C90C2B-DD7F-4EAD-B240-E35860756736}.Release|Win32.Build.0 = Release|Win32
+ {F3674DAE-F85A-428C-85FE-3529671DF6ED}.Debug|Win32.ActiveCfg = Debug|Win32
+ {F3674DAE-F85A-428C-85FE-3529671DF6ED}.Debug|Win32.Build.0 = Debug|Win32
+ {F3674DAE-F85A-428C-85FE-3529671DF6ED}.Release|Win32.ActiveCfg = Release|Win32
+ {F3674DAE-F85A-428C-85FE-3529671DF6ED}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/src/examples/wintestclient/wintestclient.vcproj b/src/examples/wintestclient/wintestclient.vcproj new file mode 100755 index 0000000..c1f3f17 --- /dev/null +++ b/src/examples/wintestclient/wintestclient.vcproj @@ -0,0 +1,213 @@ +<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9,00"
+ Name="wintestclient"
+ ProjectGUID="{C9C90C2B-DD7F-4EAD-B240-E35860756736}"
+ RootNamespace="wintestclient"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="196613"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\..\..\include\dlt;..\..\include;..\..\winclientlib"
+ PreprocessorDefinitions="WIN32;__WIN32__;_DEBUG;_CONSOLE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="winclientlib.lib"
+ LinkIncremental="2"
+ AdditionalLibraryDirectories=".\Debug"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ AdditionalIncludeDirectories="..\..\..\include\dlt;..\..\include;..\..\winclientlib"
+ PreprocessorDefinitions="WIN32;__WIN32__;NDEBUG;_CONSOLE"
+ RuntimeLibrary="2"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Quelldateien"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\stdafx.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\wintestclient.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Headerdateien"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath=".\stdafx.h"
+ >
+ </File>
+ <File
+ RelativePath=".\targetver.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Ressourcendateien"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ <File
+ RelativePath=".\ReadMe.txt"
+ >
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt new file mode 100755 index 0000000..2ad8ce5 --- /dev/null +++ b/src/lib/CMakeLists.txt @@ -0,0 +1,53 @@ +####### +# Dlt - Diagnostic Log and Trace +# @licence make 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@ +######## + +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 ) + +add_library(dlt ${dlt_LIB_SRCS}) + +target_link_libraries(dlt rt ${CMAKE_THREAD_LIBS_INIT}) + +set_target_properties(dlt PROPERTIES VERSION 2.2.0 SOVERSION 2) + +install(TARGETS dlt + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib/static + COMPONENT base) + + + + diff --git a/src/lib/dlt_client.c b/src/lib/dlt_client.c new file mode 100755 index 0000000..87aa273 --- /dev/null +++ b/src/lib/dlt_client.c @@ -0,0 +1,452 @@ +/* + * Dlt- Diagnostic Log and Trace client 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_client.c ** +** ** +** TARGET : linux ** +** ** +** PROJECT : DLT ** +** ** +** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** +** Markus Klein ** +** ** +** PURPOSE : ** +** ** +** REMARKS : ** +** ** +** PLATFORM DEPENDANT [yes/no]: yes ** +** ** +** TO BE CHANGED BY USER [yes/no]: no ** +** ** +*******************************************************************************/ + +/******************************************************************************* +** Author Identity ** +******************************************************************************** +** ** +** Initials Name Company ** +** -------- ------------------------- ---------------------------------- ** +** aw Alexander Wenzel BMW ** +** mk Markus Klein Fraunhofer ESK ** +*******************************************************************************/ + +/******************************************************************************* +** Revision Control History ** +*******************************************************************************/ + +/* + * $LastChangedRevision$ + * $LastChangedDate$ + * $LastChangedBy$ + Initials Date Comment + aw 12.07.2010 initial + */ + +#include <stdio.h> + +#if defined (__WIN32__) || defined (_MSC_VER) +#pragma warning(disable : 4996) /* Switch off C4996 warnings */ +#include <winsock2.h> /* for socket(), connect(), send(), and recv() */ +#else +#include <sys/socket.h> /* for socket(), connect(), send(), and recv() */ +#include <arpa/inet.h> /* for sockaddr_in and inet_addr() */ +#include <netdb.h> +#include <sys/stat.h> +#endif + +#if defined(_MSC_VER) +#include <io.h> +#else +#include <unistd.h> +#include <syslog.h> +#endif + +#include <fcntl.h> + +#include <stdlib.h> /* for malloc(), free() */ +#include <string.h> /* for strlen(), memcmp(), memmove() */ +#include <errno.h> + +#include "dlt_types.h" +#include "dlt_client.h" +#include "dlt_client_cfg.h" + +static int (*message_callback_function) (DltMessage *message, void *data) = NULL; + +void dlt_client_register_message_callback(int (*registerd_callback) (DltMessage *message, void *data)){ + message_callback_function = registerd_callback; +} + +int dlt_client_init(DltClient *client, int verbose) +{ + if (client==0) + { + return -1; + } + + client->sock=-1; + client->servIP=0; + client->serialDevice=0; + client->baudrate=DLT_CLIENT_INITIAL_BAUDRATE; + client->serial_mode=0; + client->receiver.buffer=0; + + return 0; +} + +int dlt_client_connect(DltClient *client, int verbose) +{ + struct sockaddr_in servAddr; + unsigned short servPort = DLT_DAEMON_TCP_PORT; + struct hostent *host; /* Structure containing host information */ + + if (client==0) + { + return -1; + } + + if (client->serial_mode==0) + { + /* open socket */ + if ((client->sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) + { + fprintf(stderr,"ERROR: socket() failed!\n"); + return -1; + } + + if ((host = (struct hostent*) gethostbyname(client->servIP)) == 0) + { + fprintf(stderr, "ERROR: gethostbyname() failed\n"); + return -1; + } + + memset(&servAddr, 0, sizeof(servAddr)); + servAddr.sin_family = AF_INET; + servAddr.sin_addr.s_addr = inet_addr(inet_ntoa(*( struct in_addr*)( host -> h_addr_list[0]))); + servAddr.sin_port = htons(servPort); + + if (connect(client->sock, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0) + { + fprintf(stderr,"ERROR: connect() failed!\n"); + return -1; + } + + if (verbose) + { + printf("Connected to DLT daemon (%s)\n",client->servIP); + } + } + else + { + /* open serial connection */ + client->sock=open(client->serialDevice,O_RDWR); + if (client->sock<0) + { + fprintf(stderr,"ERROR: Failed to open device %s\n", client->serialDevice); + return -1; + } + + if (isatty(client->sock)) + { + #if !defined (__WIN32__) + if (dlt_setup_serial(client->sock,client->baudrate)<0) + { + fprintf(stderr,"ERROR: Failed to configure serial device %s (%s) \n", client->serialDevice, strerror(errno)); + return -1; + } + #else + return -1; + #endif + } + else + { + if (verbose) + { + fprintf(stderr,"ERROR: Device is not a serial device, device = %s (%s) \n", client->serialDevice, strerror(errno)); + } + return -1; + } + + if (verbose) + { + printf("Connected to %s\n", client->serialDevice); + } + } + + if (dlt_receiver_init(&(client->receiver),client->sock,DLT_CLIENT_RCVBUFSIZE)!=0) + { + return -1; + } + + return 0; +} + +int dlt_client_cleanup(DltClient *client, int verbose) +{ + if (client==0) + { + return -1; + } + + if (client->sock!=-1) + { + close(client->sock); + } + + if (dlt_receiver_free(&(client->receiver))==-1) + { + return -1; + } + + return 0; +} + +int dlt_client_main_loop(DltClient *client, void *data, int verbose) +{ + DltMessage msg; + int ret; + + if (client==0) + { + return -1; + } + + if (dlt_message_init(&msg,verbose)==-1) + { + return -1; + } + + while (1) + { + if (client->serial_mode==0) + { + /* wait for data from socket */ + ret = dlt_receiver_receive_socket(&(client->receiver)); + } + else + { + /* wait for data from serial connection */ + ret = dlt_receiver_receive_fd(&(client->receiver)); + } + + if (ret<=0) + { + /* No more data to be received */ + if (dlt_message_free(&msg,verbose)==-1) + { + return -1; + } + + return 1; + } + + while (dlt_message_read(&msg,(unsigned char*)(client->receiver.buf),client->receiver.bytesRcvd,0,verbose)==0) + { + /* Call callback function */ + if (message_callback_function) + { + (*message_callback_function)(&msg,data); + } + + if (msg.found_serialheader) + { + if (dlt_receiver_remove(&(client->receiver),msg.headersize+msg.datasize-sizeof(DltStorageHeader)+sizeof(dltSerialHeader))==-1) + { + /* Return value ignored */ + dlt_message_free(&msg,verbose); + return -1; + } + } + else + { + if (dlt_receiver_remove(&(client->receiver),msg.headersize+msg.datasize-sizeof(DltStorageHeader))==-1) + { + /* Return value ignored */ + dlt_message_free(&msg,verbose); + return -1; + } + } + } + + if (dlt_receiver_move_to_begin(&(client->receiver))==-1) + { + /* Return value ignored */ + dlt_message_free(&msg,verbose); + return -1; + } + } + + if (dlt_message_free(&msg,verbose)==-1) + { + return -1; + } + + return 0; +} + +int dlt_client_send_inject_msg(DltClient *client, char *apid, char *ctid, uint32_t serviceID, uint8_t *buffer, uint32_t size) +{ + DltMessage msg; + int ret; + int offset=0; + + int32_t len; + + if ((client==0) || (client->sock<0) || (apid==0) || (ctid==0) || (buffer==0) || (size==0) || + (serviceID<DLT_SERVICE_ID_CALLSW_CINJECTION)) + { + return -1; + } + + /* initialise new message */ + if (dlt_message_init(&msg,0)==-1) + { + return -1; + } + + /* prepare payload of data */ + msg.datasize = sizeof(uint32_t) + sizeof(uint32_t) + size; + if (msg.databuffer) + { + free(msg.databuffer); + } + msg.databuffer = (uint8_t *) malloc(msg.datasize); + + memcpy(msg.databuffer , &serviceID,sizeof(serviceID)); + offset+=sizeof(uint32_t); + memcpy(msg.databuffer+offset, &size, sizeof(size)); + offset+=sizeof(uint32_t); + memcpy(msg.databuffer+offset, buffer, size); + + /* prepare storage header */ + msg.storageheader = (DltStorageHeader*)msg.headerbuffer; + + if (dlt_set_storageheader(msg.storageheader,"")==-1) + { + dlt_message_free(&msg,0); + return -1; + } + + /* prepare standard header */ + msg.standardheader = (DltStandardHeader*)(msg.headerbuffer + sizeof(DltStorageHeader)); + msg.standardheader->htyp = DLT_HTYP_WEID | DLT_HTYP_WTMS | DLT_HTYP_UEH | DLT_HTYP_PROTOCOL_VERSION1 ; + + #if (BYTE_ORDER==BIG_ENDIAN) + msg.standardheader->htyp = (msg.standardheader->htyp | DLT_HTYP_MSBF); + #endif + + msg.standardheader->mcnt = 0; + + /* Set header extra parameters */ + dlt_set_id(msg.headerextra.ecu,""); + //msg.headerextra.seid = 0; + msg.headerextra.tmsp = dlt_uptime(); + + /* Copy header extra parameters to headerbuffer */ + if (dlt_message_set_extraparameters(&msg,0)==-1) + { + dlt_message_free(&msg,0); + return -1; + } + + /* prepare extended header */ + msg.extendedheader = (DltExtendedHeader*)(msg.headerbuffer + + sizeof(DltStorageHeader) + + sizeof(DltStandardHeader) + + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp) ); + + msg.extendedheader->msin = DLT_MSIN_CONTROL_REQUEST; + + msg.extendedheader->noar = 1; /* number of arguments */ + + dlt_set_id(msg.extendedheader->apid,(apid[0]=='\0')?DLT_CLIENT_DUMMY_APP_ID:apid); + dlt_set_id(msg.extendedheader->ctid,(ctid[0]=='\0')?DLT_CLIENT_DUMMY_CON_ID:ctid); + + /* prepare length information */ + msg.headersize = sizeof(DltStorageHeader) + + sizeof(DltStandardHeader) + + sizeof(DltExtendedHeader) + + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp); + + len=msg.headersize - sizeof(DltStorageHeader) + msg.datasize; + if (len>UINT16_MAX) + { + fprintf(stderr,"Critical: Huge injection message discarded!\n"); + dlt_message_free(&msg,0); + + return -1; + } + + msg.standardheader->len = DLT_HTOBE_16(len); + + /* Send data (without storage header) */ + if (client->serial_mode) + { + /* via FileDescriptor */ + ret=write(client->sock, msg.headerbuffer+sizeof(DltStorageHeader),msg.headersize-sizeof(DltStorageHeader)); + ret=write(client->sock, msg.databuffer,msg.datasize); + } + else + { + /* via Socket */ + send(client->sock, (const char *)(msg.headerbuffer+sizeof(DltStorageHeader)),msg.headersize-sizeof(DltStorageHeader),0); + send(client->sock, (const char *)msg.databuffer,msg.datasize,0); + } + + /* free message */ + if (dlt_message_free(&msg,0)==-1) + { + return -1; + } + + return 0; +} + +int dlt_client_setbaudrate(DltClient *client, int baudrate) +{ + if (client==0) + { + return -1; + } + + client->baudrate = dlt_convert_serial_speed(baudrate); + + return 0; +} + diff --git a/src/lib/dlt_client_cfg.h b/src/lib/dlt_client_cfg.h new file mode 100755 index 0000000..52182b3 --- /dev/null +++ b/src/lib/dlt_client_cfg.h @@ -0,0 +1,110 @@ +/*
+ * Dlt- Diagnostic Log and Trace daemon
+ * @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_client_cfg.h **
+** **
+** TARGET : linux **
+** **
+** PROJECT : DLT **
+** **
+** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de **
+** Markus Klein **
+** **
+** PURPOSE : **
+** **
+** REMARKS : **
+** **
+** PLATFORM DEPENDANT [yes/no]: yes **
+** **
+** TO BE CHANGED BY USER [yes/no]: no **
+** **
+*******************************************************************************/
+
+/*******************************************************************************
+** Author Identity **
+********************************************************************************
+** **
+** Initials Name Company **
+** -------- ------------------------- ---------------------------------- **
+** aw Alexander Wenzel BMW **
+** mk Markus Klein Fraunhofer ESK **
+*******************************************************************************/
+
+/*******************************************************************************
+** Author Identity **
+********************************************************************************
+** **
+** Initials Name Company **
+** -------- ------------------------- ---------------------------------- **
+** aw Alexander Wenzel BMW **
+** mk Markus Klein Fraunhofer ESK **
+*******************************************************************************/
+
+#ifndef DLT_CLIENT_CFG_H
+#define DLT_CLIENT_CFG_H
+
+/*************/
+/* Changable */
+/*************/
+ +/* Dummy application id of DLT client */
+#define DLT_CLIENT_DUMMY_APP_ID "CA1" + +/* Dummy context id of DLT client */ +#define DLT_CLIENT_DUMMY_CON_ID "CC1" + +/* Size of buffer */ +#define DLT_CLIENT_TEXTBUFSIZE 512 + +/* Size of receive buffer */ +#define DLT_CLIENT_RCVBUFSIZE 10024 + +/* Initial baudrate */ +#if !defined (__WIN32__) && !defined(_MSC_VER) +#define DLT_CLIENT_INITIAL_BAUDRATE B115200 +#else +#define DLT_CLIENT_INITIAL_BAUDRATE 0 +#endif
+
+/************************/
+/* Don't change please! */
+/************************/
+
+#endif /* DLT_CLIENT_CFG_H */
diff --git a/src/lib/dlt_user.c b/src/lib/dlt_user.c new file mode 100755 index 0000000..c1bcba4 --- /dev/null +++ b/src/lib/dlt_user.c @@ -0,0 +1,2776 @@ +/* +* 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_user.c ** +** ** +** TARGET : linux ** +** ** +** PROJECT : DLT ** +** ** +** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** +** Markus Klein ** +** ** +** PURPOSE : ** +** ** +** REMARKS : ** +** ** +** PLATFORM DEPENDANT [yes/no]: yes ** +** ** +** TO BE CHANGED BY USER [yes/no]: no ** +** ** +*******************************************************************************/ + +/******************************************************************************* +** Author Identity ** +******************************************************************************** +** ** +** Initials Name Company ** +** -------- ------------------------- ---------------------------------- ** +** aw Alexander Wenzel BMW ** +** mk Markus Klein Fraunhofer ESK ** +*******************************************************************************/ + +/******************************************************************************* +** Revision Control History ** +*******************************************************************************/ + +/* + * $LastChangedRevision: 1670 $ + * $LastChangedDate: 2011-04-08 15:12:06 +0200 (Fr, 08. Apr 2011) $ + * $LastChangedBy$ + Initials Date Comment + aw 13.01.2010 initial + */ + +#include <stdlib.h> /* for getenv(), free(), atexit() */ +#include <string.h> /* for strcmp(), strncmp(), strlen(), memset(), memcpy() */ +#include <signal.h> /* for signal(), SIGPIPE, SIG_IGN */ + +#if !defined (__WIN32__) +#include <syslog.h> /* for LOG_... */ +#include <semaphore.h> +#include <pthread.h> /* POSIX Threads */ +#endif + +#include <sys/stat.h> +#include <fcntl.h> +#include <errno.h> + +#include <sys/uio.h> /* writev() */ + +#include "dlt_user.h" +#include "dlt_user_shared.h" +#include "dlt_user_shared_cfg.h" +#include "dlt_user_cfg.h" + +static DltUser dlt_user; +static int dlt_user_initialised = 0; + +static char str[DLT_USER_BUFFER_LENGTH]; +static char text[DLT_USER_TEXT_LENGTH]; + +static sem_t dlt_mutex; +static pthread_t dlt_receiverthread_handle; +static pthread_attr_t dlt_receiverthread_attr; + +/* Function prototypes for internally used functions */ +static void dlt_user_receiverthread_function(void *ptr); +static void dlt_user_atexit_handler(void); +static int dlt_user_log_init(DltContext *handle, DltContextData *log); +static int dlt_user_log_send_log(DltContextData *log, int mtype); +static int dlt_user_log_send_register_application(void); +static int dlt_user_log_send_unregister_application(void); +static int dlt_user_log_send_register_context(DltContextData *log); +static int dlt_user_log_send_unregister_context(DltContextData *log); +static int dlt_send_app_ll_ts_limit(const char *appid, DltLogLevelType loglevel, DltTraceStatusType tracestatus); +static int dlt_user_print_msg(DltMessage *msg, DltContextData *log); +static int dlt_user_log_check_user_message(void); +static void dlt_user_log_reattach_to_daemon(void); +static int dlt_user_log_send_overflow(void); + +int dlt_init(void) +{ + char filename[DLT_USER_MAX_FILENAME_LENGTH]; + int ret; + + dlt_user_initialised = 1; + + /* Initialize common part of dlt_init()/dlt_init_file() */ + if (dlt_init_common()==-1) + { + dlt_user_initialised = 0; + return -1; + } + + dlt_user.dlt_is_file = 0; + dlt_user.overflow = 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); + + ret=mkfifo(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH ); + if (ret==-1) + { + sprintf(str,"Loging disabled, FIFO user %s cannot be created!\n",filename); + dlt_log(LOG_WARNING, str); + /* return 0; */ /* removed to prevent error, when FIFO already exists */ + } + + dlt_user.dlt_user_handle = open(filename, O_RDWR); + if (dlt_user.dlt_user_handle == -1) + { + sprintf(str,"Loging disabled, FIFO user %s cannot be opened!\n",filename); + dlt_log(LOG_WARNING, str); + unlink(filename); + return 0; + } + + /* open DLT output FIFO */ + dlt_user.dlt_log_handle = open(DLT_USER_FIFO, O_WRONLY | O_NONBLOCK); + if (dlt_user.dlt_log_handle==-1) + { + sprintf(str,"Loging disabled, FIFO %s cannot be opened with open()!\n",DLT_USER_FIFO); + dlt_log(LOG_WARNING, str); + return 0; + } + + if (dlt_receiver_init(&(dlt_user.receiver),dlt_user.dlt_user_handle, DLT_USER_RCVBUF_MAX_SIZE)==-1) + { + dlt_user_initialised = 0; + return -1; + } + + /* Set default thread stack size */ + if (pthread_attr_init(&dlt_receiverthread_attr)<0) + { + 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), + &dlt_receiverthread_attr, + (void *) &dlt_user_receiverthread_function, + 0)!=0) + { + if (pthread_attr_destroy(&dlt_receiverthread_attr)!=0) + { + dlt_log(LOG_WARNING, "Can't destroy thread attributes!\n"); + } + + dlt_log(LOG_CRIT, "Can't create receiver thread!\n"); + dlt_user_initialised = 0; + return -1; + } + + if (pthread_attr_destroy(&dlt_receiverthread_attr)!=0) + { + dlt_log(LOG_WARNING, "Can't destroy thread attributes!\n"); + } + + return 0; +} + +int dlt_init_file(const char *name) +{ + dlt_user_initialised = 1; + + /* Initialize common part of dlt_init()/dlt_init_file() */ + if (dlt_init_common()==-1) + { + dlt_user_initialised = 0; + return -1; + } + + dlt_user.dlt_is_file = 1; + + /* open DLT output file */ + dlt_user.dlt_log_handle = open(name,O_WRONLY|O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); /* mode: wb */ + if (dlt_user.dlt_log_handle == -1) + { + sprintf(str,"Log file %s cannot be opened!\n",name); + dlt_log(LOG_ERR, str); + return -1; + } + + return 0; +} + +int dlt_init_common(void) +{ + char *env_local_print; + + /* Binary semaphore for threads */ + if (sem_init(&dlt_mutex, 0, 1)==-1) + { + dlt_user_initialised = 0; + return -1; + } + + dlt_user.dlt_log_handle=-1; + dlt_user.dlt_user_handle=-1; + + dlt_set_id(dlt_user.ecuID,DLT_USER_DEFAULT_ECU_ID); + dlt_set_id(dlt_user.appID,""); + + dlt_user.application_description = 0; + + /* Verbose mode is enabled by default */ + dlt_user.verbose_mode = 1; + + /* Local print is disabled by default */ + dlt_user.enable_local_print = 0; + + dlt_user.local_print_mode = DLT_PM_UNSET; + + env_local_print = getenv(DLT_USER_ENV_LOCAL_PRINT_MODE); + if (env_local_print) + { + if (strcmp(env_local_print,"AUTOMATIC")==0) + { + dlt_user.local_print_mode = DLT_PM_AUTOMATIC; + } + else if (strcmp(env_local_print,"FORCE_ON")==0) + { + dlt_user.local_print_mode = DLT_PM_FORCE_ON; + } + else if (strcmp(env_local_print,"FORCE_OFF")==0) + { + dlt_user.local_print_mode = DLT_PM_FORCE_OFF; + } + } + + /* Initialize LogLevel/TraceStatus field */ + dlt_user.dlt_ll_ts = 0; + 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); + + return 0; +} + +void dlt_user_atexit_handler(void) +{ + /* Unregister app (this also unregisters all contexts in daemon) */ + /* Ignore return value */ + dlt_unregister_app(); + + /* Cleanup */ + /* Ignore return value */ + dlt_free(); +} + +int dlt_free(void) +{ + int i; + char filename[DLT_USER_MAX_FILENAME_LENGTH]; + + if (dlt_user_initialised==0) + { + return -1; + } + + if (dlt_receiverthread_handle) + { + /* Ignore return value */ + pthread_cancel(dlt_receiverthread_handle); + } + + if (dlt_user.dlt_user_handle!=-1) + { + sprintf(filename,"/tmp/dlt%d",getpid()); + + close(dlt_user.dlt_user_handle); + dlt_user.dlt_user_handle=-1; + + unlink(filename); + } + + if (dlt_user.dlt_log_handle!=-1) + { + /* close log file/output fifo to daemon */ + close(dlt_user.dlt_log_handle); + dlt_user.dlt_log_handle = -1; + } + + /* 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++) + { + if (dlt_user.dlt_ll_ts[i].injection_table!=0) + { + free(dlt_user.dlt_ll_ts[i].injection_table); + dlt_user.dlt_ll_ts[i].injection_table = 0; + } + dlt_user.dlt_ll_ts[i].nrcallbacks = 0; + } + + free(dlt_user.dlt_ll_ts); + dlt_user.dlt_ll_ts = 0; + dlt_user.dlt_ll_ts_max_num_entries = 0; + dlt_user.dlt_ll_ts_num_entries = 0; + } + + dlt_user_initialised = 0; + + return 0; +} + + + +int dlt_register_app(const char *appid, const char * description) +{ + int ret; + + if (dlt_user_initialised==0) + { + if (dlt_init()<0) + { + return -1; + } + } + + if ((appid==0) || (appid[0]=='\0')) + { + return -1; + } + + DLT_SEM_LOCK(); + + /* Store locally application id and application description */ + dlt_set_id(dlt_user.appID, appid); + + if (dlt_user.application_description!=0) + { + free(dlt_user.application_description); + } + + dlt_user.application_description = 0; + + if (description!=0) + { + dlt_user.application_description= malloc(strlen(description)+1); + strncpy(dlt_user.application_description, description, strlen(description)); + + /* Terminate transmitted string with 0 */ + dlt_user.application_description[strlen(description)]='\0'; + } + + DLT_SEM_FREE(); + + ret = dlt_user_log_send_register_application(); + + return ret; +} +int dlt_register_context(DltContext *handle, const char *contextid, const char * description) +{ + if (dlt_user_initialised==0) + { + if (dlt_init()<0) + { + return -1; + } + } + + DLT_SEM_LOCK(); + + if (dlt_user.appID[0]=='\0') + { + dlt_log(LOG_ERR, "no application registered!\n"); + + DLT_SEM_FREE(); + return -1; + } + + if ((contextid==0) || (contextid[0]=='\0')) + { + DLT_SEM_FREE(); + return -1; + } + + DLT_SEM_FREE(); + + return dlt_register_context_ll_ts(handle, contextid, description, DLT_USER_LOG_LEVEL_NOT_SET, DLT_USER_TRACE_STATUS_NOT_SET); +} + +int dlt_register_context_ll_ts(DltContext *handle, const char *contextid, const char * description, int loglevel, int tracestatus) +{ + DltContextData log; + int i; + int registered,ret; + char ctid[DLT_ID_SIZE+1]; + + if (dlt_user_initialised==0) + { + if (dlt_init()<0) + { + return -1; + } + } + + DLT_SEM_LOCK(); + + if (dlt_user.appID[0]=='\0') + { + dlt_log(LOG_ERR, "no application registered!\n"); + + DLT_SEM_FREE(); + return -1; + } + + DLT_SEM_FREE(); + + if ((contextid==0) || (contextid[0]=='\0')) + { + return -1; + } + + if ((loglevel<DLT_USER_LOG_LEVEL_NOT_SET) || (loglevel>DLT_LOG_VERBOSE) || (loglevel==DLT_LOG_DEFAULT)) + { + return -1; + } + + if ((tracestatus<DLT_USER_TRACE_STATUS_NOT_SET) || (tracestatus>DLT_TRACE_STATUS_ON) || (tracestatus==DLT_TRACE_STATUS_DEFAULT)) + { + return -1; + } + + if (dlt_user_log_init(handle, &log)==-1) + { + return -1; + } + + /* Store context id in log level/trace status field */ + + /* Check if already registered, else register context */ + DLT_SEM_LOCK(); + + registered=0; + for (i=0;i<dlt_user.dlt_ll_ts_num_entries;i++) + { + if (dlt_user.dlt_ll_ts) + { + if (memcmp(dlt_user.dlt_ll_ts[i].contextID, contextid,DLT_ID_SIZE)==0) + { + registered=1; + + memset(ctid,0,(DLT_ID_SIZE+1)); + dlt_print_id(ctid, contextid); + + sprintf(str,"context '%s' already registered!\n",ctid); + dlt_log(LOG_WARNING, str); + + break; + } + } + } + + if (registered==0) + { + /* Allocate or expand context array */ + if (dlt_user.dlt_ll_ts == 0) + { + dlt_user.dlt_ll_ts = (dlt_ll_ts_type*) malloc(sizeof(dlt_ll_ts_type)*DLT_USER_CONTEXT_ALLOC_SIZE); + if (dlt_user.dlt_ll_ts==0) + { + DLT_SEM_FREE(); + return -1; + } + + dlt_user.dlt_ll_ts_max_num_entries = DLT_USER_CONTEXT_ALLOC_SIZE; + + /* Initialize new entries */ + for (i=0;i<dlt_user.dlt_ll_ts_max_num_entries;i++) + { + dlt_set_id(dlt_user.dlt_ll_ts[i].contextID,""); + + /* At startup, logging and tracing is locally enabled */ + /* the correct log level/status is set after received from daemon */ + dlt_user.dlt_ll_ts[i].log_level = DLT_USER_INITIAL_LOG_LEVEL; + dlt_user.dlt_ll_ts[i].trace_status = DLT_USER_INITIAL_TRACE_STATUS; + + dlt_user.dlt_ll_ts[i].context_description = 0; + + dlt_user.dlt_ll_ts[i].injection_table = 0; + dlt_user.dlt_ll_ts[i].nrcallbacks = 0; + } + } + else + { + if ((dlt_user.dlt_ll_ts_num_entries%DLT_USER_CONTEXT_ALLOC_SIZE)==0) + { + /* allocate memory in steps of DLT_USER_CONTEXT_ALLOC_SIZE, e.g. 500 */ + dlt_ll_ts_type *old; + old = dlt_user.dlt_ll_ts; + dlt_user.dlt_ll_ts_max_num_entries = ((dlt_user.dlt_ll_ts_num_entries/DLT_USER_CONTEXT_ALLOC_SIZE)+1)*DLT_USER_CONTEXT_ALLOC_SIZE; + dlt_user.dlt_ll_ts = (dlt_ll_ts_type*) malloc(sizeof(dlt_ll_ts_type)* + dlt_user.dlt_ll_ts_max_num_entries); + if (dlt_user.dlt_ll_ts==0) + { + DLT_SEM_FREE(); + return -1; + } + + memcpy(dlt_user.dlt_ll_ts,old,sizeof(dlt_ll_ts_type)*dlt_user.dlt_ll_ts_num_entries); + free(old); + + /* Initialize new entries */ + for (i=dlt_user.dlt_ll_ts_num_entries;i<dlt_user.dlt_ll_ts_max_num_entries;i++) + { + dlt_set_id(dlt_user.dlt_ll_ts[i].contextID,""); + + /* At startup, logging and tracing is locally enabled */ + /* the correct log level/status is set after received from daemon */ + dlt_user.dlt_ll_ts[i].log_level = DLT_USER_INITIAL_LOG_LEVEL; + dlt_user.dlt_ll_ts[i].trace_status = DLT_USER_INITIAL_TRACE_STATUS; + + dlt_user.dlt_ll_ts[i].context_description = 0; + + dlt_user.dlt_ll_ts[i].injection_table = 0; + dlt_user.dlt_ll_ts[i].nrcallbacks = 0; + } + } + } + + /* Store locally context id and context description */ + dlt_set_id(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].contextID, contextid); + + if (dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description!=0) + { + free(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description); + } + + dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description = 0; + + if (description!=0) + { + dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description = malloc(strlen(description)+1); + strncpy(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description, description, strlen(description)); + + /* Terminate transmitted string with 0 */ + dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description[strlen(description)]='\0'; + } + + if (loglevel!=DLT_USER_LOG_LEVEL_NOT_SET) + { + dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].log_level = loglevel; + } + + if (tracestatus!=DLT_USER_TRACE_STATUS_NOT_SET) + { + dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].trace_status = tracestatus; + } + + /* Prepare transfer struct */ + //dlt_set_id(log->appID, dlt_user.appID); + dlt_set_id(handle->contextID, contextid); + handle->log_level_pos = dlt_user.dlt_ll_ts_num_entries; + + log.context_description = dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description; + + if (loglevel!=DLT_USER_LOG_LEVEL_NOT_SET) + { + log.log_level = loglevel; + } + else + { + log.log_level = DLT_USER_LOG_LEVEL_NOT_SET; + } + + if (tracestatus!=DLT_USER_TRACE_STATUS_NOT_SET) + { + log.trace_status = tracestatus; + } + else + { + log.trace_status = DLT_USER_TRACE_STATUS_NOT_SET; + } + + dlt_user.dlt_ll_ts_num_entries++; + + DLT_SEM_FREE(); + + ret=dlt_user_log_send_register_context(&log); + } + else + { + DLT_SEM_FREE(); + + ret=-1; + } + + return ret; +} + +int dlt_unregister_app(void) +{ + int ret; + + if (dlt_user_initialised==0) + { + return -1; + } + + /* Inform daemon to unregister application and all of its contexts */ + ret = dlt_user_log_send_unregister_application(); + + DLT_SEM_LOCK(); + + /* Clear and free local stored application information */ + dlt_set_id(dlt_user.appID, ""); + + if (dlt_user.application_description!=0) + { + free(dlt_user.application_description); + } + + dlt_user.application_description = 0; + + DLT_SEM_FREE(); + + return ret; +} + +int dlt_unregister_context(DltContext *handle) +{ + DltContextData log; + int ret; + + if (dlt_user_initialised==0) + { + return -1; + } + + if (dlt_user_log_init(handle, &log) == -1) + { + return -1; + } + + DLT_SEM_LOCK(); + + if (dlt_user.dlt_ll_ts) + { + /* Clear and free local stored context information */ + dlt_set_id(dlt_user.dlt_ll_ts[handle->log_level_pos].contextID, ""); + + dlt_user.dlt_ll_ts[handle->log_level_pos].log_level = DLT_USER_INITIAL_LOG_LEVEL; + dlt_user.dlt_ll_ts[handle->log_level_pos].trace_status = DLT_USER_INITIAL_TRACE_STATUS; + + if (dlt_user.dlt_ll_ts[handle->log_level_pos].context_description!=0) + { + free(dlt_user.dlt_ll_ts[handle->log_level_pos].context_description); + } + + dlt_user.dlt_ll_ts[handle->log_level_pos].context_description = 0; + + if (dlt_user.dlt_ll_ts[handle->log_level_pos].injection_table) + { + free(dlt_user.dlt_ll_ts[handle->log_level_pos].injection_table); + dlt_user.dlt_ll_ts[handle->log_level_pos].injection_table = 0; + } + + dlt_user.dlt_ll_ts[handle->log_level_pos].nrcallbacks = 0; + } + + DLT_SEM_FREE(); + + /* Inform daemon to unregister context */ + ret = dlt_user_log_send_unregister_context(&log); + + return ret; +} + +int dlt_set_application_ll_ts_limit(DltLogLevelType loglevel, DltTraceStatusType tracestatus) +{ + int i; + int ret; + + if (dlt_user_initialised==0) + { + if (dlt_init()<0) + { + return -1; + } + } + + /* Removed because of DltLogLevelType and DltTraceStatusType + + if ((loglevel<DLT_LOG_DEFAULT) || (loglevel>DLT_LOG_VERBOSE)) + { + return -1; + } + + if ((tracestatus<DLT_TRACE_STATUS_DEFAULT) || (tracestatus>DLT_TRACE_STATUS_ON)) + { + return -1; + } + + if (dlt_user.dlt_ll_ts==0) + { + return -1; + } + + */ + + DLT_SEM_LOCK(); + + /* Update local structures */ + for (i=0; i<dlt_user.dlt_ll_ts_num_entries;i++) + { + dlt_user.dlt_ll_ts[i].log_level = loglevel; + dlt_user.dlt_ll_ts[i].trace_status = tracestatus; + } + + DLT_SEM_FREE(); + + /* Inform DLT server about update */ + ret = dlt_send_app_ll_ts_limit(dlt_user.appID, loglevel, tracestatus); + + return ret; +} + +int dlt_forward_msg(void *msgdata,size_t size) +{ + DltUserHeader userheader; + DltReturnValue ret; + + if ((msgdata==0) || (size==0)) + { + return -1; + } + + if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG)==-1) + { + /* Type of internal user message; same value for Trace messages */ + return -1; + } + + if (dlt_user.dlt_is_file) + { + /* log to file */ + ret = dlt_user_log_out2(dlt_user.dlt_log_handle, msgdata, size, 0, 0); + return ((ret==DLT_RETURN_OK)?0:-1); + } + else + { + /* Reattach to daemon if neccesary */ + dlt_user_log_reattach_to_daemon(); + + if (dlt_user.overflow) + { + if (dlt_user_log_send_overflow()==0) + { + dlt_user.overflow=0; + } + } + + /* log to FIFO */ + ret = dlt_user_log_out3(dlt_user.dlt_log_handle, + &(userheader), sizeof(DltUserHeader), + msgdata, size, 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), + msgdata, size, 0, 0)==-1) + { + dlt_log(LOG_ERR,"Storing message to history buffer failed! Message discarded.\n"); + } + + DLT_SEM_FREE(); + } + + switch (ret) + { + case DLT_RETURN_PIPE_FULL: + { + /* data could not be written */ + dlt_user.overflow = 1; + return -1; + } + case DLT_RETURN_PIPE_ERROR: + { + /* handle not open or pipe error */ + close(dlt_user.dlt_log_handle); + dlt_user.dlt_log_handle = -1; + + return -1; + } + case DLT_RETURN_ERROR: + { + /* other error condition */ + return -1; + } + case DLT_RETURN_OK: + { + return 0; + } + default: + { + /* This case should not occur */ + return -1; + } + } + } + + return 0; +} + +/* ********************************************************************************************* */ + +int dlt_user_log_write_start(DltContext *handle, DltContextData *log,DltLogLevelType loglevel) +{ + return dlt_user_log_write_start_id(handle,log,loglevel,DLT_USER_DEFAULT_MSGID); +} + +int dlt_user_log_write_start_id(DltContext *handle, DltContextData *log,DltLogLevelType loglevel, uint32_t messageid) +{ + uint32_t mid; + + if (dlt_user_initialised==0) + { + if (dlt_init()<0) + { + return -1; + } + } + + if (dlt_user_log_init(handle, log)==-1) + { + return -1; + } + + if (log==0) + { + return -1; + } + + /* Removed because of DltLogLevelType + + if ((loglevel<DLT_LOG_DEFAULT) || (loglevel>DLT_LOG_VERBOSE)) + { + return -1; + } + + */ + + mid = messageid; + + log->args_num = 0; + log->log_level = loglevel; + log->size = 0; + + if (dlt_user.dlt_ll_ts==0) + { + return -1; + } + + DLT_SEM_LOCK(); + + if ((log->log_level<=(int)(dlt_user.dlt_ll_ts[handle->log_level_pos].log_level) ) && (log->log_level!=0)) + { + DLT_SEM_FREE(); + + /* In non-verbose mode, insert message id */ + if (dlt_user.verbose_mode==0) + { + if ((sizeof(uint32_t))>DLT_USER_BUF_MAX_SIZE) + { + return -1; + } + /* Write message id */ + memcpy(log->buffer,&(mid),sizeof(uint32_t)); + log->size = sizeof(uint32_t); + + /* as the message id is part of each message in non-verbose mode, + it doesn't increment the argument counter in extended header (if used) */ + } + return 1; + } + else + { + DLT_SEM_FREE(); + return 0; + } + + return -1; +} + +int dlt_user_log_write_finish(DltContextData *log) +{ + if (log==0) + { + return -1; + } + + return dlt_user_log_send_log(log, DLT_TYPE_LOG); +} + +int dlt_user_log_write_raw(DltContextData *log,void *data,uint16_t length) +{ + uint16_t arg_size; + uint32_t type_info; + + if (log==0) + { + return -1; + } + + if ((log->size+length+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE) + { + return -1; + } + + if (dlt_user.verbose_mode) + { + if ((log->size+length+sizeof(uint32_t)+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE) + { + return -1; + } + + /* Transmit type information */ + type_info = DLT_TYPE_INFO_RAWD; + + memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t)); + log->size += sizeof(uint32_t); + + } + + /* First transmit length of raw data, then the raw data itself */ + arg_size = (uint16_t)length; + + memcpy((log->buffer)+log->size,&(arg_size),sizeof(uint16_t)); + log->size += sizeof(uint16_t); + + memcpy((log->buffer)+log->size,data,arg_size); + log->size += arg_size; + + log->args_num ++; + + return 0; +} + +int dlt_user_log_write_float32(DltContextData *log, float32_t data) +{ + uint32_t type_info; + + if (log==0) + { + return -1; + } + + if (sizeof(float32_t)!=4) + { + return -1; + } + + if ((log->size+sizeof(float32_t))>DLT_USER_BUF_MAX_SIZE) + { + return -1; + } + + if (dlt_user.verbose_mode) + { + if ((log->size+sizeof(uint32_t)+sizeof(float32_t))>DLT_USER_BUF_MAX_SIZE) + { + return -1; + } + + type_info = DLT_TYPE_INFO_FLOA | DLT_TYLE_32BIT; + + memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t)); + log->size += sizeof(uint32_t); + } + + memcpy((log->buffer)+log->size,&data, sizeof(float32_t)); + log->size += sizeof(float32_t); + + log->args_num ++; + + return 0; +} + +int dlt_user_log_write_float64(DltContextData *log, float64_t data) +{ + uint32_t type_info; + + if (log==0) + { + return -1; + } + + if (sizeof(float64_t)!=8) + { + return -1; + } + + if ((log->size+sizeof(float64_t))>DLT_USER_BUF_MAX_SIZE) + { + return -1; + } + + if (dlt_user.verbose_mode) + { + if ((log->size+sizeof(uint32_t)+sizeof(float64_t))>DLT_USER_BUF_MAX_SIZE) + { + return -1; + } + + type_info = DLT_TYPE_INFO_FLOA | DLT_TYLE_64BIT; + + memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t)); + log->size += sizeof(uint32_t); + } + + memcpy((log->buffer)+log->size,&data, sizeof(float64_t)); + log->size += sizeof(float64_t); + + log->args_num ++; + + return 0; +} + +int dlt_user_log_write_uint( DltContextData *log, unsigned int data) +{ + if (log==0) + { + return -1; + } + + switch (sizeof(unsigned int)) + { + case 1: + { + return dlt_user_log_write_uint8(log, (uint8_t)data); + break; + } + case 2: + { + return dlt_user_log_write_uint16(log, (uint16_t)data); + break; + } + case 4: + { + return dlt_user_log_write_uint32(log, (uint32_t)data); + break; + } + case 8: + { + return dlt_user_log_write_uint64(log, (uint64_t)data); + break; + } + default: + { + return -1; + break; + } + } + + return 0; +} + +int dlt_user_log_write_uint8(DltContextData *log, uint8_t data) +{ + uint32_t type_info; + + if (log==0) + { + return -1; + } + + if ((log->size+sizeof(uint8_t))>DLT_USER_BUF_MAX_SIZE) + { + return -1; + } + + if (dlt_user.verbose_mode) + { + if ((log->size+sizeof(uint32_t)+sizeof(uint8_t))>DLT_USER_BUF_MAX_SIZE) + { + return -1; + } + + type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_8BIT; + + memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t)); + log->size += sizeof(uint32_t); + } + + memcpy((log->buffer)+log->size,&data,sizeof(uint8_t)); + log->size += sizeof(uint8_t); + + log->args_num ++; + + return 0; +} + +int dlt_user_log_write_uint16(DltContextData *log, uint16_t data) +{ + uint32_t type_info; + + if (log==0) + { + return -1; + } + + if ((log->size+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE) + { + return -1; + } + + if (dlt_user.verbose_mode) + { + if ((log->size+sizeof(uint32_t)+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE) + { + return -1; + } + + type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_16BIT; + + memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t)); + log->size += sizeof(uint32_t); + } + + memcpy((log->buffer)+log->size,&data,sizeof(uint16_t)); + log->size += sizeof(uint16_t); + + log->args_num ++; + + return 0; +} + +int dlt_user_log_write_uint32(DltContextData *log, uint32_t data) +{ + uint32_t type_info; + + if (log==0) + { + return -1; + } + + if ((log->size+sizeof(uint32_t))>DLT_USER_BUF_MAX_SIZE) + { + return -1; + } + + if (dlt_user.verbose_mode) + { + if ((log->size+sizeof(uint32_t)+sizeof(uint32_t))>DLT_USER_BUF_MAX_SIZE) + { + return -1; + } + + type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_32BIT; + + memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t)); + log->size += sizeof(uint32_t); + } + + memcpy((log->buffer)+log->size,&data, sizeof(uint32_t)); + log->size += sizeof(uint32_t); + + log->args_num ++; + + return 0; +} + +int dlt_user_log_write_uint64(DltContextData *log, uint64_t data) +{ + uint32_t type_info; + + if (log==0) + { + return -1; + } + + if ((log->size+sizeof(uint64_t))>DLT_USER_BUF_MAX_SIZE) + { + return -1; + } + + if (dlt_user.verbose_mode) + { + if ((log->size+sizeof(uint32_t)+sizeof(uint64_t))>DLT_USER_BUF_MAX_SIZE) + { + return -1; + } + + type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_64BIT; + + memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t)); + log->size +=sizeof(uint32_t); + } + + memcpy((log->buffer)+log->size,&data,sizeof(uint64_t)); + log->size += sizeof(uint64_t); + + log->args_num ++; + + return 0; +} + +int dlt_user_log_write_int(DltContextData *log, int data) +{ + if (log==0) + { + return -1; + } + + switch (sizeof(int)) + { + case 1: + { + return dlt_user_log_write_int8(log, (int8_t)data); + break; + } + case 2: + { + return dlt_user_log_write_int16(log, (int16_t)data); + break; + } + case 4: + { + return dlt_user_log_write_int32(log, (int32_t)data); + break; + } + case 8: + { + return dlt_user_log_write_int64(log, (int64_t)data); + break; + } + default: + { + return -1; + break; + } + } + + return 0; +} + +int dlt_user_log_write_int8(DltContextData *log, int8_t data) +{ + uint32_t type_info; + + if (log==0) + { + return -1; + } + + if ((log->size+sizeof(int8_t))>DLT_USER_BUF_MAX_SIZE) + { + return -1; + } + + if (dlt_user.verbose_mode) + { + if ((log->size+sizeof(uint32_t)+sizeof(int8_t))>DLT_USER_BUF_MAX_SIZE) + { + return -1; + } + + type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_8BIT; + + memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t)); + log->size += sizeof(uint32_t); + } + + memcpy((log->buffer)+log->size,&data,sizeof(int8_t)); + log->size += sizeof(int8_t); + + log->args_num ++; + + return 0; +} + +int dlt_user_log_write_int16(DltContextData *log, int16_t data) +{ + uint32_t type_info; + + if (log==0) + { + return -1; + } + + if ((log->size+sizeof(int16_t))>DLT_USER_BUF_MAX_SIZE) + { + return -1; + } + + if (dlt_user.verbose_mode) + { + if ((log->size+sizeof(uint32_t)+sizeof(int16_t))>DLT_USER_BUF_MAX_SIZE) + { + return -1; + } + + type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_16BIT; + + memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t)); + log->size += sizeof(uint32_t); + } + + memcpy((log->buffer)+log->size,&data,sizeof(int16_t)); + log->size += sizeof(int16_t); + + log->args_num ++; + + return 0; +} + +int dlt_user_log_write_int32(DltContextData *log, int32_t data) +{ + uint32_t type_info; + + if (log==0) + { + return -1; + } + + if ((log->size+sizeof(int32_t))>DLT_USER_BUF_MAX_SIZE) + { + return -1; + } + + if (dlt_user.verbose_mode) + { + if ((log->size+sizeof(uint32_t)+sizeof(int32_t))>DLT_USER_BUF_MAX_SIZE) + { + return -1; + } + + type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_32BIT; + + memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t)); + log->size += sizeof(uint32_t); + } + + memcpy((log->buffer)+log->size,&data, sizeof(int32_t)); + log->size += sizeof(int32_t); + + log->args_num ++; + + return 0; +} + +int dlt_user_log_write_int64(DltContextData *log, int64_t data) +{ + uint32_t type_info; + + if (log==0) + { + return -1; + } + + if ((log->size+sizeof(int64_t))>DLT_USER_BUF_MAX_SIZE) + { + return -1; + } + + if (dlt_user.verbose_mode) + { + if ((log->size+sizeof(uint32_t)+sizeof(int64_t))>DLT_USER_BUF_MAX_SIZE) + { + return -1; + } + + type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_64BIT; + + memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t)); + log->size += sizeof(uint32_t); + } + + memcpy((log->buffer)+log->size,&data,sizeof(int64_t)); + log->size += sizeof(int64_t); + + log->args_num ++; + + return 0; +} + +int dlt_user_log_write_bool(DltContextData *log, uint8_t data) +{ + uint32_t type_info; + + if (log==0) + { + return -1; + } + + if ((log->size+sizeof(uint8_t))>DLT_USER_BUF_MAX_SIZE) + { + return -1; + } + + if (dlt_user.verbose_mode) + { + if ((log->size+sizeof(uint32_t)+sizeof(uint8_t))>DLT_USER_BUF_MAX_SIZE) + { + return -1; + } + + type_info = DLT_TYPE_INFO_BOOL; + + memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t)); + log->size += sizeof(uint32_t); + } + + memcpy((log->buffer)+log->size,&data,sizeof(uint8_t)); + log->size += sizeof(uint8_t); + + log->args_num ++; + + return 0; +} + +int dlt_user_log_write_string(DltContextData *log, const char *text) +{ + uint16_t arg_size; + uint32_t type_info; + + if ((log==0) || (text==0)) + { + return -1; + } + + if ((log->size+(strlen(text)+1)+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE) + { + return -1; + } + + if (dlt_user.verbose_mode) + { + if ((log->size+(strlen(text)+1)+sizeof(uint32_t)+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE) + { + return -1; + } + + type_info = DLT_TYPE_INFO_STRG; + + memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t)); + log->size += sizeof(uint32_t); + } + + arg_size = strlen(text) + 1; + + memcpy((log->buffer)+log->size,&(arg_size),sizeof(uint16_t)); + log->size += sizeof(uint16_t); + + memcpy((log->buffer)+log->size,text,arg_size); + log->size += arg_size; + + log->args_num ++; + + return 0; +} + +int dlt_register_injection_callback(DltContext *handle, uint32_t service_id, + int (*dlt_injection_callback)(uint32_t service_id, void *data, uint32_t length)) +{ + DltContextData log; + int i,j,k; + int found = 0; + + DltUserInjectionCallback *old; + + if (handle==0) + { + return -1; + } + + if (dlt_user_log_init(handle, &log)==-1) + { + return -1; + } + + if (service_id<DLT_USER_INJECTION_MIN) + { + return -1; + } + /* This function doesn't make sense storing to local file is choosen; + so terminate this function */ + if (dlt_user.dlt_is_file) + { + return 0; + } + + DLT_SEM_LOCK(); + + if (dlt_user.dlt_ll_ts==0) + { + DLT_SEM_FREE(); + return 0; + } + + /* Insert callback in corresponding table */ + i=handle->log_level_pos; + + /* Insert each service_id only once */ + for (k=0;k<dlt_user.dlt_ll_ts[i].nrcallbacks;k++) + { + if ((dlt_user.dlt_ll_ts[i].injection_table) && + (dlt_user.dlt_ll_ts[i].injection_table[k].service_id == service_id)) + { + found = 1; + break; + } + } + + if (found) + { + j = k; + } + else + { + j=dlt_user.dlt_ll_ts[i].nrcallbacks; + + /* Allocate or expand injection table */ + if (dlt_user.dlt_ll_ts[i].injection_table == 0) + { + dlt_user.dlt_ll_ts[i].injection_table = (DltUserInjectionCallback*) malloc(sizeof(DltUserInjectionCallback)); + } + else + { + old = dlt_user.dlt_ll_ts[i].injection_table; + dlt_user.dlt_ll_ts[i].injection_table = (DltUserInjectionCallback*) malloc(sizeof(DltUserInjectionCallback)*(j+1)); + memcpy(dlt_user.dlt_ll_ts[i].injection_table,old,sizeof(DltUserInjectionCallback)*j); + free(old); + } + + dlt_user.dlt_ll_ts[i].nrcallbacks++; + } + + /* Store service_id and corresponding function pointer for callback function */ + dlt_user.dlt_ll_ts[i].injection_table[j].service_id = service_id; + dlt_user.dlt_ll_ts[i].injection_table[j].injection_callback = dlt_injection_callback; + + DLT_SEM_FREE(); + return 0; +} + +int dlt_user_trace_network(DltContext *handle, DltNetworkTraceType nw_trace_type, uint16_t header_len, void *header, uint16_t payload_len, void *payload) +{ + DltContextData log; + + if (dlt_user_initialised==0) + { + if (dlt_init()<0) + { + return -1; + } + } + + if (dlt_user_log_init(handle, &log)==-1) + { + return -1; + } + + if (handle==0) + { + return -1; + } + + /* Commented out because of DltNetworkTraceType: + + if ((nw_trace_type<=0) || (nw_trace_type>0x15)) + { + return -1; + } + + */ + + DLT_SEM_LOCK(); + + if (dlt_user.dlt_ll_ts==0) + { + DLT_SEM_FREE(); + return -1; + } + + if (dlt_user.dlt_ll_ts[handle->log_level_pos].trace_status==DLT_TRACE_STATUS_ON) + { + DLT_SEM_FREE(); + + log.args_num = 0; + log.trace_status = nw_trace_type; + log.size = 0; + + if (header==0) + { + header_len=0; + } + + /* Write header and its length */ + if (dlt_user_log_write_raw(&log, header, header_len)==-1) + { + return -1; + } + + if (payload==0) + { + payload_len=0; + } + + /* Write payload and its length */ + if (dlt_user_log_write_raw(&log, payload, payload_len)==-1) + { + return -1; + } + + /* Send log */ + return dlt_user_log_send_log(&log, DLT_TYPE_NW_TRACE); + } + else + { + DLT_SEM_FREE(); + } + + return 0; +} + +int dlt_log_string(DltContext *handle,DltLogLevelType loglevel, const char *text) +{ + DltContextData log; + + if (dlt_user.verbose_mode==0) + { + return -1; + } + + if ((handle==0) || (text==0)) + { + return -1; + } + + if (dlt_user_log_write_start(handle,&log,loglevel)) + { + if (dlt_user_log_write_string(&log,text)==-1) + { + return -1; + } + if (dlt_user_log_write_finish(&log)==-1) + { + return -1; + } + } + + return 0; +} + +int dlt_log_string_int(DltContext *handle,DltLogLevelType loglevel, const char *text, int data) +{ + DltContextData log; + + if (dlt_user.verbose_mode==0) + { + return -1; + } + + if ((handle==0) || (text==0)) + { + return -1; + } + + if (dlt_user_log_write_start(handle,&log,loglevel)) + { + if (dlt_user_log_write_string(&log,text)==-1) + { + return -1; + } + if (dlt_user_log_write_int(&log,data)==-1) + { + return -1; + } + if (dlt_user_log_write_finish(&log)==-1) + { + return -1; + } + } + + return 0; +} + +int dlt_log_string_uint(DltContext *handle,DltLogLevelType loglevel, const char *text, unsigned int data) +{ + DltContextData log; + + if (dlt_user.verbose_mode==0) + { + return -1; + } + + if ((handle==0) || (text==0)) + { + return -1; + } + + if (dlt_user_log_write_start(handle,&log,loglevel)) + { + if (dlt_user_log_write_string(&log,text)==-1) + { + return -1; + } + if (dlt_user_log_write_uint(&log,data)==-1) + { + return -1; + } + if (dlt_user_log_write_finish(&log)==-1) + { + return -1; + } + } + + return 0; +} + +int dlt_log_int(DltContext *handle,DltLogLevelType loglevel, int data) +{ + DltContextData log; + + if (dlt_user.verbose_mode==0) + { + return -1; + } + + if (handle==0) + { + return -1; + } + + if (dlt_user_log_write_start(handle,&log,loglevel)) + { + if (dlt_user_log_write_int(&log,data)==-1) + { + return -1; + } + if (dlt_user_log_write_finish(&log)==-1) + { + return -1; + } + } + + return 0; +} + +int dlt_log_uint(DltContext *handle,DltLogLevelType loglevel, unsigned int data) +{ + DltContextData log; + + if (dlt_user.verbose_mode==0) + { + return -1; + } + + if (handle==0) + { + return -1; + } + + if (dlt_user_log_write_start(handle,&log,loglevel)) + { + if (dlt_user_log_write_uint(&log,data)==-1) + { + return -1; + } + if (dlt_user_log_write_finish(&log)==-1) + { + return -1; + } + } + + return 0; +} + +int dlt_log_raw(DltContext *handle,DltLogLevelType loglevel, void *data,uint16_t length) +{ + DltContextData log; + + if (dlt_user.verbose_mode==0) + { + return -1; + } + + if (handle==0) + { + return -1; + } + + if (dlt_user_log_write_start(handle,&log,loglevel)) + { + if (dlt_user_log_write_raw(&log,data,length)==-1) + { + return -1; + } + if (dlt_user_log_write_finish(&log)==-1) + { + return -1; + } + } + + return 0; +} + +int dlt_verbose_mode(void) +{ + if (dlt_user_initialised==0) + { + if (dlt_init()<0) + { + return -1; + } + } + + /* Switch to verbose mode */ + dlt_user.verbose_mode = 1; + + return 0; +} + +int dlt_nonverbose_mode(void) +{ + if (dlt_user_initialised==0) + { + if (dlt_init()<0) + { + return -1; + } + } + + /* Switch to non-verbose mode */ + dlt_user.verbose_mode = 0; + + return 0; +} + +int dlt_enable_local_print(void) +{ + if (dlt_user_initialised==0) + { + if (dlt_init()<0) + { + return -1; + } + } + + dlt_user.enable_local_print = 1; + + return 0; +} + +int dlt_disable_local_print(void) +{ + if (dlt_user_initialised==0) + { + if (dlt_init()<0) + { + return -1; + } + } + + dlt_user.enable_local_print = 0; + + return 0; +} + +void dlt_user_receiverthread_function(void *ptr) +{ + while (1) + { + /* Check for new messages from DLT daemon */ + if (dlt_user_log_check_user_message()==-1) + { + /* Critical error */ + dlt_log(LOG_CRIT,"Receiver thread encountered error condition\n"); + } + + usleep(DLT_USER_RECEIVE_DELAY); /* delay */ + } +} + +/* Private functions of user library */ + +int dlt_user_log_init(DltContext *handle, DltContextData *log) +{ + if (dlt_user_initialised==0) + { + if (dlt_init()<0) + { + return -1; + } + } + + log->handle = handle; + log->mcnt = 0; + + return 0; +} + +int dlt_user_log_send_log(DltContextData *log, int mtype) +{ + DltMessage msg; + DltUserHeader userheader; + int32_t len; + + DltReturnValue ret; + + if (log==0) + { + return -1; + } + + if (log->handle==0) + { + return -1; + } + + if (dlt_user.appID[0]=='\0') + { + return -1; + } + + if (log->handle->contextID[0]=='\0') + { + return -1; + } + + if ((mtype<DLT_TYPE_LOG) || (mtype>DLT_TYPE_CONTROL)) + { + return -1; + } + + /* also for Trace messages */ + if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG)==-1) + { + return -1; + } + + if (dlt_message_init(&msg,0)==-1) + { + return -1; + } + + msg.storageheader = (DltStorageHeader*)msg.headerbuffer; + + if (dlt_set_storageheader(msg.storageheader,dlt_user.ecuID)==-1) + { + return -1; + } + + msg.standardheader = (DltStandardHeader*)(msg.headerbuffer + sizeof(DltStorageHeader)); + msg.standardheader->htyp = DLT_HTYP_WEID | DLT_HTYP_WTMS | DLT_HTYP_PROTOCOL_VERSION1 ; + + if (dlt_user.verbose_mode) + { + /* In verbose mode, send extended header */ + msg.standardheader->htyp = (msg.standardheader->htyp | DLT_HTYP_UEH ); + } + else + { + /* In non-verbose, send extended header if desired */ +#if (DLT_USER_USE_EXTENDED_HEADER_FOR_NONVERBOSE==1) + msg.standardheader->htyp = (msg.standardheader->htyp | DLT_HTYP_UEH ); +#endif + } + +#if (BYTE_ORDER==BIG_ENDIAN) + msg.standardheader->htyp = (msg.standardheader->htyp | DLT_HTYP_MSBF); +#endif + + msg.standardheader->mcnt = log->mcnt++; + + /* Set header extra parameters */ + dlt_set_id(msg.headerextra.ecu,dlt_user.ecuID); + //msg.headerextra.seid = 0; + msg.headerextra.tmsp = dlt_uptime(); + + if (dlt_message_set_extraparameters(&msg,0)==-1) + { + return -1; + } + + /* Fill out extended header, if extended header should be provided */ + if (DLT_IS_HTYP_UEH(msg.standardheader->htyp)) + { + /* with extended header */ + msg.extendedheader = (DltExtendedHeader*)(msg.headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp) ); + + switch (mtype) + { + case DLT_TYPE_LOG: + { + msg.extendedheader->msin = (DLT_TYPE_LOG << DLT_MSIN_MSTP_SHIFT) | ((log->log_level << DLT_MSIN_MTIN_SHIFT) & DLT_MSIN_MTIN) ; /* messsage info */ + break; + } + case DLT_TYPE_NW_TRACE: + { + msg.extendedheader->msin = (DLT_TYPE_NW_TRACE << DLT_MSIN_MSTP_SHIFT) | ((log->trace_status << DLT_MSIN_MTIN_SHIFT) & DLT_MSIN_MTIN) ; /* messsage info */ + break; + } + default: + { + /* This case should not occur */ + return -1; + break; + } + } + + /* If in verbose mode, set flag in header for verbose mode */ + if (dlt_user.verbose_mode) + { + msg.extendedheader->msin |= DLT_MSIN_VERB; + } + + msg.extendedheader->noar = log->args_num; /* number of arguments */ + dlt_set_id(msg.extendedheader->apid,dlt_user.appID); /* application id */ + dlt_set_id(msg.extendedheader->ctid,log->handle->contextID); /* context id */ + + msg.headersize = sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + sizeof(DltExtendedHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp); + } + else + { + /* without extended header */ + msg.headersize = sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp); + } + + len=msg.headersize - sizeof(DltStorageHeader) +log->size; + if (len>UINT16_MAX) + { + dlt_log(LOG_CRIT,"Huge message discarded!\n"); + return -1; + } + + msg.standardheader->len = DLT_HTOBE_16(len); + + /* print to std out, if enabled */ + if ((dlt_user.local_print_mode != DLT_PM_FORCE_OFF) && + (dlt_user.local_print_mode != DLT_PM_AUTOMATIC)) + { + if ((dlt_user.enable_local_print) || (dlt_user.local_print_mode == DLT_PM_FORCE_ON)) + { + if (dlt_user_print_msg(&msg, log)==-1) + { + return -1; + } + } + } + + if (dlt_user.dlt_is_file) + { + /* log to file */ + ret=dlt_user_log_out2(dlt_user.dlt_log_handle, msg.headerbuffer, msg.headersize, log->buffer, log->size); + return ((ret==DLT_RETURN_OK)?0:-1); + } + else + { + /* Reattach to daemon if neccesary */ + dlt_user_log_reattach_to_daemon(); + + if (dlt_user.overflow) + { + if (dlt_user_log_send_overflow()==0) + { + dlt_user.overflow=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); + + /* 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(); + } + + switch (ret) + { + case DLT_RETURN_PIPE_FULL: + { + /* data could not be written */ + dlt_user.overflow = 1; + return -1; + } + case DLT_RETURN_PIPE_ERROR: + { + /* handle not open or pipe error */ + close(dlt_user.dlt_log_handle); + dlt_user.dlt_log_handle = -1; + + if (dlt_user.local_print_mode == DLT_PM_AUTOMATIC) + { + dlt_user_print_msg(&msg, log); + } + + return -1; + } + case DLT_RETURN_ERROR: + { + /* other error condition */ + return -1; + } + case DLT_RETURN_OK: + { + return 0; + } + default: + { + /* This case should never occur. */ + return -1; + } + } + } + + return 0; +} + +int dlt_user_log_send_register_application(void) +{ + DltUserHeader userheader; + DltUserControlMsgRegisterApplication usercontext; + + DltReturnValue ret; + + if (dlt_user.appID[0]=='\0') + { + return -1; + } + + /* set userheader */ + if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_REGISTER_APPLICATION)==-1) + { + return -1; + } + + /* set usercontext */ + dlt_set_id(usercontext.apid,dlt_user.appID); /* application id */ + usercontext.pid = getpid(); + + if (dlt_user.application_description!=0) + { + usercontext.description_length = strlen(dlt_user.application_description); + } + else + { + usercontext.description_length = 0; + } + + if (dlt_user.dlt_is_file) + { + return 0; + } + + /* log to FIFO */ + ret=dlt_user_log_out3(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgRegisterApplication),dlt_user.application_description,usercontext.description_length); + return ((ret==DLT_RETURN_OK)?0:-1); +} + +int dlt_user_log_send_unregister_application(void) +{ + DltUserHeader userheader; + DltUserControlMsgUnregisterApplication usercontext; + + DltReturnValue ret; + + if (dlt_user.appID[0]=='\0') + { + return -1; + } + + /* set userheader */ + if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_UNREGISTER_APPLICATION)==-1) + { + return -1; + } + + /* set usercontext */ + dlt_set_id(usercontext.apid,dlt_user.appID); /* application id */ + usercontext.pid = getpid(); + + if (dlt_user.dlt_is_file) + { + return 0; + } + + /* log to FIFO */ + ret=dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgUnregisterApplication)); + return ((ret==DLT_RETURN_OK)?0:-1); +} + +int dlt_user_log_send_register_context(DltContextData *log) +{ + DltUserHeader userheader; + DltUserControlMsgRegisterContext usercontext; + DltReturnValue ret; + + if (log==0) + { + return -1; + } + + if (log->handle==0) + { + return -1; + } + + if ((dlt_user.appID[0]=='\0') || (log->handle->contextID=='\0')) + { + return -1; + } + + /* set userheader */ + if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_REGISTER_CONTEXT)==-1) + { + return -1; + } + + /* set usercontext */ + dlt_set_id(usercontext.apid,dlt_user.appID); /* application id */ + dlt_set_id(usercontext.ctid,log->handle->contextID); /* context id */ + usercontext.log_level_pos = log->handle->log_level_pos; + usercontext.pid = getpid(); + + usercontext.log_level = (int8_t)log->log_level; + usercontext.trace_status = (int8_t)log->trace_status; + + if (log->context_description!=0) + { + usercontext.description_length = strlen(log->context_description); + } + else + { + usercontext.description_length = 0; + } + + if (dlt_user.dlt_is_file) + { + return 0; + } + + /* log to FIFO */ + ret=dlt_user_log_out3(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgRegisterContext),log->context_description,usercontext.description_length); + return ((ret==DLT_RETURN_OK)?0:-1); +} + +int dlt_user_log_send_unregister_context(DltContextData *log) +{ + DltUserHeader userheader; + DltUserControlMsgUnregisterContext usercontext; + DltReturnValue ret; + + if (log==0) + { + return -1; + } + + if (log->handle==0) + { + return -1; + } + + if ((dlt_user.appID[0]=='\0') || (log->handle->contextID=='\0')) + { + return -1; + } + + /* set userheader */ + if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_UNREGISTER_CONTEXT)==-1) + { + return -1; + } + + /* set usercontext */ + dlt_set_id(usercontext.apid,dlt_user.appID); /* application id */ + dlt_set_id(usercontext.ctid,log->handle->contextID); /* context id */ + usercontext.pid = getpid(); + + if (dlt_user.dlt_is_file) + { + return 0; + } + + /* log to FIFO */ + ret=dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgUnregisterContext)); + return ((ret==DLT_RETURN_OK)?0:-1); +} + +int dlt_send_app_ll_ts_limit(const char *appid, DltLogLevelType loglevel, DltTraceStatusType tracestatus) +{ + DltUserHeader userheader; + DltUserControlMsgAppLogLevelTraceStatus usercontext; + DltReturnValue ret; + + if ((appid==0) || (appid[0]=='\0')) + { + return -1; + } + + /* Removed because of DltLogLevelType and DltTraceStatusType + + if ((loglevel<DLT_LOG_DEFAULT) || (loglevel>DLT_LOG_VERBOSE)) + { + return -1; + } + + if ((tracestatus<DLT_TRACE_STATUS_DEFAULT) || (tracestatus>DLT_TRACE_STATUS_ON)) + { + return -1; + } + + */ + + /* set userheader */ + if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_APP_LL_TS)==-1) + { + return -1; + } + + /* set usercontext */ + dlt_set_id(usercontext.apid,appid); /* application id */ + usercontext.log_level = loglevel; + usercontext.trace_status = tracestatus; + + if (dlt_user.dlt_is_file) + { + return 0; + } + + /* log to FIFO */ + ret=dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgAppLogLevelTraceStatus)); + return ((ret==DLT_RETURN_OK)?0:-1); +} + +int dlt_user_print_msg(DltMessage *msg, DltContextData *log) +{ + uint8_t *databuffer_tmp; + int32_t datasize_tmp; + + if ((msg==0) || (log==0)) + { + return -1; + } + + /* Save variables before print */ + databuffer_tmp = msg->databuffer; + datasize_tmp = msg->datasize; + + /* Act like a receiver, convert header back to host format */ + msg->standardheader->len = DLT_BETOH_16(msg->standardheader->len); + dlt_message_get_extraparameters(msg,0); + + msg->databuffer = log->buffer; + msg->datasize = log->size; + + /* Print message as ASCII */ + if (dlt_message_print_ascii(msg,text,DLT_USER_TEXT_LENGTH,0)==-1) + { + return -1; + } + + /* Restore variables and set len to BE*/ + msg->databuffer = databuffer_tmp; + msg->datasize = datasize_tmp; + + msg->standardheader->len = DLT_HTOBE_16(msg->standardheader->len); + + return 0; +} + +int dlt_user_log_check_user_message(void) +{ + int offset=0; + int leave_while=0; + + int i; + + DltUserHeader *userheader; + DltReceiver *receiver = &(dlt_user.receiver); + + DltUserControlMsgLogLevel *usercontextll; + + DltUserControlMsgInjection *usercontextinj; + unsigned char *userbuffer; + unsigned char *inject_buffer; + + if (dlt_user.dlt_user_handle!=-1) + { + while (1) + { + if (dlt_receiver_receive_fd(receiver)<=0) + { + /* No new message available */ + return 0; + } + + /* look through buffer as long as data is in there */ + while (1) + { + if (receiver->bytesRcvd < sizeof(DltUserHeader)) + { + break; + } + + /* resync if necessary */ + offset=0; + do + { + userheader = (DltUserHeader*) (receiver->buf+offset); + + /* Check for user header pattern */ + if (dlt_user_check_userheader(userheader)) + { + break; + } + offset++; + + } + while ((sizeof(DltUserHeader)+offset)<=receiver->bytesRcvd); + + /* Check for user header pattern */ + if (dlt_user_check_userheader(userheader)==0) + { + break; + } + + /* Set new start offset */ + if (offset>0) + { + receiver->buf+=offset; + receiver->bytesRcvd-=offset; + } + + switch (userheader->message) + { + case DLT_USER_MESSAGE_LOG_LEVEL: + { + if (receiver->bytesRcvd < (sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogLevel))) + { + leave_while=1; + break; + } + + usercontextll = (DltUserControlMsgLogLevel*) (receiver->buf+sizeof(DltUserHeader)); + + /* Update log level and trace status */ + if (usercontextll!=0) + { + DLT_SEM_LOCK(); + + if ((usercontextll->log_level_pos>=0) && (usercontextll->log_level_pos<dlt_user.dlt_ll_ts_num_entries)) + { + // printf("Store ll, ts\n"); + if (dlt_user.dlt_ll_ts) + { + dlt_user.dlt_ll_ts[usercontextll->log_level_pos].log_level = usercontextll->log_level; + dlt_user.dlt_ll_ts[usercontextll->log_level_pos].trace_status = usercontextll->trace_status; + } + } + + DLT_SEM_FREE(); + } + + /* keep not read data in buffer */ + if (dlt_receiver_remove(receiver,sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogLevel))==-1) + { + return -1; + } + } + break; + case DLT_USER_MESSAGE_INJECTION: + { + /* At least, user header, user context, and service id and data_length of injected message is available */ + if (receiver->bytesRcvd < (sizeof(DltUserHeader)+sizeof(DltUserControlMsgInjection))) + { + leave_while = 1; + break; + } + + usercontextinj = (DltUserControlMsgInjection*) (receiver->buf+sizeof(DltUserHeader)); + userbuffer = (unsigned char*) (receiver->buf+sizeof(DltUserHeader)+sizeof(DltUserControlMsgInjection)); + inject_buffer = 0; + + if (userbuffer!=0) + { + + if (receiver->bytesRcvd < (sizeof(DltUserHeader)+sizeof(DltUserControlMsgInjection)+usercontextinj->data_length_inject)) + { + leave_while = 1; + break; + } + + DLT_SEM_LOCK(); + + if ((usercontextinj->data_length_inject>0) && (dlt_user.dlt_ll_ts)) + { + /* Check if injection callback is registered for this context */ + for (i=0; i<dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].nrcallbacks;i++) + { + if ((dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table) && + (dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table[i].service_id == usercontextinj->service_id)) + { + /* callback available, so prepare data, then call it */ + inject_buffer = malloc(usercontextinj->data_length_inject); + if (inject_buffer!=0) + { + /* copy from receiver to inject_buffer */ + memcpy(inject_buffer, userbuffer, usercontextinj->data_length_inject); + + /* call callback */ + if (dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table[i].injection_callback!=0) + { + // printf("Got injection(%d), length=%d, '%s' \n", usercontext->service_id, usercontext->data_length_inject, inject_buffer); + dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table[i].injection_callback( + usercontextinj->service_id, inject_buffer, usercontextinj->data_length_inject); + } + + if (inject_buffer!=0) + { + free(inject_buffer); + inject_buffer = 0; + } + } + + break; + } + } + } + + DLT_SEM_FREE(); + + /* keep not read data in buffer */ + if (dlt_receiver_remove(receiver,(sizeof(DltUserHeader)+sizeof(DltUserControlMsgInjection)+usercontextinj->data_length_inject))==-1) + { + return -1; + } + } + } + break; + default: + { + dlt_log(LOG_ERR,"Invalid user message type received!\n"); + /* Ignore result */ + dlt_receiver_remove(receiver,sizeof(DltUserHeader)); + /* In next invocation of while loop, a resync will be triggered if additional data was received */ + } + break; + } /* switch() */ + + if (leave_while==1) + { + leave_while=0; + break; + } + + } /* while buffer*/ + + if (dlt_receiver_move_to_begin(receiver)==-1) + { + return -1; + } + } /* while receive */ + } /* if */ + + return 0; +} + +void dlt_user_log_reattach_to_daemon(void) +{ + int num, count, reregistered=0; + + uint8_t buf[DLT_USER_RINGBUFFER_SIZE]; + size_t size; + + DltContext handle; + DltContextData log_new; + DltReturnValue ret; + + if (dlt_user.dlt_log_handle<0) + { + dlt_user.dlt_log_handle=-1; + + /* try to open pipe to dlt daemon */ + dlt_user.dlt_log_handle = open(DLT_USER_FIFO, O_WRONLY | O_NONBLOCK); + if (dlt_user.dlt_log_handle > 0) + { + if (dlt_user_log_init(&handle,&log_new)==-1) + { + return; + } + + dlt_log(LOG_NOTICE, "Logging re-enabled!\n"); + + /* Re-register application */ + if (dlt_user_log_send_register_application()==-1) + { + return; + } + + DLT_SEM_LOCK(); + + /* Re-register all stored contexts */ + for (num=0; num<dlt_user.dlt_ll_ts_num_entries; num++) + { + /* Re-register stored context */ + if ((dlt_user.appID[0]!='\0') && (dlt_user.dlt_ll_ts[num].contextID[0]!='\0') && (dlt_user.dlt_ll_ts)) + { + //dlt_set_id(log_new.appID, dlt_user.appID); + dlt_set_id(handle.contextID, dlt_user.dlt_ll_ts[num].contextID); + handle.log_level_pos = num; + log_new.context_description = dlt_user.dlt_ll_ts[num].context_description; + + log_new.log_level = DLT_USER_LOG_LEVEL_NOT_SET; + log_new.trace_status = DLT_USER_TRACE_STATUS_NOT_SET; + + if (dlt_user_log_send_register_context(&log_new)==-1) + { + DLT_SEM_FREE(); + return; + } + + reregistered=1; + } + } + + DLT_SEM_FREE(); + + 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; + } + } + } + + } + } + } + } +} + +int dlt_user_log_send_overflow(void) +{ + DltUserHeader userheader; + DltReturnValue ret; + + /* set userheader */ + if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_OVERFLOW)==-1) + { + return -1; + } + + if (dlt_user.dlt_is_file) + { + return 0; + } + + /* log to FIFO */ + ret=dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), 0, 0); + return ((ret==DLT_RETURN_OK)?0:-1); +} + diff --git a/src/lib/dlt_user_cfg.h b/src/lib/dlt_user_cfg.h new file mode 100755 index 0000000..f5f7700 --- /dev/null +++ b/src/lib/dlt_user_cfg.h @@ -0,0 +1,143 @@ +/*
+ * Dlt- Diagnostic Log and Trace daemon
+ * @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_user_cfg.h **
+** **
+** TARGET : linux **
+** **
+** PROJECT : DLT **
+** **
+** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de **
+** Markus Klein **
+** **
+** PURPOSE : **
+** **
+** REMARKS : **
+** **
+** PLATFORM DEPENDANT [yes/no]: yes **
+** **
+** TO BE CHANGED BY USER [yes/no]: no **
+** **
+*******************************************************************************/
+
+/*******************************************************************************
+** Author Identity **
+********************************************************************************
+** **
+** Initials Name Company **
+** -------- ------------------------- ---------------------------------- **
+** aw Alexander Wenzel BMW **
+** mk Markus Klein Fraunhofer ESK **
+*******************************************************************************/
+
+/*******************************************************************************
+** Author Identity **
+********************************************************************************
+** **
+** Initials Name Company **
+** -------- ------------------------- ---------------------------------- **
+** aw Alexander Wenzel BMW **
+** mk Markus Klein Fraunhofer ESK **
+*******************************************************************************/
+
+#ifndef DLT_USER_CFG_H
+#define DLT_USER_CFG_H
+
+/*************/
+/* Changable */
+/*************/
+
+/* 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
+
+/* Number of context entries, which will be allocated,
+ if no more context entries are available */
+#define DLT_USER_CONTEXT_ALLOC_SIZE 500
+
+/* Maximu length of a filename string */
+#define DLT_USER_MAX_FILENAME_LENGTH 255
+
+/* 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"
+
+/* Initial log level */
+#define DLT_USER_INITIAL_LOG_LEVEL DLT_LOG_INFO
+
+/* Initial trace status */
+#define DLT_USER_INITIAL_TRACE_STATUS DLT_TRACE_STATUS_OFF
+
+/* use extended header for non-verbose mode: 0 - don't use, 1 - use */
+#define DLT_USER_USE_EXTENDED_HEADER_FOR_NONVERBOSE 0
+
+/* default message id for non-verbose mode, if no message id was provided */
+#define DLT_USER_DEFAULT_MSGID 0xffff
+
+/* delay in receiver routine in usec (100000 usec = 100ms) */
+#define DLT_USER_RECEIVE_DELAY 100000
+
+/* Name of environment variable for local print mode */
+#define DLT_USER_ENV_LOCAL_PRINT_MODE "DLT_LOCAL_PRINT_MODE"
+
+/************************/
+/* Don't change please! */
+/************************/
+
+/* Minimum valid ID of an injection message */
+#define DLT_USER_INJECTION_MIN 0xFFF
+
+/* Defines of the different local print modes */
+#define DLT_PM_UNSET 0
+#define DLT_PM_AUTOMATIC 1
+#define DLT_PM_FORCE_ON 2
+#define DLT_PM_FORCE_OFF 3
+
+#endif /* DLT_USER_CFG_H */
diff --git a/src/shared/dlt_common.c b/src/shared/dlt_common.c new file mode 100755 index 0000000..21a36da --- /dev/null +++ b/src/shared/dlt_common.c @@ -0,0 +1,3461 @@ +/* + * Dlt- Diagnostic Log and Trace console apps + * @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_common.c ** +** ** +** TARGET : linux ** +** ** +** PROJECT : DLT ** +** ** +** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** +** Markus Klein ** +** ** +** PURPOSE : ** +** ** +** REMARKS : ** +** ** +** PLATFORM DEPENDANT [yes/no]: yes ** +** ** +** TO BE CHANGED BY USER [yes/no]: no ** +** ** +*******************************************************************************/ + +/******************************************************************************* +** Author Identity ** +******************************************************************************** +** ** +** Initials Name Company ** +** -------- ------------------------- ---------------------------------- ** +** aw Alexander Wenzel BMW ** +** mk Markus Klein Fraunhofer ESK ** +*******************************************************************************/ + +/******************************************************************************* +** Revision Control History ** +*******************************************************************************/ + +/* + * $LastChangedRevision: 1670 $ + * $LastChangedDate: 2011-04-08 15:12:06 +0200 (Fr, 08. Apr 2011) $ + * $LastChangedBy$ + Initials Date Comment + aw 13.01.2010 initial + */ +#include <stdio.h> +#include <stdlib.h> /* for malloc(), free() */ +#include <string.h> /* for strlen(), memcmp(), memmove() */ +#include <time.h> /* for localtime(), strftime() */ + +#include "dlt_common.h" +#include "dlt_common_cfg.h" + +#include "version.h" +#include "svnversion.h" + +#if defined (__WIN32__) || defined (_MSC_VER) +#include <winsock2.h> /* for socket(), connect(), send(), and recv() */ +#else +#include <sys/socket.h> /* for socket(), connect(), send(), and recv() */ +#include <syslog.h> +#include <time.h> /* for clock_gettime() */ +#endif + +#if defined (_MSC_VER) +#include <io.h> +#else +#include <unistd.h> /* for read(), close() */ +#include <sys/time.h> /* for gettimeofday() */ +#endif + +#if defined (__MSDOS__) || defined (_MSC_VER) +#pragma warning(disable : 4996) /* Switch off C4996 warnings */ +#include <windows.h> +#include <winbase.h> +#endif + +static char str[DLT_COMMON_BUFFER_LENGTH]; + +const char dltSerialHeader[DLT_ID_SIZE] = { 'D','L','S',1 }; +char dltSerialHeaderChar[DLT_ID_SIZE] = { 'D','L','S',1 }; + +static int log_as_daemon = 0; + +char *message_type[] = {"log","app_trace","nw_trace","control","","","",""}; +char *log_info[] = {"","fatal","error","warn","info","debug","verbose","","","","","","","","",""}; +char *trace_type[] = {"","variable","func_in","func_out","state","vfb","","","","","","","","","",""}; +char *nw_trace_type[] = {"","ipc","can","flexray","most","vfb","","","","","","","","","",""}; +char *control_type[] = {"","request","response","time","","","","","","","","","","","",""}; +static char *service_id[] = {"","set_log_level","set_trace_status","get_log_info","get_default_log_level","store_config","reset_to_factory_default", + "set_com_interface_status","set_com_interface_max_bandwidth","set_verbose_mode","set_message_filtering","set_timing_packets", + "get_local_time","use_ecu_id","use_session_id","use_timestamp","use_extended_header","set_default_log_level","set_default_trace_status", + "get_software_version","message_buffer_overflow" + }; +static char *return_type[] = {"ok","not_supported","error","","","","","","no_matching_context_id"}; + +void dlt_print_hex(uint8_t *ptr,int size) +{ + int num; + + if (ptr==0) + { + return; + } + + for (num=0;num<size;num++) + { + if (num>0) + { + printf(" "); + } + + printf("%.2x",((uint8_t*)ptr)[num]); + } +} + +int dlt_print_hex_string(char *text,int textlength,uint8_t *ptr,int size) +{ + int num; + + if ((ptr==0) || (text==0) || (textlength<=0) || (size<0)) + { + return -1; + } + + /* Length 3: AB_ , A is first digit of hex number, B is second digit of hex number, _ is space */ + if (textlength<(size*3)) + { + dlt_log(LOG_ERR, "String does not fit binary data!\n"); + return -1; + } + + for (num=0;num<size;num++) + { + if (num>0) + { + sprintf(text," "); + text++; + } + + sprintf(text,"%.2x",((uint8_t*)ptr)[num]); + text+=2; /* 2 chars */ + } + + return 0; +} + +int dlt_print_mixed_string(char *text,int textlength,uint8_t *ptr,int size,int html) +{ + int required_size = 0; + int lines, rest, i; + + if ((ptr==0) || (text==0) || (textlength<=0) || (size<0)) + { + return -1; + } + + /* Check maximum required size and do a length check */ + if (html==0) + { + required_size=(DLT_COMMON_HEX_LINELEN+(2*DLT_COMMON_HEX_CHARS+(DLT_COMMON_HEX_CHARS-1))+DLT_COMMON_CHARLEN+DLT_COMMON_HEX_CHARS+DLT_COMMON_CHARLEN) * + ((size/DLT_COMMON_HEX_CHARS) + 1); + /* Example: (8 chars line number + (2*16 chars + 15 spaces) + space + 16 ascii chars + CR) * + ((size/16) lines + extra line for the rest) */ + } + else + { + required_size=(DLT_COMMON_HEX_LINELEN+(2*DLT_COMMON_HEX_CHARS+(DLT_COMMON_HEX_CHARS-1))+DLT_COMMON_CHARLEN+DLT_COMMON_HEX_CHARS+4*DLT_COMMON_CHARLEN) * + ((size/DLT_COMMON_HEX_CHARS) + 1); + /* Example: (8 chars line number + (2*16 chars + 15 spaces) + space + 16 ascii chars + 4 [HTML CR: <BR>]) * + ((size/16) lines + extra line for the rest) */ + } + + if (textlength<required_size) + { + sprintf(str, "String does not fit mixed data (available=%d, required=%d) !\n", textlength, required_size); + dlt_log(LOG_ERR, str); + return -1; + } + + /* print full lines */ + for (lines=0; lines< (size / DLT_COMMON_HEX_CHARS); lines++) + { + /* Line number */ + sprintf(text,"%.6x: ",lines * DLT_COMMON_HEX_CHARS); + text+=DLT_COMMON_HEX_LINELEN; /* 'XXXXXX: ' */ + + /* Hex-Output */ + /* It is not required to decrement textlength, as it was already checked, that + there is enough space for the complete output */ + dlt_print_hex_string(text,textlength,(uint8_t*)(ptr+(lines*DLT_COMMON_HEX_CHARS)),DLT_COMMON_HEX_CHARS); + text+=((2*DLT_COMMON_HEX_CHARS)+(DLT_COMMON_HEX_CHARS-1)); /* 32 characters + 15 spaces */ + + sprintf(text," "); + text+=DLT_COMMON_CHARLEN; + + /* Char-Output */ + /* It is not required to decrement textlength, as it was already checked, that + there is enough space for the complete output */ + dlt_print_char_string(&text,textlength,(uint8_t*)(ptr+(lines*DLT_COMMON_HEX_CHARS)),DLT_COMMON_HEX_CHARS); + + if (html==0) + { + sprintf(text,"\n"); + text+=DLT_COMMON_CHARLEN; + } + else + { + sprintf(text,"<BR>"); + text+=(4*DLT_COMMON_CHARLEN); + } + } + + /* print partial line */ + rest = size % DLT_COMMON_HEX_CHARS; + + if (rest>0) + { + /* Line number */ + sprintf(text,"%.6x: ", (size / DLT_COMMON_HEX_CHARS) * DLT_COMMON_HEX_CHARS); + text+=DLT_COMMON_HEX_LINELEN; /* 'XXXXXX: ' */ + + /* Hex-Output */ + /* It is not required to decrement textlength, as it was already checked, that + there is enough space for the complete output */ + dlt_print_hex_string(text,textlength,(uint8_t*)(ptr+ ((size / DLT_COMMON_HEX_CHARS) * DLT_COMMON_HEX_CHARS)),rest); + text+=2*rest+(rest-1); + + for (i=0;i<(DLT_COMMON_HEX_CHARS-rest);i++) + { + sprintf(text," xx"); + text+=(3*DLT_COMMON_CHARLEN); + } + + sprintf(text," "); + text+=DLT_COMMON_CHARLEN; + + /* Char-Output */ + /* It is not required to decrement textlength, as it was already checked, that + there is enough space for the complete output */ + dlt_print_char_string(&text,textlength,(uint8_t*)(ptr+ ((size / DLT_COMMON_HEX_CHARS) * DLT_COMMON_HEX_CHARS)),rest); + } + + return 0; +} + +int dlt_print_char_string(char **text,int textlength,uint8_t *ptr,int size) +{ + int num; + + if (text==0) + { + return -1; + } + + if ((ptr==0) || (*text==0) || (textlength<=0) || (size<0)) + { + return -1; + } + + if (textlength< size) + { + dlt_log(LOG_ERR, "String does not fit character data!\n"); + return -1; + } + + for (num=0;num<size;num++) + { + if ( (((char*)ptr)[num]<DLT_COMMON_ASCII_CHAR_SPACE) || (((char*)ptr)[num]>DLT_COMMON_ASCII_CHAR_TILDE) ) + { + sprintf(*text,"."); + } + else + { + /* replace < with . */ + if (((char*)ptr)[num]!=DLT_COMMON_ASCII_CHAR_LT) + { + sprintf(*text,"%c",((char *)ptr)[num]); + } + else + { + sprintf(*text,"."); + } + } + (*text)++; + } + + return 0; +} + +void dlt_print_id(char *text,const char *id) +{ + int i, len; + + if (text==0) + { + return; + } + + /* Initialize text */ + for (i=0; i<DLT_ID_SIZE; i++) + { + text[i]='-'; + } + + text[DLT_ID_SIZE] = 0; + + len = ((strlen(id)<=DLT_ID_SIZE)?strlen(id):DLT_ID_SIZE); + + /* Check id*/ + for (i=0; i<len; i++) + text[i] = id[i]; +} + +void dlt_set_id(char *id,const char *text) +{ + id[0] = 0; + id[1] = 0; + id[2] = 0; + id[3] = 0; + + if (text==0) + { + return; + } + + if (text[0]!=0) + { + id[0] = text[0]; + } + else + { + return; + } + + if (text[1]!=0) + { + id[1] = text[1]; + } + else + { + return; + } + + if (text[2]!=0) + { + id[2] = text[2]; + } + else + { + return; + } + + if (text[3]!=0) + { + id[3] = text[3]; + } + else + { + return; + } +} + +void dlt_clean_string(char *text,int length) +{ + int num; + + if (text==0) + { + return; + } + + for (num=0;num<length;num++) + { + if (text[num]=='\r' || text[num]=='\n') + { + text[num] = ' '; + } + } +} + +int dlt_filter_init(DltFilter *filter,int verbose) +{ + PRINT_FUNCTION_VERBOSE(verbose); + + if (filter==0) + { + return -1; + } + + filter->counter = 0; + + return 0; +} + +int dlt_filter_free(DltFilter *filter,int verbose) +{ + PRINT_FUNCTION_VERBOSE(verbose); + + if (filter==0) + { + return -1; + } + + return 0; +} + +int dlt_filter_load(DltFilter *filter,const char *filename,int verbose) +{ + FILE *handle; + char str1[DLT_COMMON_BUFFER_LENGTH]; + char apid[DLT_ID_SIZE],ctid[DLT_ID_SIZE]; + + PRINT_FUNCTION_VERBOSE(verbose); + + if (filter==0) + { + return -1; + } + + handle = fopen(filename,"r"); + if (handle == 0) + { + sprintf(str,"Filter file %s cannot be opened!\n",filename); + dlt_log(LOG_ERR, str); + return -1; + } + + /* Reset filters */ + filter->counter=0; + + while (!feof(handle)) + { + str1[0]=0; + if (fscanf(handle,"%s",str1)!=1) + { + break; + } + if (str1[0]==0) + { + break; + } + printf(" %s",str1); + if (strcmp(str1,"----")==0) + { + dlt_set_id(apid,""); + } + else + { + dlt_set_id(apid,str1); + } + + str1[0]=0; + if (fscanf(handle,"%s",str1)!=1) + { + break; + } + if (str1[0]==0) + { + break; + } + printf(" %s\r\n",str1); + if (strcmp(str1,"----")==0) + { + dlt_set_id(ctid,""); + } + else + { + dlt_set_id(ctid,str1); + } + + if (filter->counter<DLT_FILTER_MAX) + { + dlt_filter_add(filter,apid,ctid,verbose); + } + else + { + sprintf(str, "Maximum number (%d) of allowed filters reached!\n", DLT_FILTER_MAX); + dlt_log(LOG_ERR, str); + return 0; + } + } + + fclose(handle); + + return 0; +} + +int dlt_filter_save(DltFilter *filter,const char *filename,int verbose) +{ + FILE *handle; + int num; + char buf[DLT_COMMON_BUFFER_LENGTH]; + + PRINT_FUNCTION_VERBOSE(verbose); + + if (filter==0) + { + return -1; + } + + handle = fopen(filename,"w"); + if (handle == 0) + { + sprintf(str,"Filter file %s cannot be opened!\n",filename); + dlt_log(LOG_ERR, str); + return -1; + } + + for (num=0;num<filter->counter;num++) + { + if (filter->apid[num][0]==0) + { + fprintf(handle,"---- "); + } + else + { + dlt_print_id(buf,filter->apid[num]); + fprintf(handle,"%s ",buf); + } + if (filter->ctid[num][0]==0) + { + fprintf(handle,"---- "); + } + else + { + dlt_print_id(buf,filter->ctid[num]); + fprintf(handle,"%s ",buf); + } + } + + fclose(handle); + + return 0; +} + +int dlt_filter_find(DltFilter *filter,const char *apid,const char *ctid, int verbose) +{ + int num; + + PRINT_FUNCTION_VERBOSE(verbose); + + if ((filter==0) || (apid==0)) + { + return -1; + } + + for (num=0; num<filter->counter; num++) + { + if (memcmp(filter->apid[num],apid,DLT_ID_SIZE)==0) + { + /* apid matches, now check for ctid */ + if (ctid==0) + { + /* check if empty ctid matches */ + if (memcmp(filter->ctid[num],"",DLT_ID_SIZE)==0) + { + return num; + } + } + else + { + if (memcmp(filter->ctid[num],ctid,DLT_ID_SIZE)==0) + { + return num; + } + } + } + } + + return -1; /* Not found */ +} + +int dlt_filter_add(DltFilter *filter,const char *apid,const char *ctid, int verbose) +{ + PRINT_FUNCTION_VERBOSE(verbose); + + if ((filter==0) || (apid==0)) + { + return -1; + } + + if (filter->counter >= DLT_FILTER_MAX) + { + dlt_log(LOG_ERR, "Maximum numbers of allowed filters reached!\n"); + return -1; + } + + /* add each filter (apid, ctid) only once to filter array */ + if (dlt_filter_find(filter,apid,ctid,verbose)<0) + { + /* filter not found, so add it to filter array */ + if (filter->counter<DLT_FILTER_MAX) + { + dlt_set_id(filter->apid[filter->counter],apid); + dlt_set_id(filter->ctid[filter->counter],(ctid?ctid:"")); + + filter->counter++; + + return 0; + } + } + + return -1; +} + +int dlt_filter_delete(DltFilter *filter,const char *apid,const char *ctid, int verbose) +{ + int j,k; + int found=0; + + PRINT_FUNCTION_VERBOSE(verbose); + + if ((filter==0) || (apid==0)) + { + return -1; + } + + if (filter->counter>0) + { + /* Get first occurence of apid and ctid in filter array */ + for (j=0; j<filter->counter; j++) + { + if ((memcmp(filter->apid[j],apid,DLT_ID_SIZE)==0) && + (memcmp(filter->ctid[j],ctid,DLT_ID_SIZE)==0) + ) + + { + found=1; + break; + } + } + + if (found) + { + /* j is index */ + /* Copy from j+1 til end to j til end-1 */ + + dlt_set_id(filter->apid[j],""); + dlt_set_id(filter->ctid[j],""); + + for (k=j; k<(filter->counter-1); k++) + { + dlt_set_id(filter->apid[k],filter->apid[k+1]); + dlt_set_id(filter->ctid[k],filter->ctid[k+1]); + } + + filter->counter--; + return 0; + } + } + + return -1; +} + +int dlt_message_init(DltMessage *msg,int verbose) +{ + PRINT_FUNCTION_VERBOSE(verbose); + + if (msg==0) + { + return -1; + } + + /* initalise structure parameters */ + msg->headersize = 0; + msg->datasize = 0; + + msg->databuffer = 0; + + msg->storageheader = 0; + msg->standardheader = 0; + msg->extendedheader = 0; + + msg->found_serialheader = 0; + + return 0; +} + +int dlt_message_free(DltMessage *msg,int verbose) +{ + PRINT_FUNCTION_VERBOSE(verbose); + + if (msg==0) + { + return -1; + } + /* delete databuffer if exists */ + if (msg->databuffer) + { + free(msg->databuffer); + } + msg->databuffer = 0; + + return 0; +} + +int dlt_message_header(DltMessage *msg,char *text,int textlength,int verbose) +{ + return dlt_message_header_flags(msg,text,textlength,DLT_HEADER_SHOW_ALL,verbose); +} + +int dlt_message_header_flags(DltMessage *msg,char *text,int textlength,int flags, int verbose) +{ + struct tm * timeinfo; + char buffer [DLT_COMMON_BUFFER_LENGTH]; + + PRINT_FUNCTION_VERBOSE(verbose); + + if ((msg==0) || (text==0) || (textlength<=0)) + { + return -1; + } + + if ((flags<DLT_HEADER_SHOW_NONE) || (flags>DLT_HEADER_SHOW_ALL)) + { + return -1; + } + + text[0] = 0; + + if ((flags & DLT_HEADER_SHOW_TIME) == DLT_HEADER_SHOW_TIME) + { + /* print received time */ + timeinfo = localtime ((const time_t*)(&(msg->storageheader->seconds))); + + if (timeinfo!=0) + { + strftime (buffer,sizeof(buffer),"%Y/%m/%d %H:%M:%S",timeinfo); + sprintf(text,"%s.%.6d ",buffer,msg->storageheader->microseconds); + } + } + + if ((flags & DLT_HEADER_SHOW_TMSTP) == DLT_HEADER_SHOW_TMSTP) + { + /* print timestamp if available */ + if ( DLT_IS_HTYP_WTMS(msg->standardheader->htyp) ) + { + sprintf(text+strlen(text),"%10u ",msg->headerextra.tmsp); + } + else + { + sprintf(text+strlen(text),"---------- "); + } + } + + if ((flags & DLT_HEADER_SHOW_MSGCNT) == DLT_HEADER_SHOW_MSGCNT) + { + /* print message counter */ + sprintf(text+strlen(text),"%.3d ",msg->standardheader->mcnt); + } + + if ((flags & DLT_HEADER_SHOW_ECUID) == DLT_HEADER_SHOW_ECUID) + { + /* print ecu id, use header extra if available, else storage header value */ + if ( DLT_IS_HTYP_WEID(msg->standardheader->htyp) ) + { + dlt_print_id(text+strlen(text),msg->headerextra.ecu); + } + else + { + dlt_print_id(text+strlen(text),msg->storageheader->ecu); + } + } + + /* print app id and context id if extended header available, else '----' */# + if ((flags & DLT_HEADER_SHOW_APID) == DLT_HEADER_SHOW_APID) + { + sprintf(text+strlen(text)," "); + if ((DLT_IS_HTYP_UEH(msg->standardheader->htyp)) && (msg->extendedheader->apid[0]!=0)) + { + dlt_print_id(text+strlen(text),msg->extendedheader->apid); + } + else + { + sprintf(text+strlen(text),"----"); + } + + sprintf(text+strlen(text)," "); + } + + if ((flags & DLT_HEADER_SHOW_CTID) == DLT_HEADER_SHOW_CTID) + { + if ((DLT_IS_HTYP_UEH(msg->standardheader->htyp)) && (msg->extendedheader->ctid[0]!=0)) + { + dlt_print_id(text+strlen(text),msg->extendedheader->ctid); + } + else + { + sprintf(text+strlen(text),"----"); + } + + sprintf(text+strlen(text)," "); + } + + /* print info about message type and length */ + if (DLT_IS_HTYP_UEH(msg->standardheader->htyp)) + { + if ((flags & DLT_HEADER_SHOW_MSGTYPE) == DLT_HEADER_SHOW_MSGTYPE) + { + sprintf(text+strlen(text),"%s",message_type[DLT_GET_MSIN_MSTP(msg->extendedheader->msin)]); + sprintf(text+strlen(text)," "); + } + + if ((flags & DLT_HEADER_SHOW_MSGSUBTYPE) == DLT_HEADER_SHOW_MSGSUBTYPE) + { + if ((DLT_GET_MSIN_MSTP(msg->extendedheader->msin))==DLT_TYPE_LOG) + { + sprintf(text+strlen(text),"%s",log_info[DLT_GET_MSIN_MTIN(msg->extendedheader->msin)]); + } + + if ((DLT_GET_MSIN_MSTP(msg->extendedheader->msin))==DLT_TYPE_APP_TRACE) + { + sprintf(text+strlen(text),"%s",trace_type[DLT_GET_MSIN_MTIN(msg->extendedheader->msin)]); + } + + if ((DLT_GET_MSIN_MSTP(msg->extendedheader->msin))==DLT_TYPE_NW_TRACE) + { + sprintf(text+strlen(text),"%s",nw_trace_type[DLT_GET_MSIN_MTIN(msg->extendedheader->msin)]); + } + + if ((DLT_GET_MSIN_MSTP(msg->extendedheader->msin))==DLT_TYPE_CONTROL) + { + sprintf(text+strlen(text),"%s",control_type[DLT_GET_MSIN_MTIN(msg->extendedheader->msin)]); + } + + sprintf(text+strlen(text)," "); + } + + if ((flags & DLT_HEADER_SHOW_VNVSTATUS) == DLT_HEADER_SHOW_VNVSTATUS) + { + /* print verbose status pf message */ + if (DLT_IS_MSIN_VERB(msg->extendedheader->msin)) + { + sprintf(text+strlen(text),"V"); + } + else + { + sprintf(text+strlen(text),"N"); + } + + sprintf(text+strlen(text)," "); + } + + if ((flags & DLT_HEADER_SHOW_NOARG) == DLT_HEADER_SHOW_NOARG) + { + /* print number of arguments */ + sprintf(text+strlen(text),"%d", msg->extendedheader->noar); + } + + } + else + { + if ((flags & DLT_HEADER_SHOW_MSGTYPE) == DLT_HEADER_SHOW_MSGTYPE) + { + sprintf(text+strlen(text),"--- "); + } + + if ((flags & DLT_HEADER_SHOW_MSGSUBTYPE) == DLT_HEADER_SHOW_MSGSUBTYPE) + { + sprintf(text+strlen(text),"--- "); + } + + if ((flags & DLT_HEADER_SHOW_VNVSTATUS) == DLT_HEADER_SHOW_VNVSTATUS) + { + sprintf(text+strlen(text),"N "); + } + + if ((flags & DLT_HEADER_SHOW_NOARG) == DLT_HEADER_SHOW_NOARG) + { + sprintf(text+strlen(text),"-"); + } + } + + return 0; +} + +int dlt_message_payload(DltMessage *msg,char *text,int textlength,int type,int verbose) +{ + uint32_t id=0,id_tmp=0; + uint8_t retval=0; + + uint8_t *ptr; + int32_t datalength; + + /* Pointer to ptr and datalength */ + uint8_t **pptr; + int32_t *pdatalength; + + int ret=0; + + int num; + uint32_t type_info=0,type_info_tmp=0; + + PRINT_FUNCTION_VERBOSE(verbose); + + if ((msg==0) || (text==0)) + { + return -1; + } + + if (textlength<=0) + { + dlt_log(LOG_ERR, "String does not fit binary data!\n"); + return -1; + } + + /* start with empty string */ + text[0] = 0; + + /* print payload only as hex */ + if (type==DLT_OUTPUT_HEX) + { + return dlt_print_hex_string(text,textlength,msg->databuffer,msg->datasize); + } + + /* print payload as mixed */ + if (type==DLT_OUTPUT_MIXED_FOR_PLAIN) + { + return dlt_print_mixed_string(text,textlength,msg->databuffer,msg->datasize,0); + } + + if (type==DLT_OUTPUT_MIXED_FOR_HTML) + { + return dlt_print_mixed_string(text,textlength,msg->databuffer,msg->datasize,1); + } + + ptr = msg->databuffer; + datalength = msg->datasize; + + /* Pointer to ptr and datalength */ + pptr = &ptr; + pdatalength = &datalength; + + /* non-verbose mode */ + + /* print payload as hex */ + if (DLT_MSG_IS_NONVERBOSE(msg)) + { + + DLT_MSG_READ_VALUE(id_tmp,ptr,datalength,uint32_t); + id=DLT_ENDIAN_GET_32(msg->standardheader->htyp, id_tmp); + + if (textlength<((datalength*3)+20)) + { + dlt_log(LOG_ERR, "String does not fit binary data!\n"); + return -1; + } + + /* process message id / service id */ + if (DLT_MSG_IS_CONTROL(msg)) + { + if (id > 0 && id <= DLT_SERVICE_ID_MESSAGE_BUFFER_OVERFLOW) + { + sprintf(text+strlen(text),"%s",service_id[id]); /* service id */ + } + else + { + if (!(DLT_MSG_IS_CONTROL_TIME(msg))) + { + sprintf(text+strlen(text),"service(%u)",id); /* service id */ + } + } + + if (datalength>0) + { + sprintf(text+strlen(text),", "); + } + } + else + { + sprintf(text+strlen(text),"%u, ",id); /* message id */ + } + + /* process return value */ + if (DLT_MSG_IS_CONTROL_RESPONSE(msg)) + { + if (datalength>0) + { + DLT_MSG_READ_VALUE(retval,ptr,datalength,uint8_t); /* No endian conversion necessary */ + if ( (retval<3) || (retval==8)) + { + sprintf(text+strlen(text),"%s",return_type[retval]); + } + else + { + sprintf(text+strlen(text),"%.2x",retval); + } + + if (datalength>=1) + { + sprintf(text+strlen(text),", "); + } + } + } + + if (type==DLT_OUTPUT_ASCII_LIMITED) + { + ret=dlt_print_hex_string(text+strlen(text),textlength-strlen(text),ptr, + (datalength>DLT_COMMON_ASCII_LIMIT_MAX_CHARS?DLT_COMMON_ASCII_LIMIT_MAX_CHARS:datalength)); + if ((datalength>DLT_COMMON_ASCII_LIMIT_MAX_CHARS) && + ((textlength-strlen(text))>4)) + { + sprintf(text+strlen(text)," ..."); + } + } + else + { + ret=dlt_print_hex_string(text+strlen(text),textlength-strlen(text),ptr,datalength); + } + + return ret; + } + + /* At this point, it is ensured that a extended header is available */ + + /* verbose mode */ + type_info=0; + type_info_tmp=0; + + for (num=0;num<(int)(msg->extendedheader->noar);num++) + { + if (num!=0) + { + sprintf(text+strlen(text)," "); + } + + /* first read the type info of the argument */ + DLT_MSG_READ_VALUE(type_info_tmp,ptr,datalength,uint32_t); + type_info=DLT_ENDIAN_GET_32(msg->standardheader->htyp, type_info_tmp); + + /* print out argument */ + if (dlt_message_argument_print(msg, type_info, pptr, pdatalength, text, textlength, -1, 0)==-1) + { + return -1; + } + } + + return 0; +} + +int dlt_message_filter_check(DltMessage *msg,DltFilter *filter,int verbose) +{ + /* check the filters if message is used */ + int num; + int found = 0; + + PRINT_FUNCTION_VERBOSE(verbose); + + if ((msg==0) || (filter==0)) + { + return -1; + } + + if ((filter->counter==0) || (!(DLT_IS_HTYP_UEH(msg->standardheader->htyp)))) + { + /* no filter is set, or no extended header is available, so do as filter is matching */ + return 1; + } + + for (num=0;num<filter->counter;num++) + { + /* check each filter if it matches */ + if ((DLT_IS_HTYP_UEH(msg->standardheader->htyp)) && + (filter->apid[num][0]==0 || memcmp(filter->apid[num],msg->extendedheader->apid,DLT_ID_SIZE)==0) && + (filter->ctid[num][0]==0 || memcmp(filter->ctid[num],msg->extendedheader->ctid,DLT_ID_SIZE)==0) ) + { + found = 1; + break; + } + } + + return found; +} + +int dlt_message_read(DltMessage *msg,uint8_t *buffer,unsigned int length,int resync, int verbose) +{ + int extra_size = 0; + + PRINT_FUNCTION_VERBOSE(verbose); + + if ((msg==0) || (buffer==0) || (length<=0)) + { + return -1; + } + + /* initialize resync_offset */ + msg->resync_offset=0; + + /* check if message contains serial header, smaller than standard header */ + if (length<sizeof(dltSerialHeader)) + { + /* dlt_log(LOG_ERR, "Length smaller than serial header!\n"); */ + return -1; + } + + if (memcmp(buffer,dltSerialHeader,sizeof(dltSerialHeader)) == 0) + { + /* serial header found */ + msg->found_serialheader = 1; + buffer += sizeof(dltSerialHeader); + length -= sizeof(dltSerialHeader); + } + else + { + /* serial header not found */ + msg->found_serialheader = 0; + if (resync) + { + /* resync if necessary */ + msg->resync_offset=0; + + do + { + if (memcmp(buffer+msg->resync_offset,dltSerialHeader,sizeof(dltSerialHeader)) == 0) + { + /* serial header found */ + msg->found_serialheader = 1; + buffer += sizeof(dltSerialHeader); + length -= sizeof(dltSerialHeader); + break; + } + + msg->resync_offset++; + } + while ((sizeof(dltSerialHeader)+msg->resync_offset)<=length); + + /* Set new start offset */ + if (msg->resync_offset>0) + { + /* Resyncing connection */ + buffer+=msg->resync_offset; + length-=msg->resync_offset; + } + } + } + + /* check that standard header fits buffer */ + if (length<sizeof(DltStandardHeader)) + { + /* dlt_log(LOG_ERR, "Length smaller than standard header!\n"); */ + return -1; + } + memcpy(msg->headerbuffer+sizeof(DltStorageHeader),buffer,sizeof(DltStandardHeader)); + + /* set ptrs to structures */ + msg->storageheader = (DltStorageHeader*) msg->headerbuffer; + msg->standardheader = (DltStandardHeader*) (msg->headerbuffer + sizeof(DltStorageHeader)); + + /* calculate complete size of headers */ + extra_size = DLT_STANDARD_HEADER_EXTRA_SIZE(msg->standardheader->htyp)+(DLT_IS_HTYP_UEH(msg->standardheader->htyp) ? sizeof(DltExtendedHeader) : 0); + msg->headersize = sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + extra_size; + msg->datasize = DLT_BETOH_16(msg->standardheader->len) - (msg->headersize - sizeof(DltStorageHeader)); + + if (verbose) + { + sprintf(str,"Buffer length: %d\n",length); + dlt_log(LOG_INFO, str); + } + if (verbose) + { + sprintf(str,"Header Size: %d\n",msg->headersize); + dlt_log(LOG_INFO, str); + } + if (verbose) + { + sprintf(str,"Data Size: %d\n",msg->datasize); + dlt_log(LOG_INFO, str); + } + + /* check data size */ + if (msg->datasize < 0) + { + sprintf(str,"Plausibility check failed. Complete message size too short (%d)!\n",msg->datasize); + dlt_log(LOG_ERR, str); + return -1; + } + + /* load standard header extra parameters and Extended header if used */ + if (extra_size>0) + { + if (length < (msg->headersize - sizeof(DltStorageHeader))) + { + return -1; + } + + memcpy(msg->headerbuffer+sizeof(DltStorageHeader)+sizeof(DltStandardHeader),buffer+sizeof(DltStandardHeader),extra_size); + + /* set extended header ptr and get standard header extra parameters */ + if (DLT_IS_HTYP_UEH(msg->standardheader->htyp)) + { + msg->extendedheader = (DltExtendedHeader*) (msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + + DLT_STANDARD_HEADER_EXTRA_SIZE(msg->standardheader->htyp)); + } + else + { + msg->extendedheader = 0; + } + + dlt_message_get_extraparameters(msg,verbose); + } + + /* check if payload fits length */ + if (length < (msg->headersize - sizeof(DltStorageHeader) + msg->datasize)) + { + /* dlt_log(LOG_ERR,"length does not fit!\n"); */ + return -1; + } + + /* free last used memory for buffer */ + if (msg->databuffer) + { + free(msg->databuffer); + } + + /* get new memory for buffer */ + msg->databuffer = (uint8_t *)malloc(msg->datasize); + if (msg->databuffer == 0) + { + sprintf(str,"Cannot allocate memory for payload buffer of size %d!\n",msg->datasize); + dlt_log(LOG_ERR, str); + return -1; + } + + /* load payload data from buffer */ + memcpy(msg->databuffer,buffer+(msg->headersize-sizeof(DltStorageHeader)),msg->datasize); + + return 0; +} + +int dlt_message_get_extraparameters(DltMessage *msg,int verbose) +{ + PRINT_FUNCTION_VERBOSE(verbose); + + if (msg==0) + { + return -1; + } + + if (DLT_IS_HTYP_WEID(msg->standardheader->htyp)) + { + memcpy(msg->headerextra.ecu,msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader),DLT_ID_SIZE); + } + + if (DLT_IS_HTYP_WSID(msg->standardheader->htyp)) + { + memcpy(&(msg->headerextra.seid),msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + + (DLT_IS_HTYP_WEID(msg->standardheader->htyp) ? DLT_SIZE_WEID : 0), DLT_SIZE_WSID); + msg->headerextra.seid = DLT_BETOH_32(msg->headerextra.seid); + } + + if (DLT_IS_HTYP_WTMS(msg->standardheader->htyp)) + { + memcpy(&(msg->headerextra.tmsp),msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + + (DLT_IS_HTYP_WEID(msg->standardheader->htyp) ? DLT_SIZE_WEID : 0) + + (DLT_IS_HTYP_WSID(msg->standardheader->htyp) ? DLT_SIZE_WSID : 0),DLT_SIZE_WTMS); + msg->headerextra.tmsp = DLT_BETOH_32(msg->headerextra.tmsp); + } + + return 0; +} + +int dlt_message_set_extraparameters(DltMessage *msg,int verbose) +{ + PRINT_FUNCTION_VERBOSE(verbose); + + if (msg==0) + { + return -1; + } + + if (DLT_IS_HTYP_WEID(msg->standardheader->htyp)) + { + memcpy(msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader),msg->headerextra.ecu,DLT_ID_SIZE); + } + + if (DLT_IS_HTYP_WSID(msg->standardheader->htyp)) + { + msg->headerextra.seid = DLT_HTOBE_32(msg->headerextra.seid); + memcpy(msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + + (DLT_IS_HTYP_WEID(msg->standardheader->htyp) ? DLT_SIZE_WEID : 0), &(msg->headerextra.seid),DLT_SIZE_WSID); + } + + if (DLT_IS_HTYP_WTMS(msg->standardheader->htyp)) + { + msg->headerextra.tmsp = DLT_HTOBE_32(msg->headerextra.tmsp); + memcpy(msg->headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + + (DLT_IS_HTYP_WEID(msg->standardheader->htyp) ? DLT_SIZE_WEID : 0) + + (DLT_IS_HTYP_WSID(msg->standardheader->htyp) ? DLT_SIZE_WSID : 0), &(msg->headerextra.tmsp),DLT_SIZE_WTMS); + } + + return 0; +} + +int dlt_file_init(DltFile *file,int verbose) +{ + PRINT_FUNCTION_VERBOSE(verbose); + + if (file==0) + { + return -1; + } + + /* initalise structure parameters */ + file->handle = 0; + file->counter = 0; + file->counter_total = 0; + file->index = 0; + + file->filter = 0; + file->filter_counter = 0; + file->file_position = 0; + + file->position = 0; + + file->error_messages = 0; + + return dlt_message_init(&(file->msg),verbose); +} + +int dlt_file_set_filter(DltFile *file,DltFilter *filter,int verbose) +{ + PRINT_FUNCTION_VERBOSE(verbose); + + if (file==0) + { + return -1; + } + + /* set filter */ + file->filter = filter; + + return 0; +} + +int dlt_file_read_header(DltFile *file,int verbose) +{ + PRINT_FUNCTION_VERBOSE(verbose); + + if (file==0) + { + return -1; + } + + /* load header from file */ + if (fread(file->msg.headerbuffer,sizeof(DltStorageHeader)+sizeof(DltStandardHeader),1,file->handle)!=1) + { + if (!feof(file->handle)) + { + dlt_log(LOG_ERR, "Cannot read header from file!\n"); + } + return -1; + } + + /* set ptrs to structures */ + file->msg.storageheader = (DltStorageHeader*) file->msg.headerbuffer; + file->msg.standardheader = (DltStandardHeader*) (file->msg.headerbuffer + sizeof(DltStorageHeader)); + + /* check id of storage header */ + if (dlt_check_storageheader(file->msg.storageheader)==0) + { + dlt_log(LOG_ERR, "DLT storage header pattern not found!\n"); + return -1; + } + + /* calculate complete size of headers */ + file->msg.headersize = sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + + DLT_STANDARD_HEADER_EXTRA_SIZE(file->msg.standardheader->htyp) + (DLT_IS_HTYP_UEH(file->msg.standardheader->htyp) ? sizeof(DltExtendedHeader) : 0); + file->msg.datasize = DLT_BETOH_16(file->msg.standardheader->len) + sizeof(DltStorageHeader) - file->msg.headersize; + if (verbose) + { + sprintf(str,"Header Size: %d\n",file->msg.headersize); + dlt_log(LOG_INFO, str); + } + if (verbose) + { + sprintf(str,"Data Size: %d\n",file->msg.datasize); + dlt_log(LOG_INFO, str); + } + + /* check data size */ + if (file->msg.datasize < 0) + { + sprintf(str,"Plausibility check failed. Complete message size too short! (%d)\n", file->msg.datasize); + dlt_log(LOG_ERR, str); + return -1; + } + + return 0; +} + +int dlt_file_read_header_raw(DltFile *file,int resync,int verbose) +{ + char dltSerialHeaderBuffer[DLT_ID_SIZE]; + + PRINT_FUNCTION_VERBOSE(verbose); + + if (file==0) + { + return -1; + } + + /* check if serial header exists, ignore if found */ + if (fread(dltSerialHeaderBuffer,sizeof(dltSerialHeaderBuffer),1,file->handle)!=1) + { + /* cannot read serial header, not enough data available in file */ + if (!feof(file->handle)) + { + dlt_log(LOG_ERR, "Cannot read header from file!\n"); + } + return -1; + } + if (memcmp(dltSerialHeaderBuffer,dltSerialHeader,sizeof(dltSerialHeader)) == 0) + { + /* serial header found */ + /* nothing to do continue reading */ + + } + else + { + /* serial header not found */ + if(resync) + { + /* increase error counter */ + file->error_messages++; + + /* resync to serial header */ + do + { + memmove(dltSerialHeaderBuffer,dltSerialHeaderBuffer+1,sizeof(dltSerialHeader)-1); + if (fread(dltSerialHeaderBuffer+3,1,1,file->handle)!=1) + { + /* cannot read any data, perhaps end of file reached */ + return -1; + } + if (memcmp(dltSerialHeaderBuffer,dltSerialHeader,sizeof(dltSerialHeader)) == 0) + { + /* serial header synchronised */ + break; + } + } while(1); + } + else + { + /* go back to last file position */ + fseek(file->handle,file->file_position,SEEK_SET); + } + } + + /* load header from file */ + if (fread(file->msg.headerbuffer+sizeof(DltStorageHeader),sizeof(DltStandardHeader),1,file->handle)!=1) + { + if (!feof(file->handle)) + { + dlt_log(LOG_ERR, "Cannot read header from file!\n"); + } + return -1; + } + + /* set ptrs to structures */ + file->msg.storageheader = (DltStorageHeader*) file->msg.headerbuffer; // this points now to a empty storage header (filled with '0') + file->msg.standardheader = (DltStandardHeader*) (file->msg.headerbuffer + sizeof(DltStorageHeader)); + + /* Skip storage header field, fill this field with '0' */ + memset(file->msg.storageheader,0,sizeof(DltStorageHeader)); + + /* Set storage header */ + dlt_set_storageheader(file->msg.storageheader,DLT_COMMON_DUMMY_ECUID); + + /* no check for storage header id*/ + + /* calculate complete size of headers */ + file->msg.headersize = sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + + DLT_STANDARD_HEADER_EXTRA_SIZE(file->msg.standardheader->htyp) + (DLT_IS_HTYP_UEH(file->msg.standardheader->htyp) ? sizeof(DltExtendedHeader) : 0); + file->msg.datasize = DLT_BETOH_16(file->msg.standardheader->len) + sizeof(DltStorageHeader) - file->msg.headersize; + if (verbose) + { + sprintf(str,"Header Size: %d\n",file->msg.headersize); + dlt_log(LOG_INFO, str); + } + if (verbose) + { + sprintf(str,"Data Size: %d\n",file->msg.datasize); + dlt_log(LOG_INFO, str); + } + + /* check data size */ + if (file->msg.datasize < 0) + { + sprintf(str,"Plausibility check failed. Complete message size too short! (%d)\n", file->msg.datasize); + dlt_log(LOG_ERR, str); + return -1; + } + + return 0; +} + +int dlt_file_read_header_extended(DltFile *file, int verbose) +{ + PRINT_FUNCTION_VERBOSE(verbose); + + if (file==0) + { + return -1; + } + + /* load standard header extra parameters if used */ + if (DLT_STANDARD_HEADER_EXTRA_SIZE(file->msg.standardheader->htyp)) + { + if (fread(file->msg.headerbuffer+sizeof(DltStorageHeader)+sizeof(DltStandardHeader), + DLT_STANDARD_HEADER_EXTRA_SIZE(file->msg.standardheader->htyp), + 1,file->handle)!=1) + { + dlt_log(LOG_ERR, "Cannot read standard header extra parameters from file!\n"); + return -1; + } + + dlt_message_get_extraparameters(&(file->msg),verbose); + } + + /* load Extended header if used */ + if (DLT_IS_HTYP_UEH(file->msg.standardheader->htyp)==0) + { + /* there is nothing to be loaded */ + return 0; + } + + if (fread(file->msg.headerbuffer+sizeof(DltStorageHeader)+sizeof(DltStandardHeader)+DLT_STANDARD_HEADER_EXTRA_SIZE(file->msg.standardheader->htyp), + (DLT_IS_HTYP_UEH(file->msg.standardheader->htyp) ? sizeof(DltExtendedHeader) : 0), + 1,file->handle)!=1) + { + dlt_log(LOG_ERR, "Cannot read extended header from file!\n"); + return -1; + } + + /* set extended header ptr */ + if (DLT_IS_HTYP_UEH(file->msg.standardheader->htyp)) + { + file->msg.extendedheader = (DltExtendedHeader*) (file->msg.headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + + DLT_STANDARD_HEADER_EXTRA_SIZE(file->msg.standardheader->htyp)); + } + else + { + file->msg.extendedheader = 0; + } + + return 0; +} + +int dlt_file_read_data(DltFile *file, int verbose) +{ + PRINT_FUNCTION_VERBOSE(verbose); + + if (file==0) + { + return -1; + } + + /* free last used memory for buffer */ + if (file->msg.databuffer) + { + free(file->msg.databuffer); + } + + /* get new memory for buffer */ + file->msg.databuffer = (uint8_t *)malloc(file->msg.datasize); + + if (file->msg.databuffer == 0) + { + sprintf(str,"Cannot allocate memory for payload buffer of size %d!\n",file->msg.datasize); + dlt_log(LOG_ERR, str); + return -1; + } + + /* load payload data from file */ + if (fread(file->msg.databuffer,file->msg.datasize,1,file->handle)!=1) + { + if (file->msg.datasize!=0) + { + sprintf(str,"Cannot read payload data from file of size %d!\n",file->msg.datasize); + dlt_log(LOG_ERR, str); + return -1; + } + } + + return 0; +} + +int dlt_file_open(DltFile *file,const char *filename,int verbose) +{ + PRINT_FUNCTION_VERBOSE(verbose); + + if (file==0) + { + return -1; + } + + /* reset counters */ + file->counter = 0; + file->counter_total = 0; + file->position = 0; + file->file_position = 0; + file->file_length = 0; + file->error_messages = 0; + + if (file->handle) + { + fclose(file->handle); + } + + /* open dlt file */ + file->handle = fopen(filename,"rb"); + if (file->handle == 0) + { + sprintf(str,"File %s cannot be opened!\n",filename); + dlt_log(LOG_ERR, str); + return -1; + } + + fseek(file->handle,0,SEEK_END); + file->file_length = ftell(file->handle); + fseek(file->handle,0,SEEK_SET); + + if (verbose) + { + /* print file length */ + sprintf(str,"File is %lu bytes long\n",file->file_length); + dlt_log(LOG_INFO, str); + } + return 0; +} + +int dlt_file_read(DltFile *file,int verbose) +{ + long *ptr; + int found = 0; + + if (verbose) + { + sprintf(str,"%s: Message %d:\n",__func__, file->counter_total); + dlt_log(LOG_INFO, str); + } + + if (file==0) + { + return -1; + } + + /* allocate new memory for index if number of messages exceeds a multiple of DLT_COMMON_INDEX_ALLOC (e.g.: 1000) */ + if (file->counter % DLT_COMMON_INDEX_ALLOC == 0) + { + ptr = (long *) malloc(((file->counter/DLT_COMMON_INDEX_ALLOC) + 1) * DLT_COMMON_INDEX_ALLOC * sizeof(long)); + + if (ptr==0) + { + return -1; + } + + if (file->index) + { + memcpy(ptr,file->index,file->counter * sizeof(long)); + free(file->index); + } + file->index = ptr; + } + + /* set to end of last succesful read message, because of conflicting calls to dlt_file_read and dlt_file_message */ + fseek(file->handle,file->file_position,SEEK_SET); + + /* get file position at start of DLT message */ + if (verbose) + { + sprintf(str,"Position in file: %ld\n",file->file_position); + dlt_log(LOG_INFO, str); + } + + /* read header */ + if (dlt_file_read_header(file,verbose)<0) + { + /* go back to last position in file */ + fseek(file->handle,file->file_position,SEEK_SET); + return -1; + } + + if (file->filter) + { + /* read the extended header if filter is enabled and extended header exists */ + if (dlt_file_read_header_extended(file, verbose)<0) + { + /* go back to last position in file */ + fseek(file->handle,file->file_position,SEEK_SET); + return-1; + } + + /* check the filters if message is used */ + if (dlt_message_filter_check(&(file->msg),file->filter,verbose) == 1) + { + /* filter matched, consequently store current message */ + /* store index pointer to message position in DLT file */ + file->index[file->counter] = file->file_position; + file->counter++; + file->position = file->counter - 1; + + found = 1; + } + + /* skip payload data */ + if (fseek(file->handle,file->msg.datasize,SEEK_CUR)!=0) + { + /* go back to last position in file */ + fseek(file->handle,file->file_position,SEEK_SET); + sprintf(str,"Seek failed to skip payload data of size %d!\n",file->msg.datasize); + dlt_log(LOG_ERR, str); + return -1; + } + } + else + { + /* filter is disabled */ + /* skip additional header parameters and payload data */ + if (fseek(file->handle,file->msg.headersize - sizeof(DltStorageHeader) - sizeof(DltStandardHeader) + file->msg.datasize,SEEK_CUR)) + { + /* go back to last position in file */ + fseek(file->handle,file->file_position,SEEK_SET); + sprintf(str,"Seek failed to skip extra header and payload data from file of size %d!\n", + file->msg.headersize - sizeof(DltStorageHeader) - sizeof(DltStandardHeader) + file->msg.datasize); + dlt_log(LOG_ERR, str); + return -1; + } + + /* store index pointer to message position in DLT file */ + file->index[file->counter] = file->file_position; + file->counter++; + file->position = file->counter - 1; + + found = 1; + } + + /* increase total message counter */ + file->counter_total++; + + /* store position to next message */ + file->file_position = ftell(file->handle); + + return found; +} + +int dlt_file_read_raw(DltFile *file,int resync, int verbose) +{ + int found = 0; + long *ptr; + + if (verbose) + { + sprintf(str,"%s: Message %d:\n",__func__, file->counter_total); + dlt_log(LOG_INFO, str); + } + + if (file==0) + return -1; + + /* allocate new memory for index if number of messages exceeds a multiple of DLT_COMMON_INDEX_ALLOC (e.g.: 1000) */ + if (file->counter % DLT_COMMON_INDEX_ALLOC == 0) + { + ptr = (long *) malloc(((file->counter/DLT_COMMON_INDEX_ALLOC) + 1) * DLT_COMMON_INDEX_ALLOC * sizeof(long)); + + if (ptr==0) + { + return -1; + } + + if (file->index) + { + memcpy(ptr,file->index,file->counter * sizeof(long)); + free(file->index); + } + file->index = ptr; + } + + /* set to end of last succesful read message, because of conflicting calls to dlt_file_read and dlt_file_message */ + fseek(file->handle,file->file_position,SEEK_SET); + + /* get file position at start of DLT message */ + if (verbose) + { + sprintf(str,"Position in file: %ld\n",file->file_position); + dlt_log(LOG_INFO, str); + } + + /* read header */ + if (dlt_file_read_header_raw(file,resync,verbose)<0) + { + /* go back to last position in file */ + fseek(file->handle,file->file_position,SEEK_SET); + return -1; + } + + /* read the extended header if filter is enabled and extended header exists */ + if (dlt_file_read_header_extended(file, verbose)<0) + { + /* go back to last position in file */ + fseek(file->handle,file->file_position,SEEK_SET); + return-1; + } + + if (dlt_file_read_data(file,verbose)<0) + { + /* go back to last position in file */ + fseek(file->handle,file->file_position,SEEK_SET); + return-1; + } + + /* store index pointer to message position in DLT file */ + file->index[file->counter] = file->file_position; + file->counter++; + file->position = file->counter - 1; + + found = 1; + + /* increase total message counter */ + file->counter_total++; + + /* store position to next message */ + file->file_position = ftell(file->handle); + + return found; +} + +int dlt_file_close(DltFile *file,int verbose) +{ + PRINT_FUNCTION_VERBOSE(verbose); + + if (file==0) + { + return -1; + } + + if (file->handle) + { + fclose(file->handle); + } + + file->handle = 0; + + return 0; +} + +int dlt_file_message(DltFile *file,int index,int verbose) +{ + PRINT_FUNCTION_VERBOSE(verbose); + + if (file==0) + { + return -1; + } + + /* check if message is in range */ + if (index >= file->counter) + { + sprintf(str,"Message %d out of range!\r\n",index); + dlt_log(LOG_ERR, str); + return -1; + } + + /* seek to position in file */ + if (fseek(file->handle,file->index[index],SEEK_SET)!=0) + { + sprintf(str,"Seek to message %d to position %ld failed!\r\n",index,file->index[index]); + dlt_log(LOG_ERR, str); + return -1; + } + + /* read all header and payload */ + if (dlt_file_read_header(file,verbose)<0) + { + return -1; + } + + if (dlt_file_read_header_extended(file,verbose)<0) + { + return -1; + } + + if (dlt_file_read_data(file,verbose)<0) + { + return -1; + } + + /* set current position in file */ + file->position = index; + + return 0; +} + +int dlt_file_free(DltFile *file,int verbose) +{ + PRINT_FUNCTION_VERBOSE(verbose); + + if (file==0) + { + return -1; + } + + /* delete index lost if exists */ + if (file->index) + { + free(file->index); + } + file->index = 0; + + /* close file */ + if (file->handle) + { + fclose(file->handle); + } + file->handle = 0; + + return dlt_message_free(&(file->msg),verbose); +} + +void dlt_log_init(int mode) +{ + log_as_daemon = mode; +} + +void dlt_log_free(void) +{ + /* Nothing to be done yet */ +} + +int dlt_log(int prio, char *s) +{ + char logfmtstring[DLT_COMMON_BUFFER_LENGTH]; + + if (s==0) + { + return -1; + } + + switch (prio) + { + case LOG_EMERG: + { + strcpy(logfmtstring,"DLT| EMERGENCY: %s"); + break; + } + case LOG_ALERT: + { + strcpy(logfmtstring,"DLT| ALERT: %s"); + break; + } + case LOG_CRIT: + { + strcpy(logfmtstring,"DLT| CRITICAL: %s"); + break; + } + case LOG_ERR: + { + strcpy(logfmtstring,"DLT| ERROR: %s"); + break; + } + case LOG_WARNING: + { + strcpy(logfmtstring,"DLT| WARNING: %s"); + break; + } + case LOG_NOTICE: + { + strcpy(logfmtstring,"DLT| NOTICE: %s"); + break; + } + case LOG_INFO: + { + strcpy(logfmtstring,"DLT| INFO: %s"); + break; + } + case LOG_DEBUG: + { + strcpy(logfmtstring,"DLT| DEBUG: %s"); + break; + } + default: + { + strcpy(logfmtstring,"DLT| %s"); + break; + } + } + +#if !defined (__WIN32__) && !defined(_MSC_VER) + if (log_as_daemon) + { + openlog("DLT",LOG_PID,LOG_DAEMON); + syslog(prio, logfmtstring, s); + closelog(); + } + else +#endif + { + printf(logfmtstring, s); + } + + return 0; +} + +int dlt_receiver_init(DltReceiver *receiver,int fd, int buffersize) +{ + if (receiver==0) + { + return -1; + } + + receiver->lastBytesRcvd = 0; + receiver->bytesRcvd = 0; + receiver->totalBytesRcvd = 0; + receiver->buffersize = buffersize; + receiver->fd = fd; + receiver->buffer = (char*)malloc(receiver->buffersize); + + if (receiver->buffer == 0) + { + receiver->buf = 0; + return -1; + } + else + { + receiver->buf = receiver->buffer; + } + + return 0; +} + +int dlt_receiver_free(DltReceiver *receiver) +{ + + if (receiver==0) + { + return -1; + } + + if (receiver->buffer) + { + free(receiver->buffer); + } + + receiver->buffer = 0; + receiver->buf = 0; + + return 0; +} + +#ifndef QT_VIEWER +int dlt_receiver_receive_socket(DltReceiver *receiver) +{ + if (receiver==0) + { + return -1; + } + + if (receiver->buffer==0) + { + return -1; + } + + receiver->buf = (char *)receiver->buffer; + receiver->lastBytesRcvd = receiver->bytesRcvd; + + /* wait for data from socket */ + if ((receiver->bytesRcvd = recv(receiver->fd, receiver->buf + receiver->lastBytesRcvd, receiver->buffersize - receiver->lastBytesRcvd , 0)) <= 0) + { + receiver->bytesRcvd = 0; + + return receiver->bytesRcvd; + } /* if */ + + receiver->totalBytesRcvd += receiver->bytesRcvd; + receiver->bytesRcvd += receiver->lastBytesRcvd; + + return receiver->bytesRcvd; +} +#endif + +int dlt_receiver_receive_fd(DltReceiver *receiver) +{ + if (receiver==0) + { + return -1; + } + + if (receiver->buffer==0) + { + return -1; + } + + receiver->buf = (char *)receiver->buffer; + receiver->lastBytesRcvd = receiver->bytesRcvd; + + /* wait for data from fd */ + if ((receiver->bytesRcvd = read(receiver->fd, receiver->buf + receiver->lastBytesRcvd, receiver->buffersize - receiver->lastBytesRcvd)) <= 0) + { + receiver->bytesRcvd = 0; + + return receiver->bytesRcvd; + } /* if */ + + receiver->totalBytesRcvd += receiver->bytesRcvd; + receiver->bytesRcvd += receiver->lastBytesRcvd; + + return receiver->bytesRcvd; +} + +int dlt_receiver_remove(DltReceiver *receiver,int size) +{ + if (receiver==0) + { + return -1; + } + + if (receiver->buf==0) + { + return -1; + } + + receiver->bytesRcvd = receiver->bytesRcvd - size; + receiver->buf = receiver->buf + size; + + return 0; +} + +int dlt_receiver_move_to_begin(DltReceiver *receiver) +{ + if (receiver==0) + { + return -1; + } + + if ((receiver->buffer==0) || (receiver->buf==0)) + { + return -1; + } + + if ((receiver->buffer!=receiver->buf) && (receiver->bytesRcvd!=0)) + { + memmove(receiver->buffer,receiver->buf,receiver->bytesRcvd); + } + + return 0; +} + +int dlt_set_storageheader(DltStorageHeader *storageheader, const char *ecu) +{ + +#if !defined(_MSC_VER) + struct timeval tv; +#endif + + if (storageheader==0) + { + return -1; + } + + /* get time of day */ +#if defined(_MSC_VER) + time(&(storageheader->seconds)); +#else + gettimeofday(&tv, NULL); +#endif + + /* prepare storage header */ + storageheader->pattern[0] = 'D'; + storageheader->pattern[1] = 'L'; + storageheader->pattern[2] = 'T'; + storageheader->pattern[3] = 0x01; + + dlt_set_id(storageheader->ecu,ecu); + + /* Set current time */ +#if defined(_MSC_VER) + storageheader->microseconds = 0; +#else + storageheader->seconds = (time_t)tv.tv_sec; /* value is long */ + storageheader->microseconds = (int32_t)tv.tv_usec; /* value is long */ +#endif + + return 0; +} + +int dlt_check_storageheader(DltStorageHeader *storageheader) +{ + if (storageheader==0) + { + return -1; + } + + return ((storageheader->pattern[0] == 'D') && + (storageheader->pattern[1] == 'L') && + (storageheader->pattern[2] == 'T') && + (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) +{ +#if !defined (__WIN32__) && !defined(_MSC_VER) + struct termios config; + + if (isatty(fd)==0) + { + return -1; + } + + if (tcgetattr(fd, &config) < 0) + { + return -1; + } + + /* Input flags - Turn off input processing + convert break to null byte, no CR to NL translation, + no NL to CR translation, don't mark parity errors or breaks + no input parity check, don't strip high bit off, + no XON/XOFF software flow control + */ + config.c_iflag &= ~(IGNBRK | BRKINT | ICRNL | + INLCR | PARMRK | INPCK | ISTRIP | IXON); + + /* Output flags - Turn off output processing + no CR to NL translation, no NL to CR-NL translation, + no NL to CR translation, no column 0 CR suppression, + no Ctrl-D suppression, no fill characters, no case mapping, + no local output processing + + config.c_oflag &= ~(OCRNL | ONLCR | ONLRET | + ONOCR | ONOEOT| OFILL | OLCUC | OPOST); + */ + config.c_oflag = 0; + + /* No line processing: + echo off, echo newline off, canonical mode off, + extended input processing off, signal chars off + */ + config.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG); + + /* Turn off character processing + clear current char size mask, no parity checking, + no output processing, force 8 bit input + */ + config.c_cflag &= ~(CSIZE | PARENB); + config.c_cflag |= CS8; + + /* One input byte is enough to return from read() + Inter-character timer off + */ + config.c_cc[VMIN] = 1; + config.c_cc[VTIME] = 0; + + /* Communication speed (simple version, using the predefined + constants) + */ + if (cfsetispeed(&config, speed) < 0 || cfsetospeed(&config, speed) < 0) + { + return -1; + } + + /* Finally, apply the configuration + */ + if (tcsetattr(fd, TCSAFLUSH, &config) < 0) + { + return -1; + } + + return 0; +#else + return -1; +#endif +} + +speed_t dlt_convert_serial_speed(int baudrate) +{ +#if !defined (__WIN32__) && !defined(_MSC_VER) + speed_t ret; + + switch (baudrate) + { + case 50: + { + ret = B50; + break; + } + case 75: + { + ret = B75; + break; + } + case 110: + { + ret = B110; + break; + } + case 134: + { + ret = B134; + break; + } + case 150: + { + ret = B150; + break; + } + case 200: + { + ret = B200; + break; + } + case 300: + { + ret = B300; + break; + } + case 600: + { + ret = B600; + break; + } + case 1200: + { + ret = B1200; + break; + } + case 1800: + { + ret = B1800; + break; + } + case 2400: + { + ret = B2400; + break; + } + case 4800: + { + ret = B4800; + break; + } + case 9600: + { + ret = B9600; + break; + } + case 19200: + { + ret = B19200; + break; + } + case 38400: + { + ret = B38400; + break; + } + case 57600: + { + ret = B57600; + break; + } + case 115200: + { + ret = B115200; + break; + } + case 230400: + { + ret = B230400; + break; + } + case 460800: + { + ret = B460800; + break; + } + case 500000: + { + ret = B500000; + break; + } + case 576000: + { + ret = B576000; + break; + } + case 921600: + { + ret = B921600; + break; + } + case 1000000: + { + ret = B1000000; + break; + } + case 1152000: + { + ret = B1152000; + break; + } + case 1500000: + { + ret = B1500000; + break; + } + case 2000000: + { + ret = B2000000; + break; + } + case 2500000: + { + ret = B2500000; + break; + } + case 3000000: + { + ret = B3000000; + break; + } + case 3500000: + { + ret = B3500000; + break; + } + case 4000000: + { + ret = B4000000; + break; + } + default: + { + ret = B115200; + break; + } + } + + return ret; +#else + return 0; +#endif +} + +#endif + +void dlt_get_version(char *buf) +{ + sprintf(buf,"DLT Package Version: %s %s, Package Revision: %s, build on %s %s\n", + PACKAGE_VERSION, PACKAGE_VERSION_STATE, SVN_VERSION, __DATE__ , __TIME__ ); +} + +uint32_t dlt_uptime(void) +{ + +#if defined (__WIN32__) || defined(_MSC_VER) + + return (uint32_t)(GetTickCount()*10); /* GetTickCount() return DWORD */ + +#else + struct timespec ts; + + if (clock_gettime(CLOCK_MONOTONIC,&ts)==0) + { + return (uint32_t)((((ts.tv_sec*1000000)+(ts.tv_nsec/1000)))/100); // in 0.1 ms = 100 us + } + else + { + return 0; + } + +#endif + +} + +int dlt_message_print_header(DltMessage *message, char *text, uint32_t size, int verbose) +{ + if ((message==0) || (text==0)) + { + return -1; + } + + dlt_message_header(message,text,size,verbose); + printf("%s\n",text); + + return 0; +} + +int dlt_message_print_hex(DltMessage *message, char *text, uint32_t size, int verbose) +{ + if ((message==0) || (text==0)) + { + return -1; + } + + dlt_message_header(message,text,size,verbose); + printf("%s ",text); + dlt_message_payload(message,text,size,DLT_OUTPUT_HEX,verbose); + printf("[%s]\n",text); + + return 0; +} + +int dlt_message_print_ascii(DltMessage *message, char *text, uint32_t size, int verbose) +{ + if ((message==0) || (text==0)) + { + return -1; + } + + dlt_message_header(message,text,size,verbose); + printf("%s ",text); + dlt_message_payload(message,text,size,DLT_OUTPUT_ASCII,verbose); + printf("[%s]\n",text); + + return 0; +} + +int dlt_message_print_mixed_plain(DltMessage *message, char *text, uint32_t size, int verbose) +{ + if ((message==0) || (text==0)) + { + return -1; + } + + dlt_message_header(message,text,size,verbose); + printf("%s \n",text); + dlt_message_payload(message,text,size,DLT_OUTPUT_MIXED_FOR_PLAIN,verbose); + printf("[%s]\n",text); + + return 0; +} + +int dlt_message_print_mixed_html(DltMessage *message, char *text, uint32_t size, int verbose) +{ + if ((message==0) || (text==0)) + { + return -1; + } + + dlt_message_header(message,text,size,verbose); + printf("%s \n",text); + dlt_message_payload(message,text,size,DLT_OUTPUT_MIXED_FOR_HTML,verbose); + printf("[%s]\n",text); + + return 0; +} + +int dlt_message_argument_print(DltMessage *msg,uint32_t type_info,uint8_t **ptr,int32_t *datalength,char *text,int textlength,int byteLength,int __attribute__((unused)) verbose) +{ + int16_t length=0,length_tmp=0; /* the macro can set this variable to -1 */ + uint16_t length2=0,length2_tmp=0,length3=0,length3_tmp=0; + + uint8_t value8u=0; + uint16_t value16u=0,value16u_tmp=0; + uint32_t value32u=0,value32u_tmp=0; + uint64_t value64u=0,value64u_tmp=0; + + int8_t value8i=0; + int16_t value16i=0,value16i_tmp=0; + int32_t value32i=0,value32i_tmp=0; + int64_t value64i=0,value64i_tmp=0; + + float32_t value32f=0,value32f_tmp=0; + int32_t value32f_tmp_int32i=0,value32f_tmp_int32i_swaped=0; + float64_t value64f=0,value64f_tmp=0; + int64_t value64f_tmp_int64i=0,value64f_tmp_int64i_swaped=0; + + uint32_t quantisation=0, quantisation_tmp=0; + + if (type_info & DLT_TYPE_INFO_STRG) + { + + /* string type */ + if (byteLength<0) + { + DLT_MSG_READ_VALUE(length_tmp,*ptr,*datalength,uint16_t); + if((*datalength)<0) + return -1; + length=DLT_ENDIAN_GET_16(msg->standardheader->htyp, length_tmp); + } + else + { + length=(int16_t)byteLength; + } + + if (type_info & DLT_TYPE_INFO_VARI) + { + DLT_MSG_READ_VALUE(length2_tmp,*ptr,*datalength,uint16_t); + if((*datalength)<0) + return -1; + length2=DLT_ENDIAN_GET_16(msg->standardheader->htyp, length2_tmp); + if((*datalength)<length2) + return -1; + *ptr += length2; + *datalength-=length2; + } + + DLT_MSG_READ_STRING((text+strlen(text)),*ptr,*datalength,length); + if((*datalength)<0) + return -1; + + } + else if (type_info & DLT_TYPE_INFO_BOOL) + { + /* Boolean type */ + if (type_info & DLT_TYPE_INFO_VARI) + { + DLT_MSG_READ_VALUE(length2_tmp,*ptr,*datalength,uint16_t); + if((*datalength)<0) + return -1; + length2=DLT_ENDIAN_GET_16(msg->standardheader->htyp, length2_tmp); + if((*datalength)<length2) + return -1; + *ptr += length2; + *datalength-=length2; + } + value8u=0; + DLT_MSG_READ_VALUE(value8u,*ptr,*datalength,uint8_t); /* No endian conversion necessary */ + if((*datalength)<0) + return -1; + sprintf(text+strlen(text),"%d",value8u); + } + else if (type_info & DLT_TYPE_INFO_SINT || type_info & DLT_TYPE_INFO_UINT) + { + /* signed or unsigned argument received */ + if (type_info & DLT_TYPE_INFO_VARI) + { + DLT_MSG_READ_VALUE(length2_tmp,*ptr,*datalength,uint16_t); + if((*datalength)<0) + return -1; + length2=DLT_ENDIAN_GET_16(msg->standardheader->htyp, length2_tmp); + DLT_MSG_READ_VALUE(length3_tmp,*ptr,*datalength,uint16_t); + if((*datalength)<0) + return -1; + length3=DLT_ENDIAN_GET_16(msg->standardheader->htyp, length3_tmp); + if((*datalength)<length2) + return -1; + *ptr += length2; + *datalength-=length2; + if((*datalength)<length3) + return -1; + *ptr += length3; + *datalength-=length3; + } + if (type_info & DLT_TYPE_INFO_FIXP) + { + quantisation=0; + quantisation_tmp=0; + DLT_MSG_READ_VALUE(quantisation_tmp,*ptr,*datalength,uint32_t); + if((*datalength)<0) + return -1; + quantisation=DLT_ENDIAN_GET_32(msg->standardheader->htyp, quantisation_tmp); + + switch ( type_info & DLT_TYPE_INFO_TYLE) + { + case DLT_TYLE_8BIT: + case DLT_TYLE_16BIT: + case DLT_TYLE_32BIT: + { + if((*datalength)<4) + return -1; + *ptr += 4; + *datalength-=4; + break; + } + case DLT_TYLE_64BIT: + { + if((*datalength)<8) + return -1; + *ptr += 8; + *datalength-=8; + break; + } + case DLT_TYLE_128BIT: + { + if((*datalength)<16) + return -1; + *ptr += 16; + *datalength-=16; + break; + } + default: + { + return -1; + } + } + } + switch ( type_info & DLT_TYPE_INFO_TYLE) + { + case DLT_TYLE_8BIT: + { + if (type_info & DLT_TYPE_INFO_SINT) + { + value8i=0; + DLT_MSG_READ_VALUE(value8i,*ptr,*datalength,int8_t); /* No endian conversion necessary */ + if((*datalength)<0) + return -1; + sprintf(text+strlen(text),"%d",value8i); + } + else + { + value8u=0; + DLT_MSG_READ_VALUE(value8u,*ptr,*datalength,uint8_t); /* No endian conversion necessary */ + if((*datalength)<0) + return -1; + sprintf(text+strlen(text),"%d",value8u); + } + break; + } + case DLT_TYLE_16BIT: + { + if (type_info & DLT_TYPE_INFO_SINT) + { + value16i=0; + value16i_tmp=0; + DLT_MSG_READ_VALUE(value16i_tmp,*ptr,*datalength,int16_t); + if((*datalength)<0) + return -1; + value16i=DLT_ENDIAN_GET_16(msg->standardheader->htyp, value16i_tmp); + sprintf(text+strlen(text),"%hd",value16i); + } + else + { + value16u=0; + value16u_tmp=0; + DLT_MSG_READ_VALUE(value16u_tmp,*ptr,*datalength,uint16_t); + if((*datalength)<0) + return -1; + value16u=DLT_ENDIAN_GET_16(msg->standardheader->htyp, value16u_tmp); + sprintf(text+strlen(text),"%hu",value16u); + } + break; + } + case DLT_TYLE_32BIT: + { + if (type_info & DLT_TYPE_INFO_SINT) + { + value32i=0; + value32i_tmp=0; + DLT_MSG_READ_VALUE(value32i_tmp,*ptr,*datalength,int32_t); + if((*datalength)<0) + return -1; + value32i=DLT_ENDIAN_GET_32(msg->standardheader->htyp, (uint32_t)value32i_tmp); + sprintf(text+strlen(text),"%d",value32i); + } + else + { + value32u=0; + value32u_tmp=0; + DLT_MSG_READ_VALUE(value32u_tmp,*ptr,*datalength,uint32_t); + if((*datalength)<0) + return -1; + value32u=DLT_ENDIAN_GET_32(msg->standardheader->htyp, value32u_tmp); + sprintf(text+strlen(text),"%u",value32u); + } + break; + } + case DLT_TYLE_64BIT: + { + if (type_info & DLT_TYPE_INFO_SINT) + { + value64i=0; + value64i_tmp=0; + DLT_MSG_READ_VALUE(value64i_tmp,*ptr,*datalength,int64_t); + if((*datalength)<0) + return -1; + value64i=DLT_ENDIAN_GET_64(msg->standardheader->htyp, (uint64_t)value64i_tmp); + #if defined (__WIN32__) && !defined(_MSC_VER) + sprintf(text+strlen(text),"%I64d",value64i); + #else + sprintf(text+strlen(text),"%lld",value64i); + #endif + } + else + { + value64u=0; + value64u_tmp=0; + DLT_MSG_READ_VALUE(value64u_tmp,*ptr,*datalength,uint64_t); + if((*datalength)<0) + return -1; + value64u=DLT_ENDIAN_GET_64(msg->standardheader->htyp, value64u_tmp); + #if defined (__WIN32__) && !defined(_MSC_VER) + sprintf(text+strlen(text),"%I64u",value64u); + #else + sprintf(text+strlen(text),"%llu",value64u); + #endif + } + break; + } + case DLT_TYLE_128BIT: + { + if (*datalength>=16) + dlt_print_hex_string(text+strlen(text),textlength,*ptr,16); + if((*datalength)<16) + return -1; + *ptr += 16; + *datalength-=16; + break; + } + default: + { + return -1; + } + } + } + else if (type_info & DLT_TYPE_INFO_FLOA) + { + /* float data argument */ + if (type_info & DLT_TYPE_INFO_VARI) + { + DLT_MSG_READ_VALUE(length2_tmp,*ptr,*datalength,uint16_t); + if((*datalength)<0) + return -1; + length2=DLT_ENDIAN_GET_16(msg->standardheader->htyp, length2_tmp); + DLT_MSG_READ_VALUE(length3_tmp,*ptr,*datalength,uint16_t); + if((*datalength)<0) + return -1; + length3=DLT_ENDIAN_GET_16(msg->standardheader->htyp, length3_tmp); + if((*datalength)<length2) + return -1; + *ptr += length2; + *datalength-=length2; + if((*datalength)<length3) + return -1; + *ptr += length3; + *datalength-=length3; + } + switch ( type_info & DLT_TYPE_INFO_TYLE) + { + case DLT_TYLE_8BIT: + { + if (*datalength>=1) + dlt_print_hex_string(text+strlen(text),textlength,*ptr,1); + if((*datalength)<1) + return -1; + *ptr += 1; + *datalength-=1; + break; + } + case DLT_TYLE_16BIT: + { + if (*datalength>=2) + dlt_print_hex_string(text+strlen(text),textlength,*ptr,2); + if((*datalength)<2) + return -1; + *ptr += 2; + *datalength-=2; + break; + } + case DLT_TYLE_32BIT: + { + if (sizeof(float32_t)==4) + { + value32f=0; + value32f_tmp=0; + value32f_tmp_int32i=0; + value32f_tmp_int32i_swaped=0; + DLT_MSG_READ_VALUE(value32f_tmp,*ptr,*datalength,float32_t); + if((*datalength)<0) + return -1; + memcpy(&value32f_tmp_int32i,&value32f_tmp,sizeof(float32_t)); + value32f_tmp_int32i_swaped=DLT_ENDIAN_GET_32(msg->standardheader->htyp, (uint32_t)value32f_tmp_int32i); + memcpy(&value32f,&value32f_tmp_int32i_swaped,sizeof(float32_t)); + sprintf(text+strlen(text),"%g",value32f); + } + else + { + dlt_log(LOG_ERR, "Invalid size of float32_t\n"); + return -1; + } + break; + } + case DLT_TYLE_64BIT: + { + if (sizeof(float64_t)==8) + { + value64f=0; + value64f_tmp=0; + value64f_tmp_int64i=0; + value64f_tmp_int64i_swaped=0; + DLT_MSG_READ_VALUE(value64f_tmp,*ptr,*datalength,float64_t); + if((*datalength)<0) + return -1; + memcpy(&value64f_tmp_int64i,&value64f_tmp,sizeof(float64_t)); + value64f_tmp_int64i_swaped=DLT_ENDIAN_GET_64(msg->standardheader->htyp, (uint64_t)value64f_tmp_int64i); + memcpy(&value64f,&value64f_tmp_int64i_swaped,sizeof(float64_t)); + sprintf(text+strlen(text),"%g",value64f); + } + else + { + dlt_log(LOG_ERR, "Invalid size of float64_t\n"); + return -1; + } + break; + } + case DLT_TYLE_128BIT: + { + if (*datalength>=16) + dlt_print_hex_string(text+strlen(text),textlength,*ptr,16); + if((*datalength)<16) + return -1; + *ptr += 16; + *datalength-=16; + break; + } + default: + { + return -1; + } + } + + } + else if (type_info & DLT_TYPE_INFO_RAWD) + { + /* raw data argument */ + DLT_MSG_READ_VALUE(length_tmp,*ptr,*datalength,uint16_t); + if((*datalength)<0) + return -1; + length=DLT_ENDIAN_GET_16(msg->standardheader->htyp, length_tmp); + if (type_info & DLT_TYPE_INFO_VARI) + { + DLT_MSG_READ_VALUE(length2_tmp,*ptr,*datalength,uint16_t); + if((*datalength)<0) + return -1; + length2=DLT_ENDIAN_GET_16(msg->standardheader->htyp, length2_tmp); + if((*datalength)<length2) + return -1; + *ptr += length2; + *datalength-=length2; + } + if((*datalength)<length) + return -1; + dlt_print_hex_string(text+strlen(text),textlength,*ptr,length); + *ptr+=length; + *datalength-=length; + } + else if (type_info & DLT_TYPE_INFO_TRAI) + { + /* trace info argument */ + DLT_MSG_READ_VALUE(length_tmp,*ptr,*datalength,uint16_t); + if((*datalength)<0) + return -1; + length=DLT_ENDIAN_GET_16(msg->standardheader->htyp, length_tmp); + DLT_MSG_READ_STRING((text+strlen(text)),*ptr,*datalength,length); + if((*datalength)<0) + return -1; + } + else + { + return -1; + } + + if (*datalength<0) + { + dlt_log(LOG_ERR, "Payload of DLT message corrupted\n"); + return -1; + } + + return 0; +} diff --git a/src/shared/dlt_common_cfg.h b/src/shared/dlt_common_cfg.h new file mode 100755 index 0000000..fd9da26 --- /dev/null +++ b/src/shared/dlt_common_cfg.h @@ -0,0 +1,126 @@ +/*
+ * Dlt- Diagnostic Log and Trace daemon
+ * @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_common_cfg.h **
+** **
+** TARGET : linux **
+** **
+** PROJECT : DLT **
+** **
+** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de **
+** Markus Klein **
+** **
+** PURPOSE : **
+** **
+** REMARKS : **
+** **
+** PLATFORM DEPENDANT [yes/no]: yes **
+** **
+** TO BE CHANGED BY USER [yes/no]: no **
+** **
+*******************************************************************************/
+
+/*******************************************************************************
+** Author Identity **
+********************************************************************************
+** **
+** Initials Name Company **
+** -------- ------------------------- ---------------------------------- **
+** aw Alexander Wenzel BMW **
+** mk Markus Klein Fraunhofer ESK **
+*******************************************************************************/
+
+/*******************************************************************************
+** Author Identity **
+********************************************************************************
+** **
+** Initials Name Company **
+** -------- ------------------------- ---------------------------------- **
+** aw Alexander Wenzel BMW **
+** mk Markus Klein Fraunhofer ESK **
+*******************************************************************************/
+
+#ifndef DLT_COMMON_CFG_H
+#define DLT_COMMON_CFG_H
+
+/*************/
+/* Changable */
+/*************/
+
+/* Buffer length for temporary buffer */
+#define DLT_COMMON_BUFFER_LENGTH 255
+
+/* Number of ASCII chars to be printed in one line as HEX and as ASCII */
+/* e.g. XX XX XX XX ABCD is DLT_COMMON_HEX_CHARS = 4 */
+#define DLT_COMMON_HEX_CHARS 16
+
+/* Length of line number */
+#define DLT_COMMON_HEX_LINELEN 8
+
+/* Length of one char */
+#define DLT_COMMON_CHARLEN 1
+
+/* Number of indices to be allocated at one, if no more indeces are left */
+#define DLT_COMMON_INDEX_ALLOC 1000
+
+/* If limited output is called,
+ this is the maximum number of characters to be printed out */
+#define DLT_COMMON_ASCII_LIMIT_MAX_CHARS 20
+
+/* This defines the dummy ECU ID set in storage header during import
+ of a message from a DLT file in RAW format (without storage header) */
+#define DLT_COMMON_DUMMY_ECUID "ECU"
+
+
+/************************/
+/* Don't change please! */
+/************************/
+
+/* ASCII value for space */
+#define DLT_COMMON_ASCII_CHAR_SPACE 32
+
+/* ASCII value for tilde */
+#define DLT_COMMON_ASCII_CHAR_TILDE 126
+
+/* ASCII value for lesser than */
+#define DLT_COMMON_ASCII_CHAR_LT 60
+
+#endif /* DLT_COMMON_CFG_H */
+
diff --git a/src/shared/dlt_user_shared.c b/src/shared/dlt_user_shared.c new file mode 100755 index 0000000..5afc828 --- /dev/null +++ b/src/shared/dlt_user_shared.c @@ -0,0 +1,199 @@ +/* + * 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_user_shared.c ** +** ** +** TARGET : linux ** +** ** +** PROJECT : DLT ** +** ** +** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** +** Markus Klein ** +** ** +** PURPOSE : ** +** ** +** REMARKS : ** +** ** +** PLATFORM DEPENDANT [yes/no]: yes ** +** ** +** TO BE CHANGED BY USER [yes/no]: no ** +** ** +*******************************************************************************/ + +/******************************************************************************* +** Author Identity ** +******************************************************************************** +** ** +** Initials Name Company ** +** -------- ------------------------- ---------------------------------- ** +** aw Alexander Wenzel BMW ** +** mk Markus Klein Fraunhofer ESK ** +*******************************************************************************/ + +/******************************************************************************* +** Revision Control History ** +*******************************************************************************/ + +/* + * $LastChangedRevision: 1670 $ + * $LastChangedDate: 2011-04-08 15:12:06 +0200 (Fr, 08. Apr 2011) $ + * $LastChangedBy$ + Initials Date Comment + aw 13.01.2010 initial + */ + +#include <sys/stat.h> +#include <fcntl.h> +#include <errno.h> + +#include <sys/uio.h> /* writev() */ + +#include "dlt_user_shared.h" +#include "dlt_user_shared_cfg.h" + +int dlt_user_set_userheader(DltUserHeader *userheader, uint32_t mtype) +{ + if (userheader==0) + { + return -1; + } + + if (mtype<=0) + { + return -1; + } + + userheader->pattern[0] = 'D'; + userheader->pattern[1] = 'U'; + userheader->pattern[2] = 'H'; + userheader->pattern[3] = 1; + userheader->message = mtype; + + return 0; +} + +int dlt_user_check_userheader(DltUserHeader *userheader) +{ + if (userheader==0) + { + return -1; + } + + return ((userheader->pattern[0] == 'D') && + (userheader->pattern[1] == 'U') && + (userheader->pattern[2] == 'H') && + (userheader->pattern[3] == 1)); +} + +DltReturnValue dlt_user_log_out2(int handle, void *ptr1, size_t len1, void* ptr2, size_t len2) +{ + struct iovec iov[2]; + int bytes_written; + + if (handle<=0) + { + /* Invalid handle */ + return DLT_RETURN_ERROR; + } + + iov[0].iov_base = ptr1; + iov[0].iov_len = len1; + iov[1].iov_base = ptr2; + iov[1].iov_len = len2; + + bytes_written = writev(handle, iov, 2); + + if (bytes_written!=(len1+len2)) + { + return DLT_RETURN_ERROR; + } + + return DLT_RETURN_OK; +} + +DltReturnValue dlt_user_log_out3(int handle, void *ptr1, size_t len1, void* ptr2, size_t len2, void *ptr3, size_t len3) +{ + struct iovec iov[3]; + int bytes_written; + + if (handle<=0) + { + /* Invalid handle */ + return DLT_RETURN_ERROR; + } + + iov[0].iov_base = ptr1; + iov[0].iov_len = len1; + iov[1].iov_base = ptr2; + iov[1].iov_len = len2; + iov[2].iov_base = ptr3; + iov[2].iov_len = len3; + + bytes_written = writev(handle, iov, 3); + + if (bytes_written!=(len1+len2+len3)) + { + switch(errno) + { + case EBADF: + { + return DLT_RETURN_PIPE_ERROR; /* EBADF - handle not open */ + break; + } + case EPIPE: + { + return DLT_RETURN_PIPE_ERROR; /* EPIPE - pipe error */ + break; + } + case EAGAIN: + { + return DLT_RETURN_PIPE_FULL; /* EAGAIN - data could not be written */ + break; + } + default: + { + break; + } + } + return DLT_RETURN_ERROR; + } + + return DLT_RETURN_OK; +} diff --git a/src/shared/dlt_user_shared.h b/src/shared/dlt_user_shared.h new file mode 100755 index 0000000..a9d1628 --- /dev/null +++ b/src/shared/dlt_user_shared.h @@ -0,0 +1,227 @@ +/*
+ * Dlt- Diagnostic Log and Trace daemon
+ * @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_user_shared.h **
+** **
+** TARGET : linux **
+** **
+** PROJECT : DLT **
+** **
+** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de **
+** Markus Klein **
+** **
+** PURPOSE : **
+** **
+** REMARKS : **
+** **
+** PLATFORM DEPENDANT [yes/no]: yes **
+** **
+** TO BE CHANGED BY USER [yes/no]: no **
+** **
+*******************************************************************************/
+
+/*******************************************************************************
+** Author Identity **
+********************************************************************************
+** **
+** Initials Name Company **
+** -------- ------------------------- ---------------------------------- **
+** aw Alexander Wenzel BMW **
+** mk Markus Klein Fraunhofer ESK **
+*******************************************************************************/
+
+/*******************************************************************************
+** Author Identity **
+********************************************************************************
+** **
+** Initials Name Company **
+** -------- ------------------------- ---------------------------------- **
+** aw Alexander Wenzel BMW **
+** mk Markus Klein Fraunhofer ESK **
+*******************************************************************************/
+
+#ifndef DLT_USER_SHARED_H
+#define DLT_USER_SHARED_H
+ +#include "dlt_types.h"
+#include "dlt_user.h"
+
+#include <sys/types.h>
+ +/**
+ * This are the return values for the functions dlt_user_log_out2() and dlt_user_log_out3()
+ */ +typedef enum +{ + DLT_RETURN_PIPE_FULL = -3, + DLT_RETURN_PIPE_ERROR = -2, + DLT_RETURN_ERROR = -1, + DLT_RETURN_OK = 0 +} DltReturnValue; +
+/**
+ * This is the header of each message to be exchanged between application and daemon.
+ */
+typedef struct
+{
+ char pattern[DLT_ID_SIZE]; /**< This pattern should be DUH0x01 */
+ uint32_t message; /**< messsage info */
+} PACKED DltUserHeader;
+
+/**
+ * This is the internal message content to exchange control msg register app information between application and daemon.
+ */
+typedef struct
+{
+ char apid[DLT_ID_SIZE]; /**< application id */
+ pid_t pid; /**< process id of user application */
+ uint32_t description_length; /**< length of description */
+} PACKED DltUserControlMsgRegisterApplication;
+
+/**
+ * This is the internal message content to exchange control msg unregister app information between application and daemon.
+ */
+typedef struct
+{
+ char apid[DLT_ID_SIZE]; /**< application id */
+ pid_t pid; /**< process id of user application */
+} PACKED DltUserControlMsgUnregisterApplication;
+
+/**
+ * This is the internal message content to exchange control msg register information between application and daemon.
+ */
+typedef struct
+{
+ char apid[DLT_ID_SIZE]; /**< application id */
+ char ctid[DLT_ID_SIZE]; /**< context id */
+ int32_t log_level_pos; /**< offset in management structure on user-application side */
+ int8_t log_level; /**< log level */
+ int8_t trace_status; /**< trace status */
+ pid_t pid; /**< process id of user application */
+ uint32_t description_length; /**< length of description */
+} PACKED DltUserControlMsgRegisterContext;
+
+/**
+ * This is the internal message content to exchange control msg unregister information between application and daemon.
+ */
+typedef struct
+{
+ char apid[DLT_ID_SIZE]; /**< application id */
+ char ctid[DLT_ID_SIZE]; /**< context id */
+ pid_t pid; /**< process id of user application */
+} PACKED DltUserControlMsgUnregisterContext;
+
+/**
+ * This is the internal message content to exchange control msg log level information between application and daemon.
+ */
+typedef struct
+{
+ uint8_t log_level; /**< log level */
+ uint8_t trace_status; /**< trace status */
+ int32_t log_level_pos; /**< offset in management structure on user-application side */
+} PACKED DltUserControlMsgLogLevel;
+
+/**
+ * This is the internal message content to exchange control msg injection information between application and daemon.
+ */
+typedef struct
+{
+ int32_t log_level_pos; /**< offset in management structure on user-application side */
+ uint32_t service_id; /**< service id of injection */
+ uint32_t data_length_inject; /**< length of injection message data field */
+} PACKED DltUserControlMsgInjection;
+
+/**
+ * This is the internal message content to exchange information about application log level and trace stats between
+ * application and daemon.
+ */
+typedef struct
+{
+ char apid[DLT_ID_SIZE]; /**< application id */
+ uint8_t log_level; /**< log level */
+ uint8_t trace_status; /**< trace status */
+} PACKED DltUserControlMsgAppLogLevelTraceStatus;
+
+/**************************************************************************************************
+* The folowing functions are used shared between the user lib and the daemon implementation
+**************************************************************************************************/
+
+/**
+ * Set user header marker and store message type in user header
+ * @param userheader pointer to the userheader
+ * @param mtype user message type of internal message
+ * @return negative value if there was an error { + return -1; + }
+ */
+int dlt_user_set_userheader(DltUserHeader *userheader, uint32_t mtype);
+
+/**
+ * Check if user header contains its marker
+ * @param userheader pointer to the userheader
+ * @return 0 no, 1 yes, negative value if there was an error
+ */
+int dlt_user_check_userheader(DltUserHeader *userheader);
+
+/**
+ * Atomic write to file descriptor, using vector of 2 elements
+ * @param handle file descriptor
+ * @param ptr1 generic pointer to first segment of data to be written
+ * @param len1 length of first segment of data to be written
+ * @param ptr2 generic pointer to second segment of data to be written
+ * @param len2 length of second segment of data to be written
+ * @return Value from DltReturnValue enum
+ */
+DltReturnValue dlt_user_log_out2(int handle, void *ptr1, size_t len1, void* ptr2, size_t len2);
+
+/**
+ * Atomic write to file descriptor, using vector of 3 elements
+ * @param handle file descriptor
+ * @param ptr1 generic pointer to first segment of data to be written
+ * @param len1 length of first segment of data to be written
+ * @param ptr2 generic pointer to second segment of data to be written
+ * @param len2 length of second segment of data to be written
+ * @param ptr3 generic pointer to third segment of data to be written
+ * @param len3 length of third segment of data to be written
+ * @return Value from DltReturnValue enum
+ */
+DltReturnValue dlt_user_log_out3(int handle, void *ptr1, size_t len1, void* ptr2, size_t len2, void *ptr3, size_t len3);
+
+#endif /* DLT_USER_SHARED_H */
diff --git a/src/shared/dlt_user_shared_cfg.h b/src/shared/dlt_user_shared_cfg.h new file mode 100755 index 0000000..08f919c --- /dev/null +++ b/src/shared/dlt_user_shared_cfg.h @@ -0,0 +1,116 @@ +/*
+ * Dlt- Diagnostic Log and Trace daemon
+ * @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_user_shared_cfg.h **
+** **
+** TARGET : linux **
+** **
+** PROJECT : DLT **
+** **
+** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de **
+** Markus Klein **
+** **
+** PURPOSE : **
+** **
+** REMARKS : **
+** **
+** PLATFORM DEPENDANT [yes/no]: yes **
+** **
+** TO BE CHANGED BY USER [yes/no]: no **
+** **
+*******************************************************************************/
+
+/*******************************************************************************
+** Author Identity **
+********************************************************************************
+** **
+** Initials Name Company **
+** -------- ------------------------- ---------------------------------- **
+** aw Alexander Wenzel BMW **
+** mk Markus Klein Fraunhofer ESK **
+*******************************************************************************/
+
+/*******************************************************************************
+** Author Identity **
+********************************************************************************
+** **
+** Initials Name Company **
+** -------- ------------------------- ---------------------------------- **
+** aw Alexander Wenzel BMW **
+** mk Markus Klein Fraunhofer ESK **
+*******************************************************************************/
+
+#ifndef DLT_USER_SHARED_CFG_H
+#define DLT_USER_SHARED_CFG_H
+
+/*************/
+/* Changable */
+/*************/
+
+/* Directory, whre the named pipes to the DLT daemon resides */
+#define DLT_USER_DIR "/tmp"
+
+/* Name of named pipe to DLT daemon */
+#define DLT_USER_FIFO "/tmp/dlt"
+
+/************************/
+/* Don't change please! */
+/************************/
+
+/* The different types of internal messages between user application and daemon. */
+#define DLT_USER_MESSAGE_LOG 1
+#define DLT_USER_MESSAGE_REGISTER_APPLICATION 2
+#define DLT_USER_MESSAGE_UNREGISTER_APPLICATION 3
+#define DLT_USER_MESSAGE_REGISTER_CONTEXT 4
+#define DLT_USER_MESSAGE_UNREGISTER_CONTEXT 5
+#define DLT_USER_MESSAGE_LOG_LEVEL 6
+#define DLT_USER_MESSAGE_INJECTION 7
+#define DLT_USER_MESSAGE_OVERFLOW 8
+#define DLT_USER_MESSAGE_APP_LL_TS 9
+
+/* Internal defined values */ + +/* must be different from DltLogLevelType */
+#define DLT_USER_LOG_LEVEL_NOT_SET -2 +/* must be different from DltTraceStatusType */
+#define DLT_USER_TRACE_STATUS_NOT_SET -2
+
+#endif /* DLT_USER_SHARED_CFG_H */
+
diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt new file mode 100755 index 0000000..6eb708d --- /dev/null +++ b/src/tests/CMakeLists.txt @@ -0,0 +1,60 @@ +####### +# Dlt - Diagnostic Log and Trace +# @licence make 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@ +######## + +set(dlt_test_user_SRCS dlt-test-user) +add_executable(dlt-test-user ${dlt_test_user_SRCS}) +target_link_libraries(dlt-test-user dlt) +set_target_properties(dlt-test-user PROPERTIES LINKER_LANGUAGE C) + +set(dlt_test_client_SRCS dlt-test-client) +add_executable(dlt-test-client ${dlt_test_client_SRCS}) +target_link_libraries(dlt-test-client dlt) +set_target_properties(dlt-test-client PROPERTIES LINKER_LANGUAGE C) + +set(dlt_test_stress_SRCS dlt-test-stress) +add_executable(dlt-test-stress ${dlt_test_stress_SRCS}) +target_link_libraries(dlt-test-stress dlt) +set_target_properties(dlt-test-stress PROPERTIES LINKER_LANGUAGE C) + +set(dlt_test_internal_SRCS dlt-test-internal) +add_executable(dlt-test-internal ${dlt_test_internal_SRCS}) +target_link_libraries(dlt-test-internal dlt) +set_target_properties(dlt-test-internal PROPERTIES LINKER_LANGUAGE C) + +install(TARGETS dlt-test-user dlt-test-client dlt-test-stress dlt-test-internal + RUNTIME DESTINATION bin + COMPONENT base) diff --git a/src/tests/dlt-test-client.c b/src/tests/dlt-test-client.c new file mode 100755 index 0000000..180badf --- /dev/null +++ b/src/tests/dlt-test-client.c @@ -0,0 +1,2004 @@ +/* + * Dlt Test Client - Diagnostic Log and Trace + * @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-test-client.c ** +** ** +** TARGET : linux ** +** ** +** PROJECT : DLT ** +** ** +** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** +** Markus Klein ** +** ** +** PURPOSE : ** +** ** +** REMARKS : ** +** ** +** PLATFORM DEPENDANT [yes/no]: yes ** +** ** +** TO BE CHANGED BY USER [yes/no]: no ** +** ** +*******************************************************************************/ + +/******************************************************************************* +** Author Identity ** +******************************************************************************** +** ** +** Initials Name Company ** +** -------- ------------------------- ---------------------------------- ** +** aw Alexander Wenzel BMW ** +** mk Markus Klein Fraunhofer ESK ** +*******************************************************************************/ + +/******************************************************************************* +** Revision Control History ** +*******************************************************************************/ + +/* + * $LastChangedRevision: 1670 $ + * $LastChangedDate: 2011-04-08 15:12:06 +0200 (Fr, 08. Apr 2011) $ + * $LastChangedBy$ + Initials Date Comment + aw 13.01.2010 initial + */ + +#include <ctype.h> /* for isprint() */ +#include <stdlib.h> /* for atoi() */ +#include <sys/stat.h> /* for S_IRUSR, S_IWUSR, S_IRGRP, S_IROTH */ +#include <fcntl.h> /* for open() */ +#include <string.h> /* for strcmp() */ +#include <sys/uio.h> /* for writev() */ + +#include "dlt_client.h" +#include "dlt_protocol.h" +#include "dlt_user.h" + +#define DLT_TESTCLIENT_TEXTBUFSIZE 10024 /* Size of buffer for text output */ +#define DLT_TESTCLIENT_ECU_ID "ECU1" + +#define DLT_TESTCLIENT_NUM_TESTS 7 + +/* Function prototypes */ +int dlt_testclient_message_callback(DltMessage *message, void *data); + +typedef struct +{ + int aflag; + int sflag; + int xflag; + int mflag; + int vflag; + int yflag; + char *ovalue; + char *fvalue; + char *tvalue; + char *evalue; + int bvalue; + + char ecuid[4]; + int ohandle; + + DltFile file; + DltFilter filter; + + int running_test; + + int test_counter_macro[DLT_TESTCLIENT_NUM_TESTS]; + int test_counter_function[DLT_TESTCLIENT_NUM_TESTS]; + + int tests_passed; + int tests_failed; + + int sock; +} DltTestclientData; + +/** + * Print usage information of tool. + */ +void usage() +{ + char version[255]; + + dlt_get_version(version); + + printf("Usage: dlt-test-client [options] hostname/serial_device_name\n"); + printf("Test against received data from dlt-test-user.\n"); + printf("%s \n", version); + printf("Options:\n"); + printf(" -a Print DLT messages; payload as ASCII\n"); + printf(" -x Print DLT messages; payload as hex\n"); + printf(" -m Print DLT messages; payload as hex and ASCII\n"); + printf(" -s Print DLT messages; only headers\n"); + printf(" -v Verbose mode\n"); + printf(" -h Usage\n"); + printf(" -y Serial device mode\n"); + printf(" -b baudrate Serial device baudrate (Default: 115200)\n"); + printf(" -e ecuid Set ECU ID (Default: ECU1)\n"); + printf(" -o filename Output messages in new DLT file\n"); + printf(" -f filename Enable filtering of messages\n"); +} + +/** + * Main function of tool. + */ +int main(int argc, char* argv[]) +{ + DltClient dltclient; + DltTestclientData dltdata; + int c,i; + int index; + + /* Initialize dltdata */ + dltdata.aflag = 0; + dltdata.sflag = 0; + dltdata.xflag = 0; + dltdata.mflag = 0; + dltdata.vflag = 0; + dltdata.yflag = 0; + dltdata.ovalue = 0; + dltdata.fvalue = 0; + dltdata.evalue = 0; + dltdata.bvalue = 0; + dltdata.ohandle=-1; + + dltdata.running_test = 0; + + for (i=0;i<DLT_TESTCLIENT_NUM_TESTS;i++) + { + dltdata.test_counter_macro[i]=0; + dltdata.test_counter_function[i]=0; + } + + dltdata.tests_passed = 0; + dltdata.tests_failed = 0; + + dltdata.sock = -1; + + /* Fetch command line arguments */ + opterr = 0; + + while ((c = getopt (argc, argv, "vashyxmf:o:e:b:")) != -1) + { + switch (c) + { + case 'v': + { + dltdata.vflag = 1; + break; + } + case 'a': + { + dltdata.aflag = 1; + break; + } + case 's': + { + dltdata.sflag = 1; + break; + } + case 'x': + { + dltdata.xflag = 1; + break; + } + case 'm': + { + dltdata.mflag = 1; + break; + } + case 'h': + { + usage(); + return -1; + } + case 'y': + { + dltdata.yflag = 1; + break; + } + case 'f': + { + dltdata.fvalue = optarg; + break; + } + case 'o': + { + dltdata.ovalue = optarg; + break; + } + case 'e': + { + dltdata.evalue = optarg; + break; + } + case 'b': + { + dltdata.bvalue = atoi(optarg); + break; + } + case '?': + { + if (optopt == 'o' || optopt == 'f' || optopt == 't') + { + fprintf (stderr, "Option -%c requires an argument.\n", optopt); + } + else if (isprint (optopt)) + { + fprintf (stderr, "Unknown option `-%c'.\n", optopt); + } + else + { + fprintf (stderr, "Unknown option character `\\x%x'.\n",optopt); + } + /* unknown or wrong option used, show usage information and terminate */ + usage(); + return -1; + } + default: + { + abort (); + } + } + } + + /* Initialize DLT Client */ + dlt_client_init(&dltclient, dltdata.vflag); + + /* Register callback to be called when message was received */ + dlt_client_register_message_callback(dlt_testclient_message_callback); + + /* Setup DLT Client structure */ + dltclient.serial_mode = dltdata.yflag; + + if (dltclient.serial_mode==0) + { + for (index = optind; index < argc; index++) + { + dltclient.servIP = argv[index]; + } + + if (dltclient.servIP == 0) + { + /* no hostname selected, show usage and terminate */ + fprintf(stderr,"ERROR: No hostname selected\n"); + usage(); + dlt_client_cleanup(&dltclient,dltdata.vflag); + return -1; + } + } + else + { + for (index = optind; index < argc; index++) + { + dltclient.serialDevice = argv[index]; + } + + if (dltclient.serialDevice == 0) + { + /* no serial device name selected, show usage and terminate */ + fprintf(stderr,"ERROR: No serial device name specified\n"); + usage(); + return -1; + } + + dlt_client_setbaudrate(&dltclient,dltdata.bvalue); + } + + /* initialise structure to use DLT file */ + dlt_file_init(&(dltdata.file),dltdata.vflag); + + /* first parse filter file if filter parameter is used */ + dlt_filter_init(&(dltdata.filter),dltdata.vflag); + + if (dltdata.fvalue) + { + if (dlt_filter_load(&(dltdata.filter),dltdata.fvalue,dltdata.vflag)<0) + { + dlt_file_free(&(dltdata.file),dltdata.vflag); + return -1; + } + + dlt_file_set_filter(&(dltdata.file),&(dltdata.filter),dltdata.vflag); + } + + /* open DLT output file */ + if (dltdata.ovalue) + { + dltdata.ohandle = open(dltdata.ovalue,O_WRONLY|O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); /* mode: wb */ + + if (dltdata.ohandle == -1) + { + dlt_file_free(&(dltdata.file),dltdata.vflag); + fprintf(stderr,"ERROR: Output file %s cannot be opened!\n",dltdata.ovalue); + return -1; + } + } + + if (dltdata.evalue) + { + dlt_set_id(dltdata.ecuid,dltdata.evalue); + } + else + { + dlt_set_id(dltdata.ecuid,DLT_TESTCLIENT_ECU_ID); + } + + /* Connect to TCP socket or open serial device */ + if (dlt_client_connect(&dltclient, dltdata.vflag)!=-1) + { + dltdata.sock = dltclient.sock; + + /* Dlt Client Main Loop */ + dlt_client_main_loop(&dltclient, &dltdata, dltdata.vflag); + + /* Dlt Client Cleanup */ + dlt_client_cleanup(&dltclient,dltdata.vflag); + } + + /* dlt-receive cleanup */ + if (dltdata.ovalue) + { + close(dltdata.ohandle); + } + + dlt_file_free(&(dltdata.file),dltdata.vflag); + + dlt_filter_free(&(dltdata.filter),dltdata.vflag); + + return 0; +} + +int dlt_testclient_message_callback(DltMessage *message, void *data) +{ + static char text[DLT_TESTCLIENT_TEXTBUFSIZE]; + int mtin; + DltTestclientData *dltdata; + + uint32_t type_info, type_info_tmp; + int16_t length,length_tmp; /* the macro can set this variable to -1 */ + uint8_t *ptr; + int32_t datalength; + + uint32_t id,id_tmp; + int slen; + int tc_old; + + struct iovec iov[2]; + int bytes_written; + + if ((message==0) || (data==0)) + { + return -1; + } + + dltdata = (DltTestclientData*)data; + + /* prepare storage header */ + if (DLT_IS_HTYP_WEID(message->standardheader->htyp)) + { + dlt_set_storageheader(message->storageheader,message->headerextra.ecu); + } + else + { + dlt_set_storageheader(message->storageheader,dltdata->ecuid); + } + + if ((dltdata->fvalue==0) || (dltdata->fvalue && dlt_message_filter_check(message,&(dltdata->filter),dltdata->vflag)==1)) + { + + dlt_message_header(message,text,sizeof(text),dltdata->vflag); + if (dltdata->aflag) + { + printf("%s ",text); + } + dlt_message_payload(message,text,sizeof(text),DLT_OUTPUT_ASCII,dltdata->vflag); + if (dltdata->aflag) + { + printf("[%s]\n",text); + } + + if (strcmp(text,"Tests starting")==0) + { + printf("Tests starting\n"); + } + + /* check test 1m */ + if (strcmp(text,"Test1: (Macro IF) Test all log levels")==0) + { + printf("Test1m: (Macro IF) Test all log levels\n"); + dltdata->running_test = 1; + dltdata->test_counter_macro[0] = 0; + } + else if (strcmp(text,"Test1: (Macro IF) finished")==0) + { + /* >=4, as "info" is default log level */ + if (dltdata->test_counter_macro[0]>=4) + { + printf("Test1m PASSED\n"); + dltdata->tests_passed++; + } + else + { + printf("Test1m FAILED\n"); + dltdata->tests_failed++; + } + dltdata->running_test = 0; + } + else if (dltdata->running_test==1) + { + if (DLT_IS_HTYP_UEH(message->standardheader->htyp)) + { + if ((DLT_GET_MSIN_MSTP(message->extendedheader->msin))==DLT_TYPE_LOG) + { + mtin=DLT_GET_MSIN_MTIN(message->extendedheader->msin); + + if (mtin==DLT_LOG_FATAL) + { + dltdata->test_counter_macro[0]++; + } + if (mtin==DLT_LOG_ERROR) + { + dltdata->test_counter_macro[0]++; + } + if (mtin==DLT_LOG_WARN) + { + dltdata->test_counter_macro[0]++; + } + if (mtin==DLT_LOG_INFO) + { + dltdata->test_counter_macro[0]++; + } + if (mtin==DLT_LOG_DEBUG) + { + dltdata->test_counter_macro[0]++; + } + if (mtin==DLT_LOG_VERBOSE) + { + dltdata->test_counter_macro[0]++; + } + } + } + } + + /* check test 2m */ + if (strcmp(text,"Test2: (Macro IF) Test all variable types (verbose)")==0) + { + printf("Test2m: (Macro IF) Test all variable types (verbose)\n"); + dltdata->running_test = 2; + dltdata->test_counter_macro[1] = 0; + } + else if (strcmp(text,"Test2: (Macro IF) finished")==0) + { + if (dltdata->test_counter_macro[1]==14) + { + printf("Test2m PASSED\n"); + dltdata->tests_passed++; + } + else + { + printf("Test2m FAILED\n"); + dltdata->tests_failed++; + } + dltdata->running_test = 0; + } + else if (dltdata->running_test==2) + { + /* Verbose */ + if (!(DLT_MSG_IS_NONVERBOSE(message))) + { + type_info=0; + type_info_tmp=0; + length=0; /* the macro can set this variable to -1 */ + length_tmp=0; + ptr = message->databuffer; + datalength = message->datasize; + + /* Log message */ + if ((DLT_GET_MSIN_MSTP(message->extendedheader->msin))==DLT_TYPE_LOG) + { + if (message->extendedheader->noar>=2) + { + /* get type of first argument: must be string */ + DLT_MSG_READ_VALUE(type_info_tmp,ptr,datalength,uint32_t); + type_info=DLT_ENDIAN_GET_32(message->standardheader->htyp, type_info_tmp); + + if (type_info & DLT_TYPE_INFO_STRG) + { + /* skip string */ + DLT_MSG_READ_VALUE(length_tmp,ptr,datalength,uint16_t); + length=DLT_ENDIAN_GET_16(message->standardheader->htyp, length_tmp); + + if (length>=0) + { + ptr+=length; + datalength-=length; + + /* read type of second argument: must be raw */ + DLT_MSG_READ_VALUE(type_info_tmp,ptr,datalength,uint32_t); + type_info=DLT_ENDIAN_GET_32(message->standardheader->htyp, type_info_tmp); + + if (type_info & DLT_TYPE_INFO_BOOL) + { + if (datalength==sizeof(uint8_t)) + { + dltdata->test_counter_macro[1]++; + } + } + else if (type_info & DLT_TYPE_INFO_SINT) + { + switch (type_info & DLT_TYPE_INFO_TYLE) + { + case DLT_TYLE_8BIT: + { + if (datalength==sizeof(int8_t)) + { + dltdata->test_counter_macro[1]++; + } + break; + } + case DLT_TYLE_16BIT: + { + if (datalength==sizeof(int16_t)) + { + dltdata->test_counter_macro[1]++; + } + break; + } + case DLT_TYLE_32BIT: + { + if (datalength==sizeof(int32_t)) + { + dltdata->test_counter_macro[1]++; + } + break; + } + case DLT_TYLE_64BIT: + { + if (datalength==sizeof(int64_t)) + { + dltdata->test_counter_macro[1]++; + } + break; + } + case DLT_TYLE_128BIT: + { + /* Not tested here */ + break; + } + } + } + else if (type_info & DLT_TYPE_INFO_UINT) + { + switch (type_info & DLT_TYPE_INFO_TYLE) + { + case DLT_TYLE_8BIT: + { + if (datalength==sizeof(uint8_t)) + { + dltdata->test_counter_macro[1]++; + } + break; + } + case DLT_TYLE_16BIT: + { + if (datalength==sizeof(uint16_t)) + { + dltdata->test_counter_macro[1]++; + } + break; + } + case DLT_TYLE_32BIT: + { + if (datalength==sizeof(uint32_t)) + { + dltdata->test_counter_macro[1]++; + } + break; + } + case DLT_TYLE_64BIT: + { + if (datalength==sizeof(uint64_t)) + { + dltdata->test_counter_macro[1]++; + } + break; + } + case DLT_TYLE_128BIT: + { + /* Not tested here */ + break; + } + } + } + else if (type_info & DLT_TYPE_INFO_FLOA) + { + switch (type_info & DLT_TYPE_INFO_TYLE) + { + case DLT_TYLE_8BIT: + { + /* Not tested here */ + break; + } + case DLT_TYLE_16BIT: + { + /* Not tested here */ + break; + } + case DLT_TYLE_32BIT: + { + if (datalength==(2*sizeof(float)+sizeof(uint32_t))) + { + dltdata->test_counter_macro[1]++; + } + break; + } + case DLT_TYLE_64BIT: + { + if (datalength==(2*sizeof(double)+sizeof(uint32_t))) + { + dltdata->test_counter_macro[1]++; + } + break; + } + case DLT_TYLE_128BIT: + /* Not tested here */ + break; + } + } + else if (type_info & DLT_TYPE_INFO_RAWD) + { + /* Get length */ + DLT_MSG_READ_VALUE(length_tmp,ptr,datalength,uint16_t); + length=DLT_ENDIAN_GET_16(message->standardheader->htyp, length_tmp); + if ((length==datalength) && (length=10)) + { + dltdata->test_counter_macro[1]++; + } + } + } + } + } + } + } + } + + /* check test 3m */ + if (strcmp(text,"Test3: (Macro IF) Test all variable types (non-verbose)")==0) + { + printf("Test3m: (Macro IF) Test all variable types (non-verbose)\n"); + dltdata->running_test = 3; + dltdata->test_counter_macro[2]=0; + } + else if (strcmp(text,"Test3: (Macro IF) finished")==0) + { + if (dltdata->test_counter_macro[2]==14) + { + printf("Test3m PASSED\n"); + dltdata->tests_passed++; + } + else + { + printf("Test3m FAILED\n"); + dltdata->tests_failed++; + } + dltdata->running_test = 0; + } + else if (dltdata->running_test==3) + { + /* Nonverbose */ + if (DLT_MSG_IS_NONVERBOSE(message)) + { + id=0; + id_tmp=0; + ptr = message->databuffer; + datalength = message->datasize; + slen=-1; + + tc_old=dltdata->test_counter_macro[2]; + + /* Get message id */ + DLT_MSG_READ_VALUE(id_tmp,ptr,datalength,uint32_t); + id=DLT_ENDIAN_GET_32(message->standardheader->htyp, id_tmp); + + /* Length of string */ + datalength-=sizeof(uint16_t); + ptr+=sizeof(uint16_t); + + switch (id) + { + case 1: + { + slen=strlen("bool")+1; + datalength-=slen; + ptr+=slen; + if (datalength==sizeof(uint8_t)) + { + dltdata->test_counter_macro[2]++; + } + break; + } + case 2: + { + slen=strlen("int")+1; + datalength-=slen; + ptr+=slen; + if (datalength==sizeof(int)) + { + dltdata->test_counter_macro[2]++; + } + break; + } + case 3: + { + slen=strlen("int8")+1; + datalength-=slen; + ptr+=slen; + if (datalength==sizeof(int8_t)) + { + dltdata->test_counter_macro[2]++; + } + break; + } + case 4: + { + slen=strlen("int16")+1; + datalength-=slen; + ptr+=slen; + if (datalength==sizeof(int16_t)) + { + dltdata->test_counter_macro[2]++; + } + break; + } + case 5: + { + slen=strlen("int32")+1; + datalength-=slen; + ptr+=slen; + if (datalength==sizeof(int32_t)) + { + dltdata->test_counter_macro[2]++; + } + break; + } + case 6: + { + slen=strlen("int64")+1; + datalength-=slen; + ptr+=slen; + if (datalength==sizeof(int64_t)) + { + dltdata->test_counter_macro[2]++; + } + break; + } + case 7: + { + slen=strlen("uint")+1; + datalength-=slen; + ptr+=slen; + if (datalength==sizeof(unsigned int)) + { + dltdata->test_counter_macro[2]++; + } + break; + } + case 8: + { + slen=strlen("uint8")+1; + datalength-=slen; + ptr+=slen; + if (datalength==sizeof(uint8_t)) + { + dltdata->test_counter_macro[2]++; + } + break; + } + case 9: + { + slen=strlen("uint16")+1; + datalength-=slen; + ptr+=slen; + if (datalength==sizeof(uint16_t)) + { + dltdata->test_counter_macro[2]++; + } + break; + } + case 10: + { + slen=strlen("uint32")+1; + datalength-=slen; + ptr+=slen; + if (datalength==sizeof(uint32_t)) + { + dltdata->test_counter_macro[2]++; + } + break; + } + case 11: + { + slen=strlen("uint64")+1; + datalength-=slen; + ptr+=slen; + if (datalength==sizeof(uint64_t)) + { + dltdata->test_counter_macro[2]++; + } + break; + } + case 12: + { + slen=strlen("float32")+1; + datalength-=slen; + ptr+=slen; + /* 2*, as the min and the max is transfered */ + if (datalength==2*sizeof(float)) + { + dltdata->test_counter_macro[2]++; + } + break; + } + case 13: + { + slen=strlen("float64")+1; + datalength-=slen; + ptr+=slen; + /* 2*, as the min and the max is transfered */ + if (datalength==2*sizeof(double)) + { + dltdata->test_counter_macro[2]++; + } + break; + } + case 14: + { + slen=strlen("raw")+1; + datalength-=slen; + ptr+=slen; + datalength-=sizeof(uint16_t); + ptr+=sizeof(uint16_t); + if (datalength==10) + { + dltdata->test_counter_macro[2]++; + } + break; + } + } + + if ((slen>=0) && (tc_old==dltdata->test_counter_macro[2])) + { + printf("ID=%d, Datalength=%d => Failed!",id,datalength); + } + } + } + + /* check test 4m */ + if (strcmp(text,"Test4: (Macro IF) Test different message sizes")==0) + { + printf("Test4m: (Macro IF) Test different message sizes\n"); + dltdata->running_test = 4; + dltdata->test_counter_macro[3]=0; + } + else if (strcmp(text,"Test4: (Macro IF) finished")==0) + { + if (dltdata->test_counter_macro[3]==4) + { + printf("Test4m PASSED\n"); + dltdata->tests_passed++; + } + else + { + printf("Test4m FAILED\n"); + dltdata->tests_failed++; + } + dltdata->running_test = 0; + } + else if (dltdata->running_test==4) + { + /* Extended header */ + if (DLT_IS_HTYP_UEH(message->standardheader->htyp)) + { + /* Log message */ + if ((DLT_GET_MSIN_MSTP(message->extendedheader->msin))==DLT_TYPE_LOG) + { + /* Verbose */ + if (DLT_IS_MSIN_VERB(message->extendedheader->msin)) + { + /* 2 arguments */ + if (message->extendedheader->noar==2) + { + /* verbose mode */ + type_info=0; + type_info_tmp=0; + length=0; + length_tmp=0; /* the macro can set this variable to -1 */ + + ptr = message->databuffer; + datalength = message->datasize; + + /* first read the type info of the first argument: must be string */ + DLT_MSG_READ_VALUE(type_info_tmp,ptr,datalength,uint32_t); + type_info=DLT_ENDIAN_GET_32(message->standardheader->htyp, type_info_tmp); + + if (type_info & DLT_TYPE_INFO_STRG) + { + /* skip string */ + DLT_MSG_READ_VALUE(length_tmp,ptr,datalength,uint16_t); + length=DLT_ENDIAN_GET_16(message->standardheader->htyp, length_tmp); + + if (length>=0) + { + ptr+=length; + datalength-=length; + + /* read type of second argument: must be raw */ + DLT_MSG_READ_VALUE(type_info_tmp,ptr,datalength,uint32_t); + type_info=DLT_ENDIAN_GET_32(message->standardheader->htyp, type_info_tmp); + + if (type_info & DLT_TYPE_INFO_RAWD) + { + /* get length of raw data block */ + DLT_MSG_READ_VALUE(length_tmp,ptr,datalength,uint16_t); + length=DLT_ENDIAN_GET_16(message->standardheader->htyp, length_tmp); + + if ((length>=0) && (length==datalength)) + { + //printf("Raw data found in payload, length="); + //printf("%d, datalength=%d \n", length, datalength); + dltdata->test_counter_macro[3]++; + } + } + } + } + } + } + } + } + } + + /* check test 5m */ + if (strcmp(text,"Test5: (Macro IF) Test high-level API")==0) + { + printf("Test5m: (Macro IF) Test high-level API\n"); + dltdata->running_test = 5; + dltdata->test_counter_macro[4]=0; + } + else if (strcmp(text,"Test5: (Macro IF) finished")==0) + { + if (dltdata->test_counter_macro[4]==12) + { + printf("Test5m PASSED\n"); + dltdata->tests_passed++; + } + else + { + printf("Test5m FAILED\n"); + dltdata->tests_failed++; + } + dltdata->running_test = 0; + } + else if (dltdata->running_test==5) + { + if (strcmp(text,"Next line: DLT_LOG_INT")==0) + { + dltdata->test_counter_macro[4]++; + } + if (strcmp(text,"-42")==0) + { + dltdata->test_counter_macro[4]++; + } + + if (strcmp(text,"Next line: DLT_LOG_UINT")==0) + { + dltdata->test_counter_macro[4]++; + } + if (strcmp(text,"42")==0) + { + dltdata->test_counter_macro[4]++; + } + + if (strcmp(text,"Next line: DLT_LOG_STRING")==0) + { + dltdata->test_counter_macro[4]++; + } + if (strcmp(text,"String output")==0) + { + dltdata->test_counter_macro[4]++; + } + + if (strcmp(text,"Next line: DLT_LOG_RAW")==0) + { + dltdata->test_counter_macro[4]++; + } + if (strcmp(text,"00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f")==0) + { + dltdata->test_counter_macro[4]++; + } + + if (strcmp(text,"Next line: DLT_LOG_STRING_INT")==0) + { + dltdata->test_counter_macro[4]++; + } + if (strcmp(text,"String output: -42")==0) + { + dltdata->test_counter_macro[4]++; + } + + if (strcmp(text,"Next line: DLT_LOG_STRING_UINT")==0) + { + dltdata->test_counter_macro[4]++; + } + if (strcmp(text,"String output: 42")==0) + { + dltdata->test_counter_macro[4]++; + } + } + + /* check test 6m */ + if (strcmp(text,"Test 6: (Macro IF) Test local printing")==0) + { + printf("Test6m: (Macro IF) Test local printing\n"); + dltdata->running_test = 6; + dltdata->test_counter_macro[5]=0; + } + else if (strcmp(text,"Test6: (Macro IF) finished")==0) + { + if (dltdata->test_counter_macro[5]==2) + { + printf("Test6m PASSED\n"); + dltdata->tests_passed++; + } + else + { + printf("Test6m FAILED\n"); + dltdata->tests_failed++; + } + dltdata->running_test = 0; + } + else if (dltdata->running_test==6) + { + dltdata->test_counter_macro[5]++; + } + + /* check test 7m */ + if (strcmp(text,"Test 7: (Macro IF) Test network trace")==0) + { + printf("Test7m: (Macro IF) Test network trace\n"); + dltdata->running_test = 7; + dltdata->test_counter_macro[6]=0; + } + else if (strcmp(text,"Test7: (Macro IF) finished")==0) + { + if (dltdata->test_counter_macro[6]==8) + { + printf("Test7m PASSED\n"); + dltdata->tests_passed++; + } + else + { + printf("Test7m FAILED\n"); + dltdata->tests_failed++; + } + dltdata->running_test = 0; + } + else if (dltdata->running_test==7) + { + if (DLT_IS_HTYP_UEH(message->standardheader->htyp)) + { + if ((DLT_GET_MSIN_MSTP(message->extendedheader->msin))==DLT_TYPE_NW_TRACE) + { + /* Check message type information*/ + /* Each correct message type increases the counter by 1 */ + mtin=DLT_GET_MSIN_MTIN(message->extendedheader->msin); + + if (mtin==DLT_NW_TRACE_IPC) + { + dltdata->test_counter_macro[6]++; + } + if (mtin==DLT_NW_TRACE_CAN) + { + dltdata->test_counter_macro[6]++; + } + if (mtin==DLT_NW_TRACE_FLEXRAY) + { + dltdata->test_counter_macro[6]++; + } + if (mtin==DLT_NW_TRACE_MOST) + { + dltdata->test_counter_macro[6]++; + } + + /* Check payload, must be two arguments (2 raw data blocks) */ + /* If the payload is correct, the counter is increased by 1 */ + if (message->extendedheader->noar==2) + { + /* verbose mode */ + type_info=0; + type_info_tmp=0; + length=0,length_tmp=0; /* the macro can set this variable to -1 */ + + ptr = message->databuffer; + datalength = message->datasize; + + /* first read the type info of the first argument: must be string */ + DLT_MSG_READ_VALUE(type_info_tmp,ptr,datalength,uint32_t); + type_info=DLT_ENDIAN_GET_32(message->standardheader->htyp, type_info_tmp); + + if (type_info & DLT_TYPE_INFO_RAWD) + { + /* skip string */ + DLT_MSG_READ_VALUE(length_tmp,ptr,datalength,uint16_t); + length=DLT_ENDIAN_GET_16(message->standardheader->htyp, length_tmp); + + if (length>=0) + { + ptr+=length; + datalength-=length; + + /* read type of second argument: must be raw */ + DLT_MSG_READ_VALUE(type_info_tmp,ptr,datalength,uint32_t); + type_info=DLT_ENDIAN_GET_32(message->standardheader->htyp, type_info_tmp); + + if (type_info & DLT_TYPE_INFO_RAWD) + { + /* get length of raw data block */ + DLT_MSG_READ_VALUE(length_tmp,ptr,datalength,uint16_t); + length=DLT_ENDIAN_GET_16(message->standardheader->htyp, length_tmp); + + if ((length>=0) && (length==datalength)) + { + //printf("Raw data found in payload, length="); + //printf("%d, datalength=%d \n", length, datalength); + dltdata->test_counter_macro[6]++; + } + } + } + } + } + } + } + } + + /* check test 1f */ + if (strcmp(text,"Test1: (Function IF) Test all log levels")==0) + { + printf("Test1f: (Function IF) Test all log levels\n"); + dltdata->running_test = 8; + dltdata->test_counter_function[0] = 0; + } + else if (strcmp(text,"Test1: (Function IF) finished")==0) + { + /* >=4, as "info" is default log level */ + if (dltdata->test_counter_function[0]>=4) + { + printf("Test1f PASSED\n"); + dltdata->tests_passed++; + } + else + { + printf("Test1f FAILED\n"); + dltdata->tests_failed++; + } + dltdata->running_test = 0; + } + else if (dltdata->running_test==8) + { + if (DLT_IS_HTYP_UEH(message->standardheader->htyp)) + { + if ((DLT_GET_MSIN_MSTP(message->extendedheader->msin))==DLT_TYPE_LOG) + { + mtin=DLT_GET_MSIN_MTIN(message->extendedheader->msin); + + if (mtin==DLT_LOG_FATAL) + { + dltdata->test_counter_function[0]++; + } + if (mtin==DLT_LOG_ERROR) + { + dltdata->test_counter_function[0]++; + } + if (mtin==DLT_LOG_WARN) + { + dltdata->test_counter_function[0]++; + } + if (mtin==DLT_LOG_INFO) + { + dltdata->test_counter_function[0]++; + } + if (mtin==DLT_LOG_DEBUG) + { + dltdata->test_counter_function[0]++; + } + if (mtin==DLT_LOG_VERBOSE) + { + dltdata->test_counter_function[0]++; + } + } + } + } + + /* check test 2f */ + if (strcmp(text,"Test2: (Function IF) Test all variable types (verbose)")==0) + { + printf("Test2f: (Function IF) Test all variable types (verbose)\n"); + dltdata->running_test = 9; + dltdata->test_counter_function[1] = 0; + } + else if (strcmp(text,"Test2: (Function IF) finished")==0) + { + if (dltdata->test_counter_function[1]==14) + { + printf("Test2f PASSED\n"); + dltdata->tests_passed++; + } + else + { + printf("Test2f FAILED\n"); + dltdata->tests_failed++; + } + dltdata->running_test = 0; + } + else if (dltdata->running_test==9) + { + /* Verbose */ + if (!(DLT_MSG_IS_NONVERBOSE(message))) + { + type_info=0; + type_info_tmp=0; + length=0; + length_tmp=0; /* the macro can set this variable to -1 */ + ptr = message->databuffer; + datalength = message->datasize; + + /* Log message */ + if ((DLT_GET_MSIN_MSTP(message->extendedheader->msin))==DLT_TYPE_LOG) + { + if (message->extendedheader->noar>=2) + { + /* get type of first argument: must be string */ + DLT_MSG_READ_VALUE(type_info_tmp,ptr,datalength,uint32_t); + type_info=DLT_ENDIAN_GET_32(message->standardheader->htyp, type_info_tmp); + + if (type_info & DLT_TYPE_INFO_STRG) + { + /* skip string */ + DLT_MSG_READ_VALUE(length_tmp,ptr,datalength,uint16_t); + length=DLT_ENDIAN_GET_16(message->standardheader->htyp, length_tmp); + + if (length>=0) + { + ptr+=length; + datalength-=length; + + /* read type of second argument: must be raw */ + DLT_MSG_READ_VALUE(type_info_tmp,ptr,datalength,uint32_t); + type_info=DLT_ENDIAN_GET_32(message->standardheader->htyp, type_info_tmp); + + if (type_info & DLT_TYPE_INFO_BOOL) + { + if (datalength==sizeof(uint8_t)) + { + dltdata->test_counter_function[1]++; + } + } + else if (type_info & DLT_TYPE_INFO_SINT) + { + switch (type_info & DLT_TYPE_INFO_TYLE) + { + case DLT_TYLE_8BIT: + { + if (datalength==sizeof(int8_t)) + { + dltdata->test_counter_function[1]++; + } + break; + } + case DLT_TYLE_16BIT: + { + if (datalength==sizeof(int16_t)) + { + dltdata->test_counter_function[1]++; + } + break; + } + case DLT_TYLE_32BIT: + { + if (datalength==sizeof(int32_t)) + { + dltdata->test_counter_function[1]++; + } + break; + } + case DLT_TYLE_64BIT: + { + if (datalength==sizeof(int64_t)) + { + dltdata->test_counter_function[1]++; + } + break; + } + case DLT_TYLE_128BIT: + { + /* Not tested here */ + break; + } + } + } + else if (type_info & DLT_TYPE_INFO_UINT) + { + switch (type_info & DLT_TYPE_INFO_TYLE) + { + case DLT_TYLE_8BIT: + { + if (datalength==sizeof(uint8_t)) + { + dltdata->test_counter_function[1]++; + } + break; + } + case DLT_TYLE_16BIT: + { + if (datalength==sizeof(uint16_t)) + { + dltdata->test_counter_function[1]++; + } + break; + } + case DLT_TYLE_32BIT: + { + if (datalength==sizeof(uint32_t)) + { + dltdata->test_counter_function[1]++; + } + break; + } + case DLT_TYLE_64BIT: + { + if (datalength==sizeof(uint64_t)) + { + dltdata->test_counter_function[1]++; + } + break; + } + case DLT_TYLE_128BIT: + { + /* Not tested here */ + break; + } + } + } + else if (type_info & DLT_TYPE_INFO_FLOA) + { + switch (type_info & DLT_TYPE_INFO_TYLE) + { + case DLT_TYLE_8BIT: + { + /* Not tested here */ + break; + } + case DLT_TYLE_16BIT: + { + /* Not tested here */ + break; + } + case DLT_TYLE_32BIT: + { + if (datalength==(2*sizeof(float)+sizeof(uint32_t))) + { + dltdata->test_counter_function[1]++; + } + break; + } + case DLT_TYLE_64BIT: + { + if (datalength==(2*sizeof(double)+sizeof(uint32_t))) + { + dltdata->test_counter_function[1]++; + } + break; + } + case DLT_TYLE_128BIT: + { + /* Not tested here */ + break; + } + } + } + else if (type_info & DLT_TYPE_INFO_RAWD) + { + /* Get length */ + DLT_MSG_READ_VALUE(length_tmp,ptr,datalength,uint16_t); + length=DLT_ENDIAN_GET_16(message->standardheader->htyp, length_tmp); + if ((length==datalength) && (length=10)) + { + dltdata->test_counter_function[1]++; + } + } + } + } + } + } + } + } + + /* check test 3f */ + if (strcmp(text,"Test3: (Function IF) Test all variable types (non-verbose)")==0) + { + printf("Test3f: (Function IF) Test all variable types (non-verbose)\n"); + dltdata->running_test = 10; + dltdata->test_counter_function[2]=0; + } + else if (strcmp(text,"Test3: (Function IF) finished")==0) + { + if (dltdata->test_counter_function[2]==14) + { + printf("Test3f PASSED\n"); + dltdata->tests_passed++; + } + else + { + printf("Test3f FAILED\n"); + dltdata->tests_failed++; + } + dltdata->running_test = 0; + } + else if (dltdata->running_test==10) + { + /* Nonverbose */ + if (DLT_MSG_IS_NONVERBOSE(message)) + { + id=0; + id_tmp=0; + ptr = message->databuffer; + datalength = message->datasize; + slen=-1; + + tc_old=dltdata->test_counter_function[2]; + + /* Get message id */ + DLT_MSG_READ_VALUE(id_tmp,ptr,datalength,uint32_t); + id=DLT_ENDIAN_GET_32(message->standardheader->htyp, id_tmp); + + /* Length of string */ + datalength-=sizeof(uint16_t); + ptr+=sizeof(uint16_t); + + switch (id) + { + case 1: + { + slen=strlen("bool")+1; + datalength-=slen; + ptr+=slen; + if (datalength==sizeof(uint8_t)) + { + dltdata->test_counter_function[2]++; + } + break; + } + case 2: + { + slen=strlen("int")+1; + datalength-=slen; + ptr+=slen; + if (datalength==sizeof(int)) + { + dltdata->test_counter_function[2]++; + } + break; + } + case 3: + { + slen=strlen("int8")+1; + datalength-=slen; + ptr+=slen; + if (datalength==sizeof(int8_t)) + { + dltdata->test_counter_function[2]++; + } + break; + } + case 4: + { + slen=strlen("int16")+1; + datalength-=slen; + ptr+=slen; + if (datalength==sizeof(int16_t)) + { + dltdata->test_counter_function[2]++; + } + break; + } + case 5: + { + slen=strlen("int32")+1; + datalength-=slen; + ptr+=slen; + if (datalength==sizeof(int32_t)) + { + dltdata->test_counter_function[2]++; + } + break; + } + case 6: + { + slen=strlen("int64")+1; + datalength-=slen; + ptr+=slen; + if (datalength==sizeof(int64_t)) + { + dltdata->test_counter_function[2]++; + } + break; + } + case 7: + { + slen=strlen("uint")+1; + datalength-=slen; + ptr+=slen; + if (datalength==sizeof(unsigned int)) + { + dltdata->test_counter_function[2]++; + } + break; + } + case 8: + { + slen=strlen("uint8")+1; + datalength-=slen; + ptr+=slen; + if (datalength==sizeof(uint8_t)) + { + dltdata->test_counter_function[2]++; + } + break; + } + case 9: + { + slen=strlen("uint16")+1; + datalength-=slen; + ptr+=slen; + if (datalength==sizeof(uint16_t)) + { + dltdata->test_counter_function[2]++; + } + break; + } + case 10: + { + slen=strlen("uint32")+1; + datalength-=slen; + ptr+=slen; + if (datalength==sizeof(uint32_t)) + { + dltdata->test_counter_function[2]++; + } + break; + } + case 11: + { + slen=strlen("uint64")+1; + datalength-=slen; + ptr+=slen; + if (datalength==sizeof(uint64_t)) + { + dltdata->test_counter_function[2]++; + } + break; + } + case 12: + { + slen=strlen("float32")+1; + datalength-=slen; + ptr+=slen; + /* 2*, as the min and the max is transfered */ + if (datalength==2*sizeof(float)) + { + dltdata->test_counter_function[2]++; + } + break; + } + case 13: + { + slen=strlen("float64")+1; + datalength-=slen; + ptr+=slen; + /* 2*, as the min and the max is transfered */ + if (datalength==2*sizeof(double)) + { + dltdata->test_counter_function[2]++; + } + break; + } + case 14: + { + slen=strlen("raw")+1; + datalength-=slen; + ptr+=slen; + datalength-=sizeof(uint16_t); + ptr+=sizeof(uint16_t); + if (datalength==10) + { + dltdata->test_counter_function[2]++; + } + break; + } + } + + if ((slen>=0) && (tc_old==dltdata->test_counter_function[2])) + { + printf("ID=%d, Datalength=%d => Failed!",id,datalength); + } + } + } + + /* check test 4f */ + if (strcmp(text,"Test4: (Function IF) Test different message sizes")==0) + { + printf("Test4f: (Function IF) Test different message sizes\n"); + dltdata->running_test = 11; + dltdata->test_counter_function[3]=0; + } + else if (strcmp(text,"Test4: (Function IF) finished")==0) + { + if (dltdata->test_counter_function[3]==4) + { + printf("Test4f PASSED\n"); + dltdata->tests_passed++; + } + else + { + printf("Test4f FAILED\n"); + dltdata->tests_failed++; + } + dltdata->running_test = 0; + } + else if (dltdata->running_test==11) + { + /* Extended header */ + if (DLT_IS_HTYP_UEH(message->standardheader->htyp)) + { + /* Log message */ + if ((DLT_GET_MSIN_MSTP(message->extendedheader->msin))==DLT_TYPE_LOG) + { + /* Verbose */ + if (DLT_IS_MSIN_VERB(message->extendedheader->msin)) + { + /* 2 arguments */ + if (message->extendedheader->noar==2) + { + /* verbose mode */ + type_info=0; + type_info_tmp=0; + length=0; + length_tmp=0; /* the macro can set this variable to -1 */ + + ptr = message->databuffer; + datalength = message->datasize; + + /* first read the type info of the first argument: should be string */ + DLT_MSG_READ_VALUE(type_info_tmp,ptr,datalength,uint32_t); + type_info=DLT_ENDIAN_GET_32(message->standardheader->htyp, type_info_tmp); + + if (type_info & DLT_TYPE_INFO_STRG) + { + /* skip string */ + DLT_MSG_READ_VALUE(length_tmp,ptr,datalength,uint16_t); + length=DLT_ENDIAN_GET_16(message->standardheader->htyp, length_tmp); + + if (length>=0) + { + ptr+=length; + datalength-=length; + + /* read type of second argument: should be raw */ + DLT_MSG_READ_VALUE(type_info_tmp,ptr,datalength,uint32_t); + type_info=DLT_ENDIAN_GET_32(message->standardheader->htyp, type_info_tmp); + + if (type_info & DLT_TYPE_INFO_RAWD) + { + /* get length of raw data block */ + DLT_MSG_READ_VALUE(length_tmp,ptr,datalength,uint16_t); + length=DLT_ENDIAN_GET_16(message->standardheader->htyp, length_tmp); + + if ((length>=0) && (length==datalength)) + { + //printf("Raw data found in payload, length="); + //printf("%d, datalength=%d \n", length, datalength); + dltdata->test_counter_function[3]++; + } + } + } + } + } + } + } + } + } + + /* check test 5f */ + if (strcmp(text,"Test5: (Function IF) Test high-level API")==0) + { + printf("Test5f: (Function IF) Test high-level API\n"); + dltdata->running_test = 12; + dltdata->test_counter_function[4]=0; + } + else if (strcmp(text,"Test5: (Function IF) finished")==0) + { + if (dltdata->test_counter_function[4]==12) + { + printf("Test5f PASSED\n"); + dltdata->tests_passed++; + } + else + { + printf("Test5f FAILED\n"); + dltdata->tests_failed++; + } + dltdata->running_test = 0; + } + else if (dltdata->running_test==12) + { + if (strcmp(text,"Next line: dlt_log_int()")==0) + { + dltdata->test_counter_function[4]++; + } + if (strcmp(text,"-42")==0) + { + dltdata->test_counter_function[4]++; + } + + if (strcmp(text,"Next line: dlt_log_uint()")==0) + { + dltdata->test_counter_function[4]++; + } + if (strcmp(text,"42")==0) + { + dltdata->test_counter_function[4]++; + } + + if (strcmp(text,"Next line: dlt_log_string()")==0) + { + dltdata->test_counter_function[4]++; + } + if (strcmp(text,"String output")==0) + { + dltdata->test_counter_function[4]++; + } + + if (strcmp(text,"Next line: dlt_log_raw()")==0) + { + dltdata->test_counter_function[4]++; + } + if (strcmp(text,"00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f")==0) + { + dltdata->test_counter_function[4]++; + } + + if (strcmp(text,"Next line: dlt_log_string_int()")==0) + { + dltdata->test_counter_function[4]++; + } + if (strcmp(text,"String output: -42")==0) + { + dltdata->test_counter_function[4]++; + } + + if (strcmp(text,"Next line: dlt_log_string_uint()")==0) + { + dltdata->test_counter_function[4]++; + } + if (strcmp(text,"String output: 42")==0) + { + dltdata->test_counter_function[4]++; + } + } + + /* check test 6f */ + if (strcmp(text,"Test 6: (Function IF) Test local printing")==0) + { + printf("Test6f: (Function IF) Test local printing\n"); + dltdata->running_test = 13; + dltdata->test_counter_function[5]=0; + } + else if (strcmp(text,"Test6: (Function IF) finished")==0) + { + if (dltdata->test_counter_function[5]==2) + { + printf("Test6f PASSED\n"); + dltdata->tests_passed++; + } + else + { + printf("Test6f FAILED\n"); + dltdata->tests_failed++; + } + dltdata->running_test = 0; + } + else if (dltdata->running_test==13) + { + dltdata->test_counter_function[5]++; + } + + /* check test 7f */ + if (strcmp(text,"Test 7: (Function IF) Test network trace")==0) + { + printf("Test7f: (Function IF) Test network trace\n"); + dltdata->running_test = 14; + dltdata->test_counter_function[6]=0; + } + else if (strcmp(text,"Test7: (Function IF) finished")==0) + { + if (dltdata->test_counter_function[6]==8) + { + printf("Test7f PASSED\n"); + dltdata->tests_passed++; + } + else + { + printf("Test7f FAILED\n"); + dltdata->tests_failed++; + } + dltdata->running_test = 0; + } + else if (dltdata->running_test==14) + { + if (DLT_IS_HTYP_UEH(message->standardheader->htyp)) + { + if ((DLT_GET_MSIN_MSTP(message->extendedheader->msin))==DLT_TYPE_NW_TRACE) + { + /* Check message type information*/ + /* Each correct message type increases the counter by 1 */ + mtin=DLT_GET_MSIN_MTIN(message->extendedheader->msin); + + if (mtin==DLT_NW_TRACE_IPC) + { + dltdata->test_counter_function[6]++; + } + if (mtin==DLT_NW_TRACE_CAN) + { + dltdata->test_counter_function[6]++; + } + if (mtin==DLT_NW_TRACE_FLEXRAY) + { + dltdata->test_counter_function[6]++; + } + if (mtin==DLT_NW_TRACE_MOST) + { + dltdata->test_counter_function[6]++; + } + + /* Check payload, must be two arguments (2 raw data blocks) */ + /* If the payload is correct, the counter is increased by 1 */ + if (message->extendedheader->noar==2) + { + /* verbose mode */ + type_info=0; + type_info_tmp=0; + length=0; + length_tmp=0; /* the macro can set this variable to -1 */ + + ptr = message->databuffer; + datalength = message->datasize; + + /* first read the type info of the first argument: should be string */ + DLT_MSG_READ_VALUE(type_info_tmp,ptr,datalength,uint32_t); + type_info=DLT_ENDIAN_GET_32(message->standardheader->htyp, type_info_tmp); + + if (type_info & DLT_TYPE_INFO_RAWD) + { + /* skip string */ + DLT_MSG_READ_VALUE(length_tmp,ptr,datalength,uint16_t); + length=DLT_ENDIAN_GET_16(message->standardheader->htyp, length_tmp); + + if (length>=0) + { + ptr+=length; + datalength-=length; + + /* read type of second argument: should be raw */ + DLT_MSG_READ_VALUE(type_info_tmp,ptr,datalength,uint32_t); + type_info=DLT_ENDIAN_GET_32(message->standardheader->htyp, type_info_tmp); + + if (type_info & DLT_TYPE_INFO_RAWD) + { + /* get length of raw data block */ + DLT_MSG_READ_VALUE(length_tmp,ptr,datalength,uint16_t); + length=DLT_ENDIAN_GET_16(message->standardheader->htyp, length_tmp); + + if ((length>=0) && (length==datalength)) + { + //printf("Raw data found in payload, length="); + //printf("%d, datalength=%d \n", length, datalength); + dltdata->test_counter_function[6]++; + } + } + } + } + } + } + } + } + + if (strcmp(text,"Tests finished")==0) + { + printf("Tests finished\n"); + dltdata->running_test = 1; + + printf("%d tests passed\n",dltdata->tests_passed); + printf("%d tests failed\n",dltdata->tests_failed); + + if (dltdata->sock!=-1) + { + close(dltdata->sock); + } + + return 0; + } + + /* if no filter set or filter is matching display message */ + if (dltdata->xflag) + { + dlt_message_print_hex(message,text,DLT_TESTCLIENT_TEXTBUFSIZE,dltdata->vflag); + } + else if (dltdata->mflag) + { + dlt_message_print_mixed_plain(message,text,DLT_TESTCLIENT_TEXTBUFSIZE,dltdata->vflag); + } + else if (dltdata->sflag) + { + dlt_message_print_header(message,text,sizeof(text),dltdata->vflag); + } + + /* if file output enabled write message */ + if (dltdata->ovalue) + { + iov[0].iov_base = message->headerbuffer; + iov[0].iov_len = message->headersize; + iov[1].iov_base = message->databuffer; + iov[1].iov_len = message->datasize; + + bytes_written = writev(dltdata->ohandle, iov, 2); + } + } + + return 0; +} diff --git a/src/tests/dlt-test-internal.c b/src/tests/dlt-test-internal.c new file mode 100755 index 0000000..00209f1 --- /dev/null +++ b/src/tests/dlt-test-internal.c @@ -0,0 +1,307 @@ +/* + * Dlt Client test utilities - Diagnostic Log and Trace + * @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-test-internal.c ** +** ** +** TARGET : linux ** +** ** +** PROJECT : DLT ** +** ** +** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** +** Markus Klein ** +** ** +** PURPOSE : ** +** ** +** REMARKS : ** +** ** +** PLATFORM DEPENDANT [yes/no]: yes ** +** ** +** TO BE CHANGED BY USER [yes/no]: no ** +** ** +*******************************************************************************/ + +/******************************************************************************* +** Author Identity ** +******************************************************************************** +** ** +** Initials Name Company ** +** -------- ------------------------- ---------------------------------- ** +** aw Alexander Wenzel BMW ** +** mk Markus Klein Fraunhofer ESK ** +*******************************************************************************/ + +/******************************************************************************* +** Revision Control History ** +*******************************************************************************/ + +/* + * $LastChangedRevision: 1670 $ + * $LastChangedDate: 2011-04-08 15:12:06 +0200 (Fr, 08. Apr 2011) $ + * $LastChangedBy$ + Initials Date Comment + aw 08.10.2010 initial + */ + +#include <ctype.h> /* for isprint() */ +#include <stdio.h> /* for printf() and fprintf() */ +#include <stdlib.h> /* for atoi() and exit() */ +#include <string.h> /* for memset() */ + +#include "dlt.h" +#include "dlt_common.h" /* for dlt_get_version() */ + +#define MAX_TESTS 1 + +int vflag = 0; +int tests_passed = 0; +int tests_failed = 0; + +void internal1(void); + +/** + * Print usage information of tool. + */ +void usage() +{ + char version[255]; + + dlt_get_version(version); + + printf("Usage: dlt-test-internal [options]\n"); + printf("Test application executing several internal tests.\n"); + printf("%s \n", version); + printf("Options:\n"); + printf(" -v Verbose mode\n"); + printf(" -1 Execute test 1 (Test ringbuffer)\n"); +} + +/** + * Main function of tool. + */ +int main(int argc, char* argv[]) +{ + int test[MAX_TESTS]; + + int i,c,help; + + for (i=0;i<MAX_TESTS;i++) + { + test[i]=0; + } + + opterr = 0; + + while ((c = getopt (argc, argv, "v1")) != -1) + { + switch (c) + { + case 'v': + { + vflag = 1; + break; + } + case '1': + { + test[0] = 1; + break; + } + case '?': + { + if (isprint (optopt)) + { + fprintf (stderr, "Unknown option `-%c'.\n", optopt); + } + else + { + fprintf (stderr, "Unknown option character `\\x%x'.\n",optopt); + } + /* unknown or wrong option used, show usage information and terminate */ + usage(); + return -1; + } + default: + { + abort (); + } + } + } + + help=0; + for (i=0;i<MAX_TESTS;i++) + { + if (test[i]==1) + { + help=1; + break; + } + } + + if (help==0) + { + usage(); + return -1; + } + + if (test[0]) + { + internal1(); + } + + printf("\n"); + printf("%d tests passed\n",tests_passed); + printf("%d tests failed\n",tests_failed); + + 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 new file mode 100755 index 0000000..ea17857 --- /dev/null +++ b/src/tests/dlt-test-stress.c @@ -0,0 +1,373 @@ +/* + * Dlt Client test utilities - Diagnostic Log and Trace + * @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-test-stress.c ** +** ** +** TARGET : linux ** +** ** +** PROJECT : DLT ** +** ** +** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** +** Markus Klein ** +** ** +** PURPOSE : ** +** ** +** REMARKS : ** +** ** +** PLATFORM DEPENDANT [yes/no]: yes ** +** ** +** TO BE CHANGED BY USER [yes/no]: no ** +** ** +*******************************************************************************/ + +/******************************************************************************* +** Author Identity ** +******************************************************************************** +** ** +** Initials Name Company ** +** -------- ------------------------- ---------------------------------- ** +** aw Alexander Wenzel BMW ** +** mk Markus Klein Fraunhofer ESK ** +*******************************************************************************/ + +/******************************************************************************* +** Revision Control History ** +*******************************************************************************/ + +/* + * $LastChangedRevision: 1670 $ + * $LastChangedDate: 2011-04-08 15:12:06 +0200 (Fr, 08. Apr 2011) $ + * $LastChangedBy$ + Initials Date Comment + aw 13.01.2010 initial + */ +#include <netdb.h> +#include <ctype.h> /* for isprint() */ +#include <errno.h> +#include <stdio.h> /* for printf() and fprintf() */ +#include <stdlib.h> /* for atoi() and exit() */ +#include <string.h> /* for memset() */ +#include <unistd.h> /* for close() */ +#include <pthread.h> /* POSIX Threads */ + +#include "dlt.h" +#include "dlt_common.h" /* for dlt_get_version() */ + +DltContext mycontext[9999]; + +typedef struct +{ + int num; +} thread_data_t; + +#define STRESS1_NUM_CONTEXTS 3000 +#define STRESS2_MAX_NUM_THREADS 256 +#define STRESS3_MAX_NUM_MESSAGES 512 + +#define MAX_TESTS 3 + +void stress1(void); + +void stress2(void); +void thread_function(void *ptr); + +void stress3(void); + +/** + * Print usage information of tool. + */ +void usage() +{ + char version[255]; + + dlt_get_version(version); + + printf("Usage: dlt-test-stress [options]\n"); + printf("Test application executing several stress tests.\n"); + printf("%s \n", version); + printf("Options:\n"); + printf(" -v Verbose mode\n"); + printf(" -f filename Use local log file instead of sending to daemon\n"); + printf(" -1 Execute test 1 (register/unregister many contexts)\n"); + printf(" -2 Execute test 2 (multiple threads logging data)\n"); + printf(" -3 Execute test 3 (logging much data)\n"); +} + +/** + * Main function of tool. + */ +int main(int argc, char* argv[]) +{ + int vflag = 0; + char *fvalue = 0; + int test[MAX_TESTS]; + + int i,c,help; + + for (i=0;i<MAX_TESTS;i++) + { + test[i]=0; + } + + opterr = 0; + + while ((c = getopt (argc, argv, "vf:123")) != -1) + { + switch (c) + { + case 'v': + { + vflag = 1; + break; + } + case 'f': + { + fvalue = optarg; + break; + } + case '1': + { + test[0] = 1; + break; + } + case '2': + { + test[1] = 1; + break; + } + case '3': + { + test[2] = 1; + break; + } + case '?': + { + if (optopt == 'f') + { + fprintf (stderr, "Option -%c requires an argument.\n", optopt); + } + else if (isprint (optopt)) + { + fprintf (stderr, "Unknown option `-%c'.\n", optopt); + } + else + { + fprintf (stderr, "Unknown option character `\\x%x'.\n",optopt); + } + /* unknown or wrong option used, show usage information and terminate */ + usage(); + return -1; + } + default: + { + abort (); + } + } + } + + if (fvalue) + { + /* DLT is intialised automatically, except another output target will be used */ + if (dlt_init_file(fvalue)<0) /* log to file */ + { + return -1; + } + } + + help=0; + for (i=0;i<MAX_TESTS;i++) + { + if (test[i]==1) + { + help=1; + break; + } + } + + if (help==0) + { + usage(); + return -1; + } + + DLT_REGISTER_APP("DSTS","DLT daemon stress tests"); + + if (test[0]) + { + stress1(); + } + if (test[1]) + { + stress2(); + } + if (test[2]) + { + stress3(); + } + + DLT_UNREGISTER_APP(); + + sleep(1); + + return 0; +} + +void stress1(void) +{ + int i,c; + char ctid[5]; + + printf("Starting stress test1... (press \"Enter\" to terminate test) \n"); + + printf("* Register %d contexts...\n",STRESS1_NUM_CONTEXTS); + + for (i=0; i<STRESS1_NUM_CONTEXTS; i++) + { + /* Generate id */ + memset(ctid,0,5); + sprintf(ctid,"%d",i); + + //printf("%i: '%s' \n",i,ctid); + + dlt_register_context(&(mycontext[i]),ctid,ctid); + usleep(500); + } + + while (1) + { + c=getchar(); + /* if "Return" is pressed, exit loop; */ + if (c==10) + { + break; + } + } + + printf("* Unregister %d contexts...\n",STRESS1_NUM_CONTEXTS); + + for (i=0; i<STRESS1_NUM_CONTEXTS; i++) + { + DLT_UNREGISTER_CONTEXT(mycontext[i]); + usleep(500); + } + + printf("Finished stress test1 \n\n"); +} + +void stress2(void) +{ + int ret,index; + + pthread_t thread[STRESS2_MAX_NUM_THREADS]; + thread_data_t thread_data[STRESS2_MAX_NUM_THREADS]; + + printf("Starting stress test2... \n"); + + srand(time(NULL)); + + printf("* Creating %d Threads, each of them registers one context,\n",STRESS2_MAX_NUM_THREADS); + printf(" sending one log message, then unregisters the context\n"); + + for (index=0;index<STRESS2_MAX_NUM_THREADS;index++) + { + thread_data[index].num = index; + ret=pthread_create(&(thread[index]), NULL, (void *) &thread_function, (void *) &(thread_data[index])); + if (ret!=0) + { + printf("Error creating thread %d: %s \n", index, strerror(errno)); + } + + usleep(1000); + } + + for (index=0;index<STRESS2_MAX_NUM_THREADS;index++) + { + if (thread[index]!=0) + { + pthread_join(thread[index], NULL); + } + } + + printf("Finished stress test2 \n\n"); +} + +void thread_function(void *ptr) +{ + thread_data_t *data; + DLT_DECLARE_CONTEXT(context_thread1); + char ctid[5]; + + data = (thread_data_t *) ptr; + + memset(ctid,0,5); + + /* Create random context id */ + sprintf(ctid,"%.2x", rand() & 0x0000ffff); + + usleep(rand()/1000); + + DLT_REGISTER_CONTEXT(context_thread1,ctid,ctid); + + DLT_LOG(context_thread1,DLT_LOG_INFO,DLT_STRING(ctid)); + + DLT_UNREGISTER_CONTEXT(context_thread1); +} + +void stress3(void) +{ + DLT_DECLARE_CONTEXT(context_stress3); + char buffer[STRESS3_MAX_NUM_MESSAGES]; + int num; + + /* Performance test */ + DLT_REGISTER_CONTEXT(context_stress3,"TST3","Stress Test 3 - Performance"); + + printf("Starting stress test3... \n"); + printf("* Logging raw data, up to a size of %d\n",STRESS3_MAX_NUM_MESSAGES); + + for (num=0;num<STRESS3_MAX_NUM_MESSAGES;num++) + { + buffer[num] = num; + DLT_LOG(context_stress3,DLT_LOG_INFO,DLT_INT(num),DLT_RAW(buffer,num)); + usleep(1); + } + + printf("Finished stress test3 \n\n"); +} diff --git a/src/tests/dlt-test-user.c b/src/tests/dlt-test-user.c new file mode 100755 index 0000000..3803797 --- /dev/null +++ b/src/tests/dlt-test-user.c @@ -0,0 +1,1069 @@ +/*
+ * Dlt Test user - Diagnostic Log and Trace
+ * @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-test-user.c **
+** **
+** TARGET : linux ** +** ** +** PROJECT : DLT ** +** ** +** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** +** Markus Klein ** +** ** +** PURPOSE : ** +** ** +** REMARKS : ** +** ** +** PLATFORM DEPENDANT [yes/no]: yes ** +** ** +** TO BE CHANGED BY USER [yes/no]: no ** +** ** +*******************************************************************************/ + +/******************************************************************************* +** Author Identity ** +******************************************************************************** +** ** +** Initials Name Company ** +** -------- ------------------------- ---------------------------------- ** +** aw Alexander Wenzel BMW ** +** mk Markus Klein Fraunhofer ESK ** +*******************************************************************************/
+
+/*******************************************************************************
+** Revision Control History **
+*******************************************************************************/
+
+/*
+ * $LastChangedRevision: 1670 $
+ * $LastChangedDate: 2011-04-08 15:12:06 +0200 (Fr, 08. Apr 2011) $
+ * $LastChangedBy$
+ Initials Date Comment
+ aw 13.01.2010 initial
+ */
+ +#include <stdio.h> /* for printf() and fprintf() */ +#include <float.h> +#include <stdlib.h> /* for atoi(), abort() */ +#include <string.h> /* for memset() */ +#include <ctype.h> /* for isprint() */ + +#include "dlt.h" + +#define DLT_TEST_NUM_CONTEXT 7 + +/* Test functions... */ + +/* for macro interface */ +int test1m(void); +int test2m(void); +int test3m(void); +int test4m(void); +int test5m(void); +int test6m(void); +int test7m(void); + +/* for function interface */ +int test1f(void); +int test2f(void); +int test3f(void); +int test4f(void); +int test5f(void); +int test6f(void); +int test7f(void); + +/* Declaration of callback functions */ +int test_injection_macro_callback(uint32_t service_id, void *data, uint32_t length); +int test_injection_function_callback(uint32_t service_id, void *data, uint32_t length); + +/* Context declaration.. */ +DLT_DECLARE_CONTEXT(context_info); + +/* for macro interface */ +DLT_DECLARE_CONTEXT(context_macro_callback); +DLT_DECLARE_CONTEXT(context_macro_test[DLT_TEST_NUM_CONTEXT]); + +/* for function interface */ +DltContext context_function_callback;
+DltContext context_function_test[DLT_TEST_NUM_CONTEXT]; + +DltContextData context_data;
+
+/**
+ * Print usage information of tool.
+ */
+void usage()
+{
+ char version[255];
+
+ dlt_get_version(version);
+
+ printf("Usage: dlt-test-user [options]\n");
+ printf("Test user application providing several Tests.\n");
+ printf("%s \n", version);
+ printf("Options:\n");
+ printf(" -v Verbose mode\n");
+ printf(" -f filename Use local log file instead of sending to daemon\n");
+ printf(" -n count Repeats of tests (Default: 1)\n");
+ printf("Tests:\n");
+ printf(" 1m: (Macro IF) Test all log levels\n"); + printf(" 2m: (Macro IF) Test all variable types (verbose) \n"); + printf(" 3m: (Macro IF) Test all variable types (non-verbose) \n"); + printf(" 4m: (Macro IF) Test different message sizes\n"); + printf(" 5m: (Macro IF) Test high-level API\n"); + printf(" 6m: (Macro IF) Test local printing\n"); + printf(" 7m: (Macro IF) Test network trace\n"); + printf(" 1f: (Function IF) Test all log levels\n"); + printf(" 2f: (Function IF) Test all variable types (verbose) \n"); + printf(" 3f: (Function IF) Test all variable types (non-verbose) \n"); + printf(" 4f: (Function IF) Test different message sizes\n"); + printf(" 5f: (Function IF) Test high-level API\n"); + printf(" 6f: (Function IF) Test local printing\n"); + printf(" 7f: (Function IF) Test network trace\n");
+}
+
+/**
+ * Main function of tool.
+ */
+int main(int argc, char* argv[])
+{
+ int vflag = 0;
+ char *fvalue = 0;
+ char *nvalue = 0; +
+ int c; + + int i; + char ctid[4], ctdesc[255]; + + int num,maxnum;
+
+ opterr = 0;
+
+ while ((c = getopt (argc, argv, "vf:n:")) != -1) + {
+ switch (c)
+ {
+ case 'v': + {
+ vflag = 1;
+ break;
+ } + case 'f':
+ { + fvalue = optarg;
+ break;
+ } + case 'n':
+ { + nvalue = optarg;
+ break;
+ } + case '?': + {
+ if (optopt == 'd' || optopt == 'f' || optopt == 'n')
+ { + fprintf (stderr, "Option -%c requires an argument.\n", optopt);
+ } + else if (isprint (optopt))
+ { + fprintf (stderr, "Unknown option `-%c'.\n", optopt);
+ } + else
+ { + fprintf (stderr, "Unknown option character `\\x%x'.\n",optopt);
+ } + /* unknown or wrong option used, show usage information and terminate */
+ usage();
+ return -1;
+ } + default:
+ { + abort ();
+ } + } + }
+
+ if (fvalue)
+ {
+ /* DLT is intialised automatically, except another output target will be used */
+ if (dlt_init_file(fvalue)<0) /* log to file */ + {
+ return -1; + }
+ } +
+ if (nvalue) + {
+ maxnum = atoi(nvalue);
+ } + else
+ { + maxnum = 1; + } + + /* Register APP */ + DLT_REGISTER_APP("DIFT","DLT Interface Test"); + + /* Register CONTEXTS... */
+ DLT_REGISTER_CONTEXT(context_info,"INFO","Information context"); + + /* used for macro interface tests */ + DLT_REGISTER_CONTEXT(context_macro_callback,"CBM","Callback Test context for macro interface"); + for (i=0;i<DLT_TEST_NUM_CONTEXT;i++) + { + snprintf(ctid,4,"TM%d",i+1); + snprintf(ctdesc,255,"Test %d context for macro interface",i+1); + DLT_REGISTER_CONTEXT(context_macro_test[i],ctid,ctdesc); + } + + /* used for function interface tests */ + dlt_register_context(&context_function_callback,"CBF","Callback Test context for function interface"); + for (i=0;i<DLT_TEST_NUM_CONTEXT;i++) + { + snprintf(ctid,4,"TF%d",i+1); + snprintf(ctdesc,255,"Test %d context for function interface",i+1); + dlt_register_context(&(context_function_test[i]),ctid,ctdesc); + } + + /* Register callbacks... */ + + /* with macro interface */ + DLT_LOG(context_macro_callback,DLT_LOG_INFO,DLT_STRING("Register callback (Macro Interface) for Injection ID: 0xFFF")); + DLT_REGISTER_INJECTION_CALLBACK(context_macro_callback, 0xFFF, test_injection_macro_callback); + + /* with function interface */ + if (dlt_user_log_write_start(&context_function_callback,&context_data,DLT_LOG_INFO))
+ {
+ dlt_user_log_write_string(&context_data,"Register callback (Function Interface) for Injection ID: 0xFFF");
+ dlt_user_log_write_finish(&context_data);
+ } + dlt_register_injection_callback(&context_function_callback, 0xFFF, test_injection_function_callback); +
+ /* Tests starting */
+ printf("Tests starting\n");
+ DLT_LOG(context_info,DLT_LOG_INFO,DLT_STRING("Tests starting"));
+
+ /* wait 3 seconds before starting */
+ sleep(3);
+
+ for (num=0;num<maxnum;num++)
+ { + /* Execute tests... */ + + /* with macro interface */ + test1m();
+ test2m();
+ test3m(); + test4m();
+ test5m(); + test6m(); + test7m(); + + /* with function interface */ + test1f();
+ test2f();
+ test3f(); + test4f();
+ test5f(); + test6f(); + test7f(); +
+ /* wait 1 second before next repeat of tests */
+ sleep(1);
+ }
+
+ /* Tests finished */
+ printf("Tests finished\n");
+ DLT_LOG(context_info,DLT_LOG_INFO,DLT_STRING("Tests finished"));
+
+ /* wait 3 seconds before terminating application */
+ sleep(3);
+ + /* Unregister CONTEXTS... */ + DLT_UNREGISTER_CONTEXT(context_info); + + /* used for macro interface tests */ + for (i=0;i<DLT_TEST_NUM_CONTEXT;i++) + { + DLT_UNREGISTER_CONTEXT(context_macro_test[i]); + } + DLT_UNREGISTER_CONTEXT(context_macro_callback); + + /* used for function interface tests */ + for (i=0;i<DLT_TEST_NUM_CONTEXT;i++) + { + dlt_unregister_context(&(context_function_test[i])); + } + dlt_unregister_context(&context_function_callback); + + /* Unregister APP */
+ DLT_UNREGISTER_APP(); +
+ dlt_free();
+
+ return 0;
+} + +/******************/ +/* The test cases */ +/******************/ + +int test1m(void) +{ + /* Test 1: (Macro IF) Test all log levels */
+ printf("Test1m: (Macro IF) Test all log levels\n");
+ DLT_LOG(context_info,DLT_LOG_INFO,DLT_STRING("Test1: (Macro IF) Test all log levels"));
+
+ DLT_LOG(context_macro_test[0],DLT_LOG_FATAL,DLT_STRING("fatal"));
+ DLT_LOG(context_macro_test[0],DLT_LOG_ERROR,DLT_STRING("error"));
+ DLT_LOG(context_macro_test[0],DLT_LOG_WARN,DLT_STRING("warn"));
+ DLT_LOG(context_macro_test[0],DLT_LOG_INFO,DLT_STRING("info"));
+ DLT_LOG(context_macro_test[0],DLT_LOG_DEBUG,DLT_STRING("debug"));
+ DLT_LOG(context_macro_test[0],DLT_LOG_VERBOSE,DLT_STRING("verbose")); + + /* wait 2 second before next test */
+ sleep(2);
+ DLT_LOG(context_info,DLT_LOG_INFO,DLT_STRING("Test1: (Macro IF) finished")); + + return 0; +} + +int test2m(void) +{ + char buffer[10]; + int num2; + + /* Test 2: (Macro IF) Test all variable types (verbose) */
+ printf("Test2m: (Macro IF) Test all variable types (verbose)\n");
+ DLT_LOG(context_info,DLT_LOG_INFO,DLT_STRING("Test2: (Macro IF) Test all variable types (verbose)"));
+
+ DLT_LOG(context_macro_test[1],DLT_LOG_INFO,DLT_STRING("bool"),DLT_BOOL(1));
+ DLT_LOG(context_macro_test[1],DLT_LOG_INFO,DLT_STRING("int"),DLT_INT(INT32_MIN)); /* (-2147483647-1) */
+ DLT_LOG(context_macro_test[1],DLT_LOG_INFO,DLT_STRING("int8"),DLT_INT8(INT8_MIN)); /* (-128) */
+ DLT_LOG(context_macro_test[1],DLT_LOG_INFO,DLT_STRING("int16"),DLT_INT16(INT16_MIN)); /* (-32767-1) */
+ DLT_LOG(context_macro_test[1],DLT_LOG_INFO,DLT_STRING("int32"),DLT_INT32(INT32_MIN)); /* (-2147483647-1) */
+ DLT_LOG(context_macro_test[1],DLT_LOG_INFO,DLT_STRING("int64"),DLT_INT64(INT64_MIN)); /* (-__INT64_C(9223372036854775807)-1) */
+ DLT_LOG(context_macro_test[1],DLT_LOG_INFO,DLT_STRING("uint"),DLT_UINT(UINT32_MAX)); /* (4294967295U) */
+ DLT_LOG(context_macro_test[1],DLT_LOG_INFO,DLT_STRING("uint8"),DLT_UINT8(UINT8_MAX)); /* (255) */
+ DLT_LOG(context_macro_test[1],DLT_LOG_INFO,DLT_STRING("uint16"),DLT_UINT16(UINT16_MAX)); /* (65535) */
+ DLT_LOG(context_macro_test[1],DLT_LOG_INFO,DLT_STRING("uint32"),DLT_UINT32(UINT32_MAX)); /* (4294967295U) */
+ DLT_LOG(context_macro_test[1],DLT_LOG_INFO,DLT_STRING("uint64"),DLT_UINT64(UINT64_MAX)); /* (__UINT64_C(18446744073709551615)) */ + DLT_LOG(context_macro_test[1],DLT_LOG_INFO,DLT_STRING("float32"),DLT_FLOAT32(FLT_MIN),DLT_FLOAT32(FLT_MAX)); + DLT_LOG(context_macro_test[1],DLT_LOG_INFO,DLT_STRING("float64"),DLT_FLOAT64(DBL_MIN),DLT_FLOAT64(DBL_MAX)); + + for(num2=0;num2<10;num2++) + {
+ buffer[num2] = num2;
+ } + + DLT_LOG(context_macro_test[1],DLT_LOG_INFO,DLT_STRING("raw"),DLT_RAW(buffer,10)); + + /* wait 2 second before next test */
+ sleep(2); + DLT_LOG(context_info,DLT_LOG_INFO,DLT_STRING("Test2: (Macro IF) finished")); + + return 0; +} + +int test3m(void) +{ + char buffer[10]; + int num2; + + /* Test 3: (Macro IF) Test all variable types (non-verbose) */
+ printf("Test3m: (Macro IF) Test all variable types (non-verbose)\n");
+ DLT_LOG(context_info,DLT_LOG_INFO,DLT_STRING("Test3: (Macro IF) Test all variable types (non-verbose)"));
+ + DLT_NONVERBOSE_MODE(); +
+ DLT_LOG_ID(context_macro_test[2],DLT_LOG_INFO,1,DLT_STRING("bool"),DLT_BOOL(1));
+ DLT_LOG_ID(context_macro_test[2],DLT_LOG_INFO,2,DLT_STRING("int"),DLT_INT(INT32_MIN)); /* (-2147483647-1) */
+ DLT_LOG_ID(context_macro_test[2],DLT_LOG_INFO,3,DLT_STRING("int8"),DLT_INT8(INT8_MIN)); /* (-128) */
+ DLT_LOG_ID(context_macro_test[2],DLT_LOG_INFO,4,DLT_STRING("int16"),DLT_INT16(INT16_MIN)); /* (-32767-1) */
+ DLT_LOG_ID(context_macro_test[2],DLT_LOG_INFO,5,DLT_STRING("int32"),DLT_INT32(INT32_MIN)); /* (-2147483647-1) */
+ DLT_LOG_ID(context_macro_test[2],DLT_LOG_INFO,6,DLT_STRING("int64"),DLT_INT64(INT64_MIN)); /* (-__INT64_C(9223372036854775807)-1) */
+ DLT_LOG_ID(context_macro_test[2],DLT_LOG_INFO,7,DLT_STRING("uint"),DLT_UINT(UINT32_MAX)); /* (4294967295U) */
+ DLT_LOG_ID(context_macro_test[2],DLT_LOG_INFO,8,DLT_STRING("uint8"),DLT_UINT8(UINT8_MAX)); /* (255) */
+ DLT_LOG_ID(context_macro_test[2],DLT_LOG_INFO,9,DLT_STRING("uint16"),DLT_UINT16(UINT16_MAX)); /* (65535) */
+ DLT_LOG_ID(context_macro_test[2],DLT_LOG_INFO,10,DLT_STRING("uint32"),DLT_UINT32(UINT32_MAX)); /* (4294967295U) */
+ DLT_LOG_ID(context_macro_test[2],DLT_LOG_INFO,11,DLT_STRING("uint64"),DLT_UINT64(UINT64_MAX)); /* (__UINT64_C(18446744073709551615)) */ + DLT_LOG_ID(context_macro_test[2],DLT_LOG_INFO,12,DLT_STRING("float32"),DLT_FLOAT32(FLT_MIN),DLT_FLOAT32(FLT_MAX)); + DLT_LOG_ID(context_macro_test[2],DLT_LOG_INFO,13,DLT_STRING("float64"),DLT_FLOAT64(DBL_MIN),DLT_FLOAT64(DBL_MAX)); +
+
+ for(num2=0;num2<10;num2++) + {
+ buffer[num2] = num2; + }
+ DLT_LOG_ID(context_macro_test[2],DLT_LOG_INFO,14,DLT_STRING("raw"),DLT_RAW(buffer,10)); + + DLT_VERBOSE_MODE(); + + /* wait 2 second before next test */
+ sleep(2); + DLT_LOG(context_info,DLT_LOG_INFO,DLT_STRING("Test3: (Macro IF) finished")); + + return 0; +} + +int test4m(void) +{ + char buffer[1024];
+ int num;
+ + for(num=0;num<1024;num++) + {
+ buffer[num] = num; + } + + /* Test 4: (Macro IF) Message size test */
+ printf("Test4m: (Macro IF) Test different message sizes\n");
+ DLT_LOG(context_info,DLT_LOG_INFO,DLT_STRING("Test4: (Macro IF) Test different message sizes"));
+
+ DLT_LOG(context_macro_test[3],DLT_LOG_INFO,DLT_STRING("1"),DLT_RAW(buffer,1));
+ DLT_LOG(context_macro_test[3],DLT_LOG_INFO,DLT_STRING("16"),DLT_RAW(buffer,16));
+ DLT_LOG(context_macro_test[3],DLT_LOG_INFO,DLT_STRING("256"),DLT_RAW(buffer,256));
+ DLT_LOG(context_macro_test[3],DLT_LOG_INFO,DLT_STRING("1024"),DLT_RAW(buffer,1024)); + + /* wait 2 second before next test */
+ sleep(2); + DLT_LOG(context_info,DLT_LOG_INFO,DLT_STRING("Test4: (Macro IF) finished")); + + return 0; +} + +int test5m(void) +{ + char buffer[32];
+ int num;
+ + for(num=0;num<32;num++) + {
+ buffer[num] = num; + } + + /* Test 5: (Macro IF) Test high-level API */
+ printf("Test5m: (Macro IF) Test high-level API\n");
+ DLT_LOG(context_info,DLT_LOG_INFO,DLT_STRING("Test5: (Macro IF) Test high-level API")); + + DLT_LOG(context_macro_test[4],DLT_LOG_INFO,DLT_STRING("Next line: DLT_LOG_INT")); + DLT_LOG_INT(context_macro_test[4], DLT_LOG_INFO, -42); + + DLT_LOG(context_macro_test[4],DLT_LOG_INFO,DLT_STRING("Next line: DLT_LOG_UINT")); + DLT_LOG_UINT(context_macro_test[4], DLT_LOG_INFO, 42); + + DLT_LOG(context_macro_test[4],DLT_LOG_INFO,DLT_STRING("Next line: DLT_LOG_STRING")); + DLT_LOG_STRING(context_macro_test[4], DLT_LOG_INFO, "String output"); + + DLT_LOG(context_macro_test[4],DLT_LOG_INFO,DLT_STRING("Next line: DLT_LOG_RAW")); + DLT_LOG_RAW(context_macro_test[4],DLT_LOG_INFO, buffer,16); + + DLT_LOG(context_macro_test[4],DLT_LOG_INFO,DLT_STRING("Next line: DLT_LOG_STRING_INT")); + DLT_LOG_STRING_INT(context_macro_test[4], DLT_LOG_INFO, "String output: ", -42); + + DLT_LOG(context_macro_test[4],DLT_LOG_INFO,DLT_STRING("Next line: DLT_LOG_STRING_UINT")); + DLT_LOG_STRING_UINT(context_macro_test[4], DLT_LOG_INFO,"String output: ", 42); + + /* wait 2 second before next test */
+ sleep(2); + DLT_LOG(context_info,DLT_LOG_INFO,DLT_STRING("Test5: (Macro IF) finished")); + + return 0; +} + +int test6m(void) +{ + /* Test 6: (Macro IF) Test local printing */ + printf("Test6m: (Macro IF) Test local printing\n");
+ DLT_LOG_STRING(context_info, DLT_LOG_INFO, "Test 6: (Macro IF) Test local printing"); + + DLT_ENABLE_LOCAL_PRINT(); + DLT_LOG_STRING(context_macro_test[5], DLT_LOG_INFO, "Message (visible: locally printed)"); + + DLT_DISABLE_LOCAL_PRINT(); + DLT_LOG_STRING(context_macro_test[5], DLT_LOG_INFO, "Message (invisible: not locally printed)"); + + /* wait 2 second before next test */
+ sleep(2); + DLT_LOG(context_info,DLT_LOG_INFO,DLT_STRING("Test6: (Macro IF) finished")); +
+ return 0; +} + +int test7m(void) +{ + char buffer[32];
+ int num;
+ + for(num=0;num<32;num++) + {
+ buffer[num] = num; + } + + /* Show all log messages and traces */ + DLT_SET_APPLICATION_LL_TS_LIMIT(DLT_LOG_VERBOSE, DLT_TRACE_STATUS_ON); + + /* Test 7: (Macro IF) Test network trace */ + printf("Test7m: (Macro IF) Test network trace\n");
+ DLT_LOG_STRING(context_info, DLT_LOG_INFO, "Test 7: (Macro IF) Test network trace"); + + /* Dummy messages: 16 byte header, 32 byte payload */ + DLT_TRACE_NETWORK(context_macro_test[6], DLT_NW_TRACE_IPC, 16, buffer, 32, buffer); + DLT_TRACE_NETWORK(context_macro_test[6], DLT_NW_TRACE_CAN, 16, buffer, 32, buffer); + DLT_TRACE_NETWORK(context_macro_test[6], DLT_NW_TRACE_FLEXRAY, 16, buffer, 32, buffer); + DLT_TRACE_NETWORK(context_macro_test[6], DLT_NW_TRACE_MOST, 16, buffer, 32, buffer); + + /* wait 2 second before next test */
+ sleep(2); + DLT_LOG(context_info,DLT_LOG_INFO,DLT_STRING("Test7: (Macro IF) finished"));
+ + DLT_SET_APPLICATION_LL_TS_LIMIT(DLT_LOG_DEFAULT, DLT_TRACE_STATUS_DEFAULT); + sleep(2); + + return 0; +} + +int test1f(void) +{ + /* Test 1: (Function IF) Test all log levels */
+ printf("Test1f: (Function IF) Test all log levels\n"); + if (dlt_user_log_write_start(&context_info,&context_data,DLT_LOG_INFO))
+ {
+ dlt_user_log_write_string(&context_data,"Test1: (Function IF) Test all log levels");
+ dlt_user_log_write_finish(&context_data);
+ } + + if (dlt_user_log_write_start(&(context_function_test[0]),&context_data,DLT_LOG_FATAL))
+ {
+ dlt_user_log_write_string(&context_data,"fatal");
+ dlt_user_log_write_finish(&context_data);
+ }
+ if (dlt_user_log_write_start(&(context_function_test[0]),&context_data,DLT_LOG_ERROR))
+ {
+ dlt_user_log_write_string(&context_data,"error");
+ dlt_user_log_write_finish(&context_data);
+ } + if (dlt_user_log_write_start(&(context_function_test[0]),&context_data,DLT_LOG_WARN))
+ {
+ dlt_user_log_write_string(&context_data,"warn");
+ dlt_user_log_write_finish(&context_data);
+ } + if (dlt_user_log_write_start(&(context_function_test[0]),&context_data,DLT_LOG_INFO))
+ {
+ dlt_user_log_write_string(&context_data,"info");
+ dlt_user_log_write_finish(&context_data);
+ } + if (dlt_user_log_write_start(&(context_function_test[0]),&context_data,DLT_LOG_DEBUG))
+ {
+ dlt_user_log_write_string(&context_data,"debug");
+ dlt_user_log_write_finish(&context_data);
+ } + if (dlt_user_log_write_start(&(context_function_test[0]),&context_data,DLT_LOG_VERBOSE))
+ {
+ dlt_user_log_write_string(&context_data,"verbose");
+ dlt_user_log_write_finish(&context_data);
+ }
+ + /* wait 2 second before next test */
+ sleep(2); + if (dlt_user_log_write_start(&context_info,&context_data,DLT_LOG_INFO))
+ {
+ dlt_user_log_write_string(&context_data,"Test1: (Function IF) finished");
+ dlt_user_log_write_finish(&context_data);
+ } + + return 0; +} + +int test2f(void) +{ + char buffer[10]; + int num2; + + /* Test 2: (Function IF) Test all variable types (verbose) */
+ printf("Test2f: (Function IF) Test all variable types (verbose)\n"); + if (dlt_user_log_write_start(&context_info,&context_data,DLT_LOG_INFO))
+ {
+ dlt_user_log_write_string(&context_data,"Test2: (Function IF) Test all variable types (verbose)");
+ dlt_user_log_write_finish(&context_data);
+ }
+ + if (dlt_user_log_write_start(&(context_function_test[1]),&context_data,DLT_LOG_INFO))
+ {
+ dlt_user_log_write_string(&context_data,"bool"); + dlt_user_log_write_bool(&context_data,1);
+ dlt_user_log_write_finish(&context_data);
+ } +
+ if (dlt_user_log_write_start(&(context_function_test[1]),&context_data,DLT_LOG_INFO))
+ {
+ dlt_user_log_write_string(&context_data,"int"); + dlt_user_log_write_int(&context_data,INT32_MIN); /* (-2147483647-1) */
+ dlt_user_log_write_finish(&context_data);
+ } + if (dlt_user_log_write_start(&(context_function_test[1]),&context_data,DLT_LOG_INFO))
+ {
+ dlt_user_log_write_string(&context_data,"int8"); + dlt_user_log_write_int8(&context_data,INT8_MIN); /* (-128) */
+ dlt_user_log_write_finish(&context_data);
+ } + if (dlt_user_log_write_start(&(context_function_test[1]),&context_data,DLT_LOG_INFO))
+ {
+ dlt_user_log_write_string(&context_data,"int16"); + dlt_user_log_write_int16(&context_data,INT16_MIN); /* (-32767-1) */
+ dlt_user_log_write_finish(&context_data);
+ } + if (dlt_user_log_write_start(&(context_function_test[1]),&context_data,DLT_LOG_INFO))
+ {
+ dlt_user_log_write_string(&context_data,"int32"); + dlt_user_log_write_int32(&context_data,INT32_MIN); /* (-2147483647-1) */
+ dlt_user_log_write_finish(&context_data);
+ } + if (dlt_user_log_write_start(&(context_function_test[1]),&context_data,DLT_LOG_INFO))
+ {
+ dlt_user_log_write_string(&context_data,"int64"); + dlt_user_log_write_int64(&context_data,INT64_MIN); /* (-__INT64_C(9223372036854775807)-1) */
+ dlt_user_log_write_finish(&context_data);
+ } + + if (dlt_user_log_write_start(&(context_function_test[1]),&context_data,DLT_LOG_INFO))
+ {
+ dlt_user_log_write_string(&context_data,"uint"); + dlt_user_log_write_uint(&context_data,UINT32_MAX); /* (4294967295U) */
+ dlt_user_log_write_finish(&context_data);
+ } + if (dlt_user_log_write_start(&(context_function_test[1]),&context_data,DLT_LOG_INFO))
+ {
+ dlt_user_log_write_string(&context_data,"uint8"); + dlt_user_log_write_uint8(&context_data,UINT8_MAX); /* (255) */
+ dlt_user_log_write_finish(&context_data);
+ } + if (dlt_user_log_write_start(&(context_function_test[1]),&context_data,DLT_LOG_INFO))
+ {
+ dlt_user_log_write_string(&context_data,"uint16"); + dlt_user_log_write_uint16(&context_data,UINT16_MAX); /* (65535) */
+ dlt_user_log_write_finish(&context_data);
+ } + if (dlt_user_log_write_start(&(context_function_test[1]),&context_data,DLT_LOG_INFO))
+ {
+ dlt_user_log_write_string(&context_data,"uint32"); + dlt_user_log_write_uint32(&context_data,UINT32_MAX); /* (4294967295U) */
+ dlt_user_log_write_finish(&context_data);
+ } + if (dlt_user_log_write_start(&(context_function_test[1]),&context_data,DLT_LOG_INFO))
+ {
+ dlt_user_log_write_string(&context_data,"uint64"); + dlt_user_log_write_uint64(&context_data,UINT64_MAX); /* (__UINT64_C(18446744073709551615)) */
+ dlt_user_log_write_finish(&context_data);
+ } + + if (dlt_user_log_write_start(&(context_function_test[1]),&context_data,DLT_LOG_INFO))
+ {
+ dlt_user_log_write_string(&context_data,"float32"); + dlt_user_log_write_float32(&context_data,FLT_MIN); + dlt_user_log_write_float32(&context_data,FLT_MAX);
+ dlt_user_log_write_finish(&context_data);
+ } + if (dlt_user_log_write_start(&(context_function_test[1]),&context_data,DLT_LOG_INFO))
+ {
+ dlt_user_log_write_string(&context_data,"float64"); + dlt_user_log_write_float64(&context_data,DBL_MIN); + dlt_user_log_write_float64(&context_data,DBL_MAX);
+ dlt_user_log_write_finish(&context_data);
+ } + + for(num2=0;num2<10;num2++) + {
+ buffer[num2] = num2; + } + + if (dlt_user_log_write_start(&(context_function_test[1]),&context_data,DLT_LOG_INFO))
+ {
+ dlt_user_log_write_string(&context_data,"raw"); + dlt_user_log_write_raw(&context_data,buffer,10);
+ dlt_user_log_write_finish(&context_data);
+ } + + /* wait 2 second before next test */
+ sleep(2); + if (dlt_user_log_write_start(&context_info,&context_data,DLT_LOG_INFO))
+ {
+ dlt_user_log_write_string(&context_data,"Test2: (Function IF) finished");
+ dlt_user_log_write_finish(&context_data);
+ } + + return 0; +} + +int test3f(void) +{ + char buffer[10]; + int num2; + + /* Test 3: (Function IF) Test all variable types (non-verbose) */
+ printf("Test3f: (Function IF) Test all variable types (non-verbose)\n"); + if (dlt_user_log_write_start(&context_info,&context_data,DLT_LOG_INFO))
+ {
+ dlt_user_log_write_string(&context_data,"Test3: (Function IF) Test all variable types (non-verbose)");
+ dlt_user_log_write_finish(&context_data);
+ } + + dlt_nonverbose_mode();
+ + if (dlt_user_log_write_start_id(&(context_function_test[2]),&context_data,DLT_LOG_INFO,1))
+ {
+ dlt_user_log_write_string(&context_data,"bool"); + dlt_user_log_write_bool(&context_data,1);
+ dlt_user_log_write_finish(&context_data);
+ } +
+ if (dlt_user_log_write_start_id(&(context_function_test[2]),&context_data,DLT_LOG_INFO,2))
+ {
+ dlt_user_log_write_string(&context_data,"int"); + dlt_user_log_write_int(&context_data,INT32_MIN); /* (-2147483647-1) */
+ dlt_user_log_write_finish(&context_data);
+ } + if (dlt_user_log_write_start_id(&(context_function_test[2]),&context_data,DLT_LOG_INFO,3))
+ {
+ dlt_user_log_write_string(&context_data,"int8"); + dlt_user_log_write_int8(&context_data,INT8_MIN); /* (-128) */
+ dlt_user_log_write_finish(&context_data);
+ } + if (dlt_user_log_write_start_id(&(context_function_test[2]),&context_data,DLT_LOG_INFO,4))
+ {
+ dlt_user_log_write_string(&context_data,"int16"); + dlt_user_log_write_int16(&context_data,INT16_MIN); /* (-32767-1) */
+ dlt_user_log_write_finish(&context_data);
+ } + if (dlt_user_log_write_start_id(&(context_function_test[2]),&context_data,DLT_LOG_INFO,5))
+ {
+ dlt_user_log_write_string(&context_data,"int32"); + dlt_user_log_write_int32(&context_data,INT32_MIN); /* (-2147483647-1) */
+ dlt_user_log_write_finish(&context_data);
+ } + if (dlt_user_log_write_start_id(&(context_function_test[2]),&context_data,DLT_LOG_INFO,6))
+ {
+ dlt_user_log_write_string(&context_data,"int64"); + dlt_user_log_write_int64(&context_data,INT64_MIN); /* (-__INT64_C(9223372036854775807)-1) */
+ dlt_user_log_write_finish(&context_data);
+ } + + if (dlt_user_log_write_start_id(&(context_function_test[2]),&context_data,DLT_LOG_INFO,7))
+ {
+ dlt_user_log_write_string(&context_data,"uint"); + dlt_user_log_write_uint(&context_data,UINT32_MAX); /* (4294967295U) */
+ dlt_user_log_write_finish(&context_data);
+ } + if (dlt_user_log_write_start_id(&(context_function_test[2]),&context_data,DLT_LOG_INFO,8))
+ {
+ dlt_user_log_write_string(&context_data,"uint8"); + dlt_user_log_write_uint8(&context_data,UINT8_MAX); /* (255) */
+ dlt_user_log_write_finish(&context_data);
+ } + if (dlt_user_log_write_start_id(&(context_function_test[2]),&context_data,DLT_LOG_INFO,9))
+ {
+ dlt_user_log_write_string(&context_data,"uint16"); + dlt_user_log_write_uint16(&context_data,UINT16_MAX); /* (65535) */
+ dlt_user_log_write_finish(&context_data);
+ } + if (dlt_user_log_write_start_id(&(context_function_test[2]),&context_data,DLT_LOG_INFO,10))
+ {
+ dlt_user_log_write_string(&context_data,"uint32"); + dlt_user_log_write_uint32(&context_data,UINT32_MAX); /* (4294967295U) */
+ dlt_user_log_write_finish(&context_data);
+ } + if (dlt_user_log_write_start_id(&(context_function_test[2]),&context_data,DLT_LOG_INFO,11))
+ {
+ dlt_user_log_write_string(&context_data,"uint64"); + dlt_user_log_write_uint64(&context_data,UINT64_MAX); /* (__UINT64_C(18446744073709551615)) */
+ dlt_user_log_write_finish(&context_data);
+ } + + if (dlt_user_log_write_start_id(&(context_function_test[2]),&context_data,DLT_LOG_INFO,12))
+ {
+ dlt_user_log_write_string(&context_data,"float32"); + dlt_user_log_write_float32(&context_data,FLT_MIN); + dlt_user_log_write_float32(&context_data,FLT_MAX);
+ dlt_user_log_write_finish(&context_data);
+ } + if (dlt_user_log_write_start_id(&(context_function_test[2]),&context_data,DLT_LOG_INFO,13))
+ {
+ dlt_user_log_write_string(&context_data,"float64"); + dlt_user_log_write_float64(&context_data,DBL_MIN); + dlt_user_log_write_float64(&context_data,DBL_MAX);
+ dlt_user_log_write_finish(&context_data);
+ } +
+ for(num2=0;num2<10;num2++) + {
+ buffer[num2] = num2; + } + + if (dlt_user_log_write_start_id(&(context_function_test[2]),&context_data,DLT_LOG_INFO,14))
+ {
+ dlt_user_log_write_string(&context_data,"raw"); + dlt_user_log_write_raw(&context_data,buffer,10);
+ dlt_user_log_write_finish(&context_data);
+ } + + dlt_verbose_mode(); + + /* wait 2 second before next test */
+ sleep(2); + if (dlt_user_log_write_start(&context_info,&context_data,DLT_LOG_INFO))
+ {
+ dlt_user_log_write_string(&context_data,"Test3: (Function IF) finished");
+ dlt_user_log_write_finish(&context_data);
+ } + + return 0; +} + +int test4f(void) +{ + char buffer[1024];
+ int num; +
+ for(num=0;num<1024;num++) + {
+ buffer[num] = num; + } + + /* Test 4: (Function IF) Message size test */
+ printf("Test4f: (Function IF) Test different message sizes\n"); + if (dlt_user_log_write_start(&context_info,&context_data,DLT_LOG_INFO))
+ {
+ dlt_user_log_write_string(&context_data,"Test4: (Function IF) Test different message sizes");
+ dlt_user_log_write_finish(&context_data);
+ } + + if (dlt_user_log_write_start(&(context_function_test[3]),&context_data,DLT_LOG_INFO))
+ {
+ dlt_user_log_write_string(&context_data,"1"); + dlt_user_log_write_raw(&context_data,buffer,1);
+ dlt_user_log_write_finish(&context_data);
+ }
+ if (dlt_user_log_write_start(&(context_function_test[3]),&context_data,DLT_LOG_INFO))
+ {
+ dlt_user_log_write_string(&context_data,"16"); + dlt_user_log_write_raw(&context_data,buffer,16);
+ dlt_user_log_write_finish(&context_data);
+ } + if (dlt_user_log_write_start(&(context_function_test[3]),&context_data,DLT_LOG_INFO))
+ {
+ dlt_user_log_write_string(&context_data,"256"); + dlt_user_log_write_raw(&context_data,buffer,256);
+ dlt_user_log_write_finish(&context_data);
+ } + if (dlt_user_log_write_start(&(context_function_test[3]),&context_data,DLT_LOG_INFO))
+ {
+ dlt_user_log_write_string(&context_data,"1024"); + dlt_user_log_write_raw(&context_data,buffer,1024);
+ dlt_user_log_write_finish(&context_data);
+ } + + /* wait 2 second before next test */
+ sleep(2); + if (dlt_user_log_write_start(&context_info,&context_data,DLT_LOG_INFO))
+ {
+ dlt_user_log_write_string(&context_data,"Test4: (Function IF) finished");
+ dlt_user_log_write_finish(&context_data);
+ } + + return 0; +} + +int test5f(void) +{ + char buffer[32];
+ int num;
+ + for(num=0;num<32;num++) + {
+ buffer[num] = num; + } + + /* Test 5: (Function IF) Test high-level API */
+ printf("Test5f: (Function IF) Test high-level API\n"); + dlt_log_string(&context_info,DLT_LOG_INFO,"Test5: (Function IF) Test high-level API"); + + dlt_log_string(&(context_function_test[4]),DLT_LOG_INFO,"Next line: dlt_log_int()"); + dlt_log_int(&(context_function_test[4]),DLT_LOG_INFO, -42); + + dlt_log_string(&(context_function_test[4]),DLT_LOG_INFO,"Next line: dlt_log_uint()"); + dlt_log_uint(&(context_function_test[4]),DLT_LOG_INFO, 42); + + dlt_log_string(&(context_function_test[4]),DLT_LOG_INFO,"Next line: dlt_log_string()"); + dlt_log_string(&(context_function_test[4]),DLT_LOG_INFO, "String output"); + + dlt_log_string(&(context_function_test[4]),DLT_LOG_INFO,"Next line: dlt_log_raw()"); + dlt_log_raw(&(context_function_test[4]),DLT_LOG_INFO, buffer,16); + + dlt_log_string(&(context_function_test[4]),DLT_LOG_INFO,"Next line: dlt_log_string_int()"); + dlt_log_string_int(&(context_function_test[4]), DLT_LOG_INFO, "String output: ", -42); + + dlt_log_string(&(context_function_test[4]),DLT_LOG_INFO,"Next line: dlt_log_string_uint()"); + dlt_log_string_uint(&(context_function_test[4]), DLT_LOG_INFO,"String output: ", 42); + + /* wait 2 second before next test */
+ sleep(2); + dlt_log_string(&context_info,DLT_LOG_INFO,"Test5: (Function IF) finished"); + + return 0; +} + +int test6f(void) +{ + /* Test 6: (Function IF) Test local printing */ + printf("Test6f: (Function IF) Test local printing\n"); + if (dlt_user_log_write_start(&context_info,&context_data,DLT_LOG_INFO))
+ {
+ dlt_user_log_write_string(&context_data,"Test 6: (Function IF) Test local printing");
+ dlt_user_log_write_finish(&context_data);
+ } + + dlt_enable_local_print(); + if (dlt_user_log_write_start(&(context_function_test[5]),&context_data,DLT_LOG_INFO))
+ {
+ dlt_user_log_write_string(&context_data,"Message (visible: locally printed)");
+ dlt_user_log_write_finish(&context_data);
+ } + + dlt_disable_local_print(); + if (dlt_user_log_write_start(&(context_function_test[5]),&context_data,DLT_LOG_INFO))
+ {
+ dlt_user_log_write_string(&context_data,"Message (invisible: not locally printed)");
+ dlt_user_log_write_finish(&context_data);
+ } + + /* wait 2 second before next test */
+ sleep(2); + if (dlt_user_log_write_start(&context_info,&context_data,DLT_LOG_INFO))
+ {
+ dlt_user_log_write_string(&context_data,"Test6: (Function IF) finished");
+ dlt_user_log_write_finish(&context_data);
+ } + + return 0; +} + +int test7f(void) +{ + char buffer[32];
+ int num; +
+ for(num=0;num<32;num++) + {
+ buffer[num] = num; + } + + /* Show all log messages and traces */ + dlt_set_application_ll_ts_limit(DLT_LOG_VERBOSE, DLT_TRACE_STATUS_ON); + + /* Test 7: (Function IF) Test network trace */ + printf("Test7f: (Function IF) Test network trace\n"); + if (dlt_user_log_write_start(&context_info,&context_data,DLT_LOG_INFO))
+ {
+ dlt_user_log_write_string(&context_data,"Test 7: (Function IF) Test network trace");
+ dlt_user_log_write_finish(&context_data);
+ } + + /* Dummy message: 16 byte header, 32 byte payload */ + dlt_user_trace_network(&(context_function_test[6]), DLT_NW_TRACE_IPC, 16, buffer, 32, buffer); + dlt_user_trace_network(&(context_function_test[6]), DLT_NW_TRACE_CAN, 16, buffer, 32, buffer); + dlt_user_trace_network(&(context_function_test[6]), DLT_NW_TRACE_FLEXRAY, 16, buffer, 32, buffer); + dlt_user_trace_network(&(context_function_test[6]), DLT_NW_TRACE_MOST, 16, buffer, 32, buffer); + + /* wait 2 second before next test */
+ sleep(2); + if (dlt_user_log_write_start(&context_info,&context_data,DLT_LOG_INFO))
+ {
+ dlt_user_log_write_string(&context_data,"Test7: (Function IF) finished");
+ dlt_user_log_write_finish(&context_data);
+ } + + dlt_set_application_ll_ts_limit(DLT_LOG_DEFAULT, DLT_TRACE_STATUS_DEFAULT); + sleep(2);
+ + return 0; +} + +int test_injection_macro_callback(uint32_t service_id, void *data, uint32_t length)
+{
+ char text[1024]; + + memset(text,0,1024);
+
+ snprintf(text,1024,"Injection received (macro IF). ID: 0x%.4x, Length: %d",service_id,length); + printf("%s \n", text); + + memset(text,0,1024); +
+ if (length>0)
+ {
+ dlt_print_mixed_string(text,1024,data,length,0);
+ printf("%s \n", text);
+ }
+
+ return 0;
+} + +int test_injection_function_callback(uint32_t service_id, void *data, uint32_t length) +{ + char text[1024]; + + memset(text,0,1024);
+
+ snprintf(text,1024,"Injection received (function IF). ID: 0x%.4x, Length: %d",service_id,length); + printf("%s \n", text); + + memset(text,0,1024); +
+ if (length>0)
+ {
+ dlt_print_mixed_string(text,1024,data,length,0);
+ printf("%s \n", text);
+ } + + return 0; +} + + diff --git a/src/winclientlib/stdafx.cpp b/src/winclientlib/stdafx.cpp new file mode 100755 index 0000000..62e53b6 --- /dev/null +++ b/src/winclientlib/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes
+// WwinClientLib.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
+
+// TODO: reference any additional headers you need in STDAFX.H
+// and not in this file
diff --git a/src/winclientlib/stdafx.h b/src/winclientlib/stdafx.h new file mode 100755 index 0000000..a13982c --- /dev/null +++ b/src/winclientlib/stdafx.h @@ -0,0 +1,32 @@ +// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently, but
+// are changed infrequently
+//
+
+#pragma once
+
+// Modify the following defines if you have to target a platform prior to the ones specified below.
+// Refer to MSDN for the latest info on corresponding values for different platforms.
+#ifndef WINVER // Allow use of features specific to Windows XP or later.
+#define WINVER 0x0501 // Change this to the appropriate value to target other versions of Windows.
+#endif
+
+#ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later.
+#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows.
+#endif
+
+#ifndef _WIN32_WINDOWS // Allow use of features specific to Windows 98 or later.
+#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later.
+#endif
+
+#ifndef _WIN32_IE // Allow use of features specific to IE 6.0 or later.
+#define _WIN32_IE 0x0600 // Change this to the appropriate value to target other versions of IE.
+#endif
+
+#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
+// Windows Header Files:
+#include <windows.h>
+
+
+
+// TODO: reference additional headers your program requires here
diff --git a/src/winclientlib/winclientlib.cpp b/src/winclientlib/winclientlib.cpp new file mode 100755 index 0000000..7d67f14 --- /dev/null +++ b/src/winclientlib/winclientlib.cpp @@ -0,0 +1,276 @@ +/******************************************************************************* +** ** +** SRC-MODULE: winclientLib.cpp ** +** ** +** TARGET : Windows ** +** ** +** PROJECT : DLT ** +** ** +** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** +** Markus Klein ** +** ** +** PURPOSE : ** +** ** +** REMARKS : ** +** ** +** PLATFORM DEPENDANT [yes/no]: yes ** +** ** +** TO BE CHANGED BY USER [yes/no]: no ** +** ** +*******************************************************************************/ + +/******************************************************************************* +** Author Identity ** +******************************************************************************** +** ** +** Initials Name Company ** +** -------- ------------------------- ---------------------------------- ** +** aw Alexander Wenzel BMW ** +** mk Markus Klein Fraunhofer ESK ** +*******************************************************************************/ + +/******************************************************************************* +** Revision Control History ** +*******************************************************************************/ + +/* + * $LastChangedRevision$ + * $LastChangedDate$ + * $LastChangedBy$ + */ + +// Need to link with Ws2_32.lib, Mswsock.lib, and Advapi32.lib + +// Disable C4995 and C4996 Warnings +#pragma warning(disable : 4995) +#pragma warning(disable : 4996) + +#include "stdafx.h" + +#include <winsock2.h> +#include <ws2tcpip.h> +#include <stdlib.h> +#include <stdio.h> +#include <windows.h> +#include <strsafe.h> +#include <io.h> + +#include <string> +#include <iostream> + +#include "winclientlib.h" +#include "dlt_client.h" + +// Function prototypes +DWORD WINAPI MyThreadFunction( LPVOID lpParam ); +void ErrorHandler(LPTSTR lpszFunction); + +// Variables +static DWORD dwThreadId; +static HANDLE hThread; +static HANDLE hEvent; + +static DltClient windltclient; + +#ifdef _MANAGED +#pragma managed(push, off) +#endif + +BOOL APIENTRY DllMain( HMODULE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + { + break; + } + } + return TRUE; +} + +#ifdef _MANAGED +#pragma managed(pop) +#endif + +using namespace std; + +/* +Some helper functions +*/ + +DWORD WINAPI MyThreadFunction( LPVOID lpParam ) +{ + // Enter Main Loop + dlt_client_main_loop(&windltclient, NULL, 0); + + // Send event about thread termination + SetEvent(hEvent); + + ExitThread(0); +} + +void ErrorHandler(LPTSTR lpszFunction) +{ + // Retrieve the system error message for the last-error code. + LPVOID lpMsgBuf; + LPVOID lpDisplayBuf; + + DWORD dw = GetLastError(); + + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + dw, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR) &lpMsgBuf, + 0, NULL ); + + // Display the error message. + lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, + (lstrlen((LPCTSTR) lpMsgBuf) + lstrlen((LPCTSTR) lpszFunction) + 40) * sizeof(TCHAR)); + StringCchPrintf((LPTSTR)lpDisplayBuf, + LocalSize(lpDisplayBuf) / sizeof(TCHAR), + TEXT("%s failed with error %d: %s"), + lpszFunction, dw, lpMsgBuf); + + MessageBox(NULL, (LPCTSTR) lpDisplayBuf, TEXT("Error"), MB_OK); + + // Free error-handling buffer allocations. + LocalFree(lpMsgBuf); + LocalFree(lpDisplayBuf); +} + +/*** +The interface functions +****/ + +WWINCLIENTLIB_API void Dlt_RegisterMessageCallback(int (*registerd_callback) (DltMessage *message, void *data)) +{ + dlt_client_register_message_callback(registerd_callback); +} + +WWINCLIENTLIB_API int Dlt_StartClient(char* server_address) +{ + WSADATA wsaData; + int iResult; + + if ((server_address==0) || (server_address[0]=='\0')) + { + return 0; + } + + // Create event, used for thread termination + hEvent = CreateEvent(NULL,FALSE,FALSE,(LPCWSTR)"Test"); + + // Initialize Winsock + iResult = WSAStartup(MAKEWORD(2,2), &wsaData); + if (iResult) + { + printf("winclientlib: WSAStartup failed: %d\n", iResult); + return -1; + } + + /* Initialize DLT Client */ + if (dlt_client_init(&windltclient, 0)==-1) + { + ErrorHandler(TEXT("dlt_client_init()")); + + Dlt_ExitClient(); + + return -1; + } + + /* Setup parameters of DltClient */ + windltclient.sock = -1; + windltclient.serial_mode = 0; /* TCP connection: + In Windows (with Visual C++), + only TCP connection is allowed! */ + windltclient.servIP = server_address; /* IP address */ + + + /* Connect to TCP socket */ + if (dlt_client_connect(&windltclient, 0)==-1) + { + ErrorHandler(TEXT("dlt_client_connect()")); + + Dlt_ExitClient(); + + return -1; + } + + // Create the thread to begin execution on its own. + hThread = CreateThread( + NULL, // default security attributes + 0, // use default stack size + MyThreadFunction, // thread function name + 0,//(LPVOID)address, // argument to thread function + 0, // use default creation flags + &dwThreadId); // returns the thread identifier + + // Check the return value for success. + // If CreateThread fails, terminate execution. + // This will automatically clean up threads and memory. + if (hThread==0) + { + ErrorHandler(TEXT("CreateThread()")); + + // Cleanup WSA + WSACleanup(); + + return -1; + } + + return 0; +} + +WWINCLIENTLIB_API int Dlt_InjectCall( char appID[4], char contID[4], uint32_t serviceID, uint8_t *buf, uint32_t buf_len ) +{ + return dlt_client_send_inject_msg(&windltclient, appID, contID, serviceID, buf, buf_len); +} + +WWINCLIENTLIB_API int Dlt_ExitClient() +{ + printf("winclientlib: exiting ...\n"); + + // Terminate thread and close handles + if (windltclient.sock!=-1) + { + if (windltclient.serial_mode==1) + { + close(windltclient.sock); + } + else + { + closesocket(windltclient.sock); + } + windltclient.sock = -1; + + WaitForSingleObject(hEvent,INFINITE); + } + + CloseHandle(hEvent); + CloseHandle(hThread); + + // Dlt Client Cleanup + if (dlt_client_cleanup(&windltclient,0)==-1) + { + printf("winclientlib: closing error.\n"); + } + else + { + printf("winclientlib: closed.\n"); + } + + // Cleanup WSA + WSACleanup(); + + exit(0); +} diff --git a/src/winclientlib/winclientlib.h b/src/winclientlib/winclientlib.h new file mode 100755 index 0000000..15c69fb --- /dev/null +++ b/src/winclientlib/winclientlib.h @@ -0,0 +1,59 @@ +/******************************************************************************* +** ** +** SRC-MODULE: winClientLib.h ** +** ** +** TARGET : Windows ** +** ** +** PROJECT : DLT ** +** ** +** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** +** Markus Klein ** +** ** +** PURPOSE : ** +** ** +** REMARKS : ** +** ** +** PLATFORM DEPENDANT [yes/no]: yes ** +** ** +** TO BE CHANGED BY USER [yes/no]: no ** +** ** +*******************************************************************************/ + +/******************************************************************************* +** Author Identity ** +******************************************************************************** +** ** +** Initials Name Company ** +** -------- ------------------------- ---------------------------------- ** +** aw Alexander Wenzel BMW ** +** mk Markus Klein Fraunhofer ESK ** +*******************************************************************************/ + +/******************************************************************************* +** Revision Control History ** +*******************************************************************************/ + +/* + * $LastChangedRevision$ + * $LastChangedDate$ + * $LastChangedBy$ + */ + +#include "dlt_common.h" // for DltMessage + +// The following ifdef block is the standard way of creating macros which make exporting +// from a DLL simpler. All files within this DLL are compiled with the WWINCLIENTLIB_EXPORTS +// symbol defined on the command line. this symbol should not be defined on any project +// that uses this DLL. This way any other project whose source files include this file see +// WWINCLIENTLIB_API functions as being imported from a DLL, whereas this DLL sees symbols +// defined with this macro as being exported. +#ifdef WINCLIENTLIB_EXPORTS +#define WWINCLIENTLIB_API __declspec(dllexport) +#else +#define WWINCLIENTLIB_API __declspec(dllimport) +#endif + +WWINCLIENTLIB_API int Dlt_StartClient(char* server_address); +WWINCLIENTLIB_API int Dlt_ExitClient(); +WWINCLIENTLIB_API int Dlt_InjectCall( char appID[4], char contID[4], uint32_t serviceID, uint8_t *buf, uint32_t buf_len ); +WWINCLIENTLIB_API void Dlt_RegisterMessageCallback(int (*registerd_callback) (DltMessage *message, void *data)); diff --git a/src/winclientlib/winclientlib.sln b/src/winclientlib/winclientlib.sln new file mode 100755 index 0000000..c5343d9 --- /dev/null +++ b/src/winclientlib/winclientlib.sln @@ -0,0 +1,20 @@ +
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual C++ Express 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "winclientlib", "winclientlib.vcproj", "{F3674DAE-F85A-428C-85FE-3529671DF6ED}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {F3674DAE-F85A-428C-85FE-3529671DF6ED}.Debug|Win32.ActiveCfg = Debug|Win32
+ {F3674DAE-F85A-428C-85FE-3529671DF6ED}.Debug|Win32.Build.0 = Debug|Win32
+ {F3674DAE-F85A-428C-85FE-3529671DF6ED}.Release|Win32.ActiveCfg = Release|Win32
+ {F3674DAE-F85A-428C-85FE-3529671DF6ED}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/src/winclientlib/winclientlib.vcproj b/src/winclientlib/winclientlib.vcproj new file mode 100755 index 0000000..6729bb2 --- /dev/null +++ b/src/winclientlib/winclientlib.vcproj @@ -0,0 +1,260 @@ +<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9,00"
+ Name="winclientlib"
+ ProjectGUID="{F3674DAE-F85A-428C-85FE-3529671DF6ED}"
+ RootNamespace="winclientlib"
+ TargetFrameworkVersion="196613"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\include;..\..\include\dlt;..\.."
+ PreprocessorDefinitions="WINCLIENTLIB_EXPORTS;_CRT_SECURE_NO_WARNINGS;WIN32;__WIN32__;_DEBUG"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="mswsock.lib Ws2_32.lib"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ EntryPointSymbol="DllMain"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ AdditionalIncludeDirectories="..\include;..\..\include\dlt;..\.."
+ PreprocessorDefinitions="WINCLIENTLIB_EXPORTS;_CRT_SECURE_NO_WARNINGS;WIN32;__WIN32__;NDEBUG"
+ RuntimeLibrary="2"
+ EnableFunctionLevelLinking="true"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="mswsock.lib Ws2_32.lib"
+ GenerateDebugInformation="true"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Quelldateien"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\lib\dlt_client.c"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ CompileAs="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ CompileAs="2"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\lib\dlt_common.c"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ CompileAs="2"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ CompileAs="2"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\winclientlib.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Headerdateien"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath="..\..\include\dlt\dlt_client.h"
+ >
+ </File>
+ <File
+ RelativePath="..\include\dlt_common.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\include\dlt\dlt_protocol.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\include\dlt\msvc_stdint.h"
+ >
+ </File>
+ <File
+ RelativePath=".\stdafx.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\stdafx.h"
+ >
+ </File>
+ <File
+ RelativePath=".\winclientlib.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Ressourcendateien"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
|