diff options
84 files changed, 26682 insertions, 0 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100755 index 0000000..2f966fd --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,265 @@ +#######
+# 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@
+########
+
+CMAKE_MINIMUM_REQUIRED( VERSION 2.6 )
+MARK_AS_ADVANCED(CMAKE_BACKWARDS_COMPATIBILITY)
+
+SET( CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS TRUE )
+
+PROJECT( automotive-dlt )
+
+# set version parameters
+SET( ${PROJECT_NAME}_MAJOR_VERSION 2 )
+SET( ${PROJECT_NAME}_MINOR_VERSION 2 )
+SET( ${PROJECT_NAME}_PATCH_LEVEL 0 )
+set(GENIVI_PROJECT_VERSION ${${PROJECT_NAME}_MAJOR_VERSION}.${${PROJECT_NAME}_MINOR_VERSION}.${${PROJECT_NAME}_PATCH_LEVEL})
+SET( ${PROJECT_NAME}_VERSION_STATE )
+SET( ${PROJECT_NAME}_REVISION 1666 )
+
+# Write version information into include file
+SET( PRINT_MAJOR_VERSION ${${PROJECT_NAME}_MAJOR_VERSION})
+SET( PRINT_MINOR_VERSION ${${PROJECT_NAME}_MINOR_VERSION})
+SET( PRINT_PATCH_LEVEL ${${PROJECT_NAME}_PATCH_LEVEL})
+SET( PRINT_VERSION ${GENIVI_PROJECT_VERSION})
+SET( PRINT_VERSION_STATE ${${PROJECT_NAME}_VERSION_STATE})
+SET( PRINT_VERSION_REVISION ${${PROJECT_NAME}_REVISION})
+
+# Print version information
+MESSAGE("VERSION ${PRINT_VERSION}")
+MESSAGE("VERSION_STATE ${PRINT_VERSION_STATE}")
+MESSAGE("REVISION ${PRINT_VERSION_REVISION}")
+
+##################### RPM CONFIG ########################
+
+set( GENIVI_RPM_RELEASE "1${SVN_REVISION}")
+SET( LICENSE "LGPL v2.1 with special exception" )
+set(SPEC_DIR "package")
+
+#########################################################
+set(GENIVI_BUILDSYSTEM_AVAILABLE $ENV{GENIVI_BUILDSYSTEM})
+IF(GENIVI_BUILDSYSTEM_AVAILABLE)
+include($ENV{GENIVI_BUILDSYSTEM}/cmake_extensions/GeniviCMakeExtensions.cmake)
+ENDIF(GENIVI_BUILDSYSTEM_AVAILABLE)
+
+SET( prefix ${CMAKE_INSTALL_PREFIX})
+SET( libdir "\${exec_prefix}/lib" )
+SET( includedir "\${exec_prefix}/include" )
+
+SET( DLTBINDIR ${CMAKE_INSTALL_PREFIX}/bin )
+SET( DLTLIBDIR ${CMAKE_INSTALL_PREFIX}/lib )
+SET( DLTLIBSTATIC ${CMAKE_INSTALL_PREFIX}/lib )
+SET( DLTINCLUDEDIR ${CMAKE_INSTALL_PREFIX}/include )
+SET( DLTDOCDIR ${CMAKE_INSTALL_PREFIX}/doc )
+
+IF(NOT CMAKE_BUILD_TYPE)
+ SET(CMAKE_BUILD_TYPE RelWithDebInfo)
+ENDIF(NOT CMAKE_BUILD_TYPE)
+
+FIND_PACKAGE(Doxygen)
+FIND_PACKAGE(Threads REQUIRED)
+
+INCLUDE_DIRECTORIES(
+${CMAKE_SOURCE_DIR}/
+${CMAKE_SOURCE_DIR}/include/dlt
+${CMAKE_SOURCE_DIR}/src/shared/
+${CMAKE_SOURCE_DIR}/src/lib/
+${CMAKE_SOURCE_DIR}/src/daemon/ )
+
+ADD_DEFINITIONS( "-Wall" )
+
+INCLUDE(TestBigEndian)
+
+TEST_BIG_ENDIAN( DLT_BIGENDIAN )
+
+IF ( DLT_BIGENDIAN )
+ ADD_DEFINITIONS( -DBYTE_ORDER=BIG_ENDIAN )
+ELSE ( DLT_BIGENDIAN )
+ ADD_DEFINITIONS( -DBYTE_ORDER=LITTLE_ENDIAN )
+ENDIF ( DLT_BIGENDIAN )
+
+INCLUDE(CheckIncludeFiles)
+
+CHECK_INCLUDE_FILES( arpa/inet.h HAVE_ARPAINET_H)
+CHECK_INCLUDE_FILES( fcntl.h HAVE_FCNTL_H)
+CHECK_INCLUDE_FILES( float.h HAVE_FLOAT_H)
+CHECK_INCLUDE_FILES( limits.h HAVE_LIMITS_H)
+CHECK_INCLUDE_FILES( netdb.h HAVE_NETDB_H)
+CHECK_INCLUDE_FILES( netinet/in.h HAVE_NETINETIN_H)
+CHECK_INCLUDE_FILES( stddef.h HAVE_STDDEF_H)
+CHECK_INCLUDE_FILES( stdint.h HAVE_STDINT_H)
+CHECK_INCLUDE_FILES( stdlib.h HAVE_STDLIB_H)
+CHECK_INCLUDE_FILES( string.h HAVE_STRING_H)
+CHECK_INCLUDE_FILES( strings.h HAVE_STRINGS_H)
+CHECK_INCLUDE_FILES( sys/ioctl.h HAVE_SYSIOCTL_H)
+CHECK_INCLUDE_FILES( sys/socket.h HAVE_SYSSOCKET_H)
+CHECK_INCLUDE_FILES( sys/time.h HAVE_SYSTIME_H)
+CHECK_INCLUDE_FILES( unistd.h HAVE_UNISTD_H)
+CHECK_INCLUDE_FILES( sys/ipc.h HAVE_SYSIPC_H)
+CHECK_INCLUDE_FILES( netdb.h HAVE_NETDB_H)
+CHECK_INCLUDE_FILES( ctype.h HAVE_CTYPE_H)
+CHECK_INCLUDE_FILES( signal.h HAVE_SIGNAL_H)
+CHECK_INCLUDE_FILES( syslog.h HAVE_SYSLOG_H)
+CHECK_INCLUDE_FILES( sys/stat.h HAVE_SYSSTAT_H)
+CHECK_INCLUDE_FILES( linux/stat.h HAVE_LINUXSTAT_H)
+CHECK_INCLUDE_FILES( sys/uio.h HAVE_SYSUIO_H)
+CHECK_INCLUDE_FILES( termios.h HAVE_TERMIOS_H)
+CHECK_INCLUDE_FILES( unistd.h HAVE_UNISTD_H)
+
+INCLUDE(CheckFunctionExists)
+
+CHECK_FUNCTION_EXISTS( bzero HAVE_FUNC_BZERO)
+CHECK_FUNCTION_EXISTS( clock_gettime HAVE_FUNC_CLOCKGETTIME)
+CHECK_FUNCTION_EXISTS( floor HAVE_FUNC_FLOOR)
+CHECK_FUNCTION_EXISTS( fork HAVE_FUNC_FORK)
+CHECK_FUNCTION_EXISTS( gethostbyname HAVE_FUNC_GETHOSTBYNAME)
+CHECK_FUNCTION_EXISTS( gettimeofday HAVE_FUNC_GETTIMEBYDAY)
+CHECK_FUNCTION_EXISTS( inet_ntoa HAVE_FUNC_INETNTOA)
+CHECK_FUNCTION_EXISTS( malloc HAVE_FUNC_MALLOC)
+CHECK_FUNCTION_EXISTS( memmove HAVE_FUNC_MEMMOVE)
+CHECK_FUNCTION_EXISTS( memset HAVE_FUNC_MEMSET)
+CHECK_FUNCTION_EXISTS( mkfifo HAVE_FUNC_MKFIFO)
+CHECK_FUNCTION_EXISTS( select HAVE_FUNC_SELECT)
+CHECK_FUNCTION_EXISTS( socket HAVE_FUNC_SOCKET)
+CHECK_FUNCTION_EXISTS( strchr HAVE_FUNC_STRCHR)
+CHECK_FUNCTION_EXISTS( strerror HAVE_FUNC_STRERROR)
+CHECK_FUNCTION_EXISTS( strstr HAVE_FUNC_STRSTR)
+CHECK_FUNCTION_EXISTS( strtol HAVE_FUNC_STRTOL)
+
+CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/config.h.cmake ${CMAKE_SOURCE_DIR}/config.h @ONLY)
+CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/svnversion.h.cmake ${CMAKE_SOURCE_DIR}/svnversion.h @ONLY)
+CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/version.h.cmake ${CMAKE_SOURCE_DIR}/version.h @ONLY)
+CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/doxygen.cfg.cmake ${CMAKE_SOURCE_DIR}/doxygen.cfg @ONLY)
+CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/automotive-dlt.pc.cmake ${CMAKE_SOURCE_DIR}/automotive-dlt.pc @ONLY)
+#CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/package/automotive-dlt.spec.cmake ${CMAKE_SOURCE_DIR}/package/automotive-dlt.spec ESCAPE_QUOTES)
+
+OPTION(BUILD_SHARED_LIBS "Set to OFF to build static libraries" ON )
+OPTION(ENABLE_BUILD_DOC "Set to ON to build Documentation" OFF)
+
+MESSAGE( STATUS )
+MESSAGE( STATUS "-------------------------------------------------------------------------------" )
+MESSAGE( STATUS "BUILD_SHARED_LIBS = ${BUILD_SHARED_LIBS}" )
+MESSAGE( STATUS "CMAKE_INSTALL_PREFIX = ${CMAKE_INSTALL_PREFIX}" )
+MESSAGE( STATUS "CMAKE_BUILD_TYPE = ${CMAKE_BUILD_TYPE}" )
+MESSAGE( STATUS "ENABLE_BUILD_DOC = ${ENABLE_BUILD_DOC}" )
+MESSAGE( STATUS "Change a value with: cmake -D<Variable>=<Value>" )
+MESSAGE( STATUS "-------------------------------------------------------------------------------" )
+MESSAGE( STATUS )
+
+SET( BUILD_SHARED_LIBS "${BUILD_SHARED_LIBS}" CACHE BOOL "Set to OFF to build static libraries" FORCE )
+SET( CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}" CACHE PATH "Where to install ${PROJECT_NAME}" FORCE )
+SET( CMAKE_BUILD_TYPE "${CMAKE_BUILD_TYPE}" CACHE STRING
+"Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel." FORCE )
+#SET( ENABLE_BUILD_DOC "${ENABLE_BUILD_DOC}" CACHE BOOL "Set to ON to build Documentation" FORCE )
+
+ADD_SUBDIRECTORY( src )
+ADD_SUBDIRECTORY( include )
+ADD_SUBDIRECTORY( testscripts )
+
+IF (ENABLE_BUILD_DOC)
+ ADD_SUBDIRECTORY( doc )
+
+ ADD_CUSTOM_COMMAND(
+ OUTPUT ${CMAKE_SOURCE_DIR}/doxygen-execute
+ DEPENDS ${CMAKE_SOURCE_DIR}/doxygen.cfg
+ COMMAND doxygen
+ ARGS ${CMAKE_SOURCE_DIR}/doxygen.cfg
+ )
+
+ ADD_CUSTOM_TARGET(doxygen-doc ALL DEPENDS ${CMAKE_SOURCE_DIR}/doxygen-execute)
+
+ SET( DOC_COMPONENT doc)
+ENDIF(ENABLE_BUILD_DOC)
+
+INSTALL(FILES automotive-dlt.pc
+ DESTINATION lib/pkgconfig
+ COMPONENT devel)
+INSTALL(FILES LICENSE.txt
+ DESTINATION doc/dlt2
+ COMPONENT base)
+
+message(STATUS "python ${CMAKE_CURRENT_SOURCE_DIR}/transform_spec_file.py ${CMAKE_CURRENT_SOURCE_DIR}/${CMAKE_PROJECT_NAME}.spec.cheetah ${CMAKE_CURRENT_SOURCE_DIR}/${CMAKE_PROJECT_NAME}.spec BUILD_DOC=${ENABLE_BUILD_DOC}")
+
+add_custom_command(OUTPUT "${CMAKE_SOURCE_DIR}/${CMAKE_PROJECT_NAME}.spec"
+ COMMAND "python" "${CMAKE_CURRENT_SOURCE_DIR}/transform_spec_file.py" "${CMAKE_CURRENT_SOURCE_DIR}/${CMAKE_PROJECT_NAME}.spec.cheetah" "${CMAKE_CURRENT_SOURCE_DIR}/${CMAKE_PROJECT_NAME}.spec" "BUILD_DOC=${ENABLE_BUILD_DOC}"
+ DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/${CMAKE_PROJECT_NAME}.spec.cheetah")
+
+add_custom_target(specfile
+ DEPENDS "${CMAKE_PROJECT_NAME}.spec")
+
+CONFIGURE_FILE(
+ "${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in"
+
+ "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
+ IMMEDIATE @ONLY)
+
+#ADD_CUSTOM_TARGET(uninstall
+# "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")
+
+EXPORT_LIBRARY_DEPENDENCIES( "${PROJECT_NAME}LibDeps.cmake" )
+
+#######################
+# CPack configuration #
+#######################
+SET(CPACK_COMPONENTS_ALL base devel ${DOC_COMPONENT} )
+
+SET(CPACK_COMPONENT_BASE_DISPLAY_NAME "Basics" )
+SET(CPACK_COMPONENT_DEVEL_DISPLAY_NAME "Development files" )
+SET(CPACK_COMPONENT_DOC_DISPLAY_NAME "Documentation" )
+
+SET(CPACK_COMPONENT_BASE_DESCRIPTION
+"This component provides a standardised log and trace interface, based on the
+standardised protocol specified in the AUTOSAR standard 4.0 DLT.
+This component can be used by GENIVI components and other applications as
+logging facility providing
+- the DLT shared library
+- the DLT daemon, including startup scripts
+- the DLT daemon adaptors
+- the DLT client console utilities
+- the DLT test applications ")
+SET(CPACK_COMPONENT_DEVEL_DESCRIPTION
+ "This component provides the development libraries and includes for automotive-dlt.")
+SET(CPACK_COMPONENT_DOC_DESCRIPTION
+ "This component provides the documentation for automotive-dlt.")
+
+SET(CPACK_COMPONENT_DEVEL_DEPENDS base)
+#SET(CPACK_COMPONENT_DOC_DEPENDS base)
+
+SET(CPACK_COMPONENT_BASE_REQUIRED)
+
+
+
+
diff --git a/LGPL.txt b/LGPL.txt new file mode 100755 index 0000000..1d00fdb --- /dev/null +++ b/LGPL.txt @@ -0,0 +1,503 @@ + GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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 for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100755 index 0000000..765e1fd --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,33 @@ + # @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@ diff --git a/LIMITATIONS b/LIMITATIONS new file mode 100755 index 0000000..831374e --- /dev/null +++ b/LIMITATIONS @@ -0,0 +1,11 @@ +KNOWN LIMITATIONS: +(26.07.2010) + +Client: +- Only one daemon connection is supported + +Daemon: +- Missing features, see TODO + +User: +- Only one application, but multiple contexts, are possible in each user application diff --git a/README.txt b/README.txt new file mode 100755 index 0000000..f1e7ee9 --- /dev/null +++ b/README.txt @@ -0,0 +1,4 @@ +License +------- +See file: LICENSE.txt +The full LGPL license: LGPL.txt diff --git a/ReleaseNotes.txt b/ReleaseNotes.txt new file mode 100755 index 0000000..7acb10c --- /dev/null +++ b/ReleaseNotes.txt @@ -0,0 +1,302 @@ +DLT - Automotive Diagnostic Log and Trace
+
+Version: 2.2.0
+
+
+Introduction
+------------
+
+The DLT daemon is the central component in GENIVI, which gathers all logs and traces from the DLT user applications. The logs and traces are stored optionally directly in a file in the ECU. The DLT daemon forwards all logs and traces to a connected DLT client.
+The DLT client can send control messages to the daemon, e.g. to set individual log levels of applications and contexts or get the list of applications and contexts registered in the DLT daemon.
+
+
+License
+-------
+see file: License.txt
+
+Contact
+-------
+Alexander Wenzel
+BMW Group
+Alexander.AW.Wenzel@bmw.de
+
+
+Changes in this release
+-----------------------
+
+2.2.0:
+
+Improvements
+
+ * Moved build process completely to cmake
+ * Added commandline parameter -u to set ring buffer size
+
+Bugfixes
+
+ * Reduced cpu consumption needed by applications using DLT library
+ * Increased default ringbuffer size to 10024 bytes
+ * Changed delay in receiver routine to 100ms
+
+
+2.1.0:
+
+Improvements
+
+ * DLT Viewer (QT)
+ * New dlt viewer (QT-based) implementated
+ * Moved to seperate project, see extra Release Notes for DLT Viewer (QT)
+
+ * DLT Viewer (WX) - Deprecated
+ * Old dlt viewer (WX) is removed now from package generation
+ * Moved to seperate project
+ * Removed filtering of messages during writing to a file
+
+ * DLT library:
+ * Functions dlt_file_read_raw() and dlt_file_read_header_raw() added
+ * Added support for raw messages in nonverbose mode
+ * Injection tables are now dynamically allocated
+ * Contexts are now dynamically allocated
+ * Added seperate file for platform float types (dlt_float_types.h)
+ and used this types.
+ Attention: This file must be adapted to each target platform.
+ * Removed signal handlers from dlt_user.c; SIGPIPE signal is ignored; atexit() handler still exists
+ * Function dlt_forward_msg() added
+
+ * DLT daemon:
+ * Small optimization in get_log_info() for one searched application with one searched context,
+ which is existing in the context table of the dlt daemon
+ * Optional syncing to serial header added
+ * Support for keep-alive messages, realized as seperate thread
+
+ * General:
+ * Combined dlt-test-user-multi and dlt-test-many to dlt-test-stress
+ * Extended dlt-test-client
+ * Added stress test3 to dlt-test-stress
+ * Added help to dlt-test-stress, printed if no test was selected
+ * Added dlt-test-internal
+ * Removed plugin support from dlt_receive and dlt_convert
+ * Extended documentation
+
+Bugfixes:
+ * dlt viewer (wx): Fixed minor bug, it's possible now to compile the dlt viewer (wx) again under mingw under Windows
+ * DLT test programs: Fixed minor bug in dlt-test-user, test3f: Wrong counter was used
+ * Removed DLT_LOG calls in injection functions due to problems (application hangs)
+
+
+2.0.5:
+
+Improvements
+
+ * DLT viewer:
+ * The default log level is now shown, if already known
+ * Renamed Filter->New.. to Filter->Delete all filter
+ * Enhanced performance
+
+ * DLT library:
+ * On crash or termination of application using the DLT library,
+ the registered context and application IDs are removed properly
+ (and are deregistered from DLT daemon)
+ * dlt_register_context_ll_ts() and Macro therefore added
+ * dlt_message_payload() has now additional type DLT_OUTPUT_ASCII_LIMITED
+ * dlt_message_header_flags() added
+
+ * DLT daemon:
+ * Support for dlt_register_context_ll_ts() added
+ * Enhanced support for get_log_info (all modes, 1 app all contexts, 1 app 1 context, all apps all contexts)
+ * Added -r option, for automatic sending context information to dlt client; if no client connection is available,
+ this information is stored in history buffer in dlt daemon
+ * Several internal performance optimizations:
+ * dlt_daemon_context_find(), dlt_daemon_application_find(): Now O(log n) instead O(n)
+ * Several functions optimized
+ * Unnecessary functions removed
+
+ * General:
+ * Moved definition of struct DltUser from dlt_user_private.h to dlt_user.h
+ * dlt.h includes now dlt_common.h
+ * Extended dlt-test-user and dlt-test-client applications
+
+Bugfixes:
+ * DLT daemon/DLT library: Fixed bug in Filter Delete
+ * DLT daemon: Fixed bug in dlt daemon which leads to a crash, when starting/stoping application, then sending
+ new log level to context of this (now not running) application.
+ * DLT daemon: Fixed bug in unregister application
+ * DLT daemon: Fixed bug in reattach to daemon
+ * DLT library: Fixed bug in send function
+ * DLT viewer: Fixed bug in set default log level
+
+2.0.4:
+
+Attention:
+ * License has changed from ADRLPD to ADRLRM
+
+Improvements
+
+ * DLT viewer:
+ * Support for non-verbose mode (as FIBEX plugin)
+
+ * DLT library:
+ * Support for non-verbose mode (as FIBEX plugin)
+ * dlt_message_print_* functions added
+ * Semaphore calls added to enable multi-threading
+ * Changed injection interface from direct usage to callback
+ * Requested log level and trace status is set immediately
+ in dlt_set_application_ll_ts_limit()
+ * Implemented receiver thread in DLT library
+ (used for setting of log level/trace status and for injection handling)
+ * Added signal-handler and atexit-handler for cleanup (calls dlt_free())
+
+ * General:
+ * Added implementation of clientlib and testclient for Windows
+ * Both adaptors sends now log messages with log level DLT_LOG_INFO
+ * Multi-threading example in src/tests/dlt-test-user-multi added
+
+Bugfixes:
+ * DLT viewer: Right mouse button for loading plugin descriptions (MOST-/Fibex-XML File)
+ is now working (also in Windows)
+ * DLT library: Fixed bug in dlt_print_mixed_string()
+ * DLT library: Fixed bug in dlt_daemon_contexts_get_next_con_id()
+ * DLT daemon: dlt_daemon_process_user_message_unregister_application() also removes now
+ all corresponding contexts
+ * DLT daemon: Added security check to dlt_daemon_control_get_log_info() in order to avoid crash
+ which occured under special circumstances
+ * DLT daemon: Register app now opens the connection to the DLT library,
+ unregister app closes the connection (was before in register context)
+ * Added -lrt to package config file
+ * Resolved dependency from dlt_client.h to dlt_common.h -> dlt_common.h is now public
+
+2.0.3:
+
+Improvements
+
+ * DLT viewer:
+ * Reduced load if idle
+ * Modified behaviour of settings in dlt-viewer
+ * Always open tmpfile in dlt-viewer if nothing other is specified
+ * File->Clear added
+ * DLT daemon:
+ * Added several checks within code
+ * DLT library:
+ * Added several checks within code
+ * Enhanced local print modes:
+ a environment variable now can be used to control local print mode:
+ Variable: DLT_LOCAL_PRINT_MODE
+ Values : "AUTOMATIC" (local print only, if dlt-daemon connection is not
+ available at startup of program using DLT library)
+ "FORCE_ON" (always do local print)
+ "FORCE_OFF" (never do local print)
+ * A client library for writing console client applications (Linux) is now available.
+ dlt-receiver and dlt-test-client uses this new library code
+ * General:
+ * Added seperate file for DltMostMessageHeader type
+ * Added seperate file for DLT protocol values
+ * Relaxed checks for passing trace messages to plugin handler
+ * Tested and improved MOST plugin
+ * Support for float (32 Bit) and double (64 Bit) values
+ * Code fragments for winclientlib and wintestclient added
+
+Bugfixes
+
+ * DLT library: Fixed bug in DLT_IMPORT_CONTEXT
+ * DLT library: Fixed bug in dlt_plugin_print() and dlt_most_payload()
+ * DLT daemon and library: Fixed bug in handling of description strings
+ * DLT viewer: Fixed bug in RMB Click for loading plugin description
+ * General: Fixed parsing and printing of MOST messages
+ * Several small bugs fixed
+
+2.0.2:
+
+Improvements
+
+ * DLT viewer:
+ * Showing timestamp
+ * Compiles now with MS Visual C++
+ * Support for loading multiple descriptions
+ of plugins is now possible (*)
+ * Plugin description can be loaded individually
+ by Right-mouse-button (*)
+ * DLT daemon:
+ * Overflow message is now stored in history buffer,
+ if necessary
+ * DLT library:
+ * Ring-buffer for injection messages implemented
+ * History Buffer for Startup + Overflow implemented
+ * Setting of maximum logged log level/trace status for
+ application triggered by application is now possible
+ * Optional local output of Log message is now possible
+ * General:
+ * Support for ARTIS Box implemented (all, without GUI)
+ * Support for timestamp in standardheader extras added
+ * Support for ECU ID in standardheader extras added;
+ this value can be overwritten by the DLT daemon
+
+(*) = feature not enabled in binary build
+
+Bugfixes
+
+ * DLT viewer:
+ * Store and load application and context description fixed
+ * Fixed crash on termination of Windows version
+ * DLT console utilities:
+ * Fixed printing of filter ids
+ * General:
+ * Big Endian/Little Endian support tested and fixed
+ * Fixed writing and reading of locally created dlt files
+ * Several smaller bugs fixed
+
+2.0.1:
+
+Improvements
+
+ * Full support for serial connection between DLT daemon and DLT Viewer
+
+Bugfixes
+
+ * Several small bugs fixed in DLT Viewer
+
+
+2.0.0:
+
+Improvments
+
+ * Initial Release of new DLT daemon Version 2 including the new DLT Client DLT Viewer
+
+Bug fixes
+
+ * Initial Release
+
+
+Known issues in this release
+----------------------------
+
+ * DLT library: Usage of dlt_user_log_write_float64() and DLT_FLOAT64() leads
+ to "Illegal instruction (core dumped)" on ARM target.
+ * DLT library: Nested calls to DLT_LOG_ ... are not supported, and will lead to a deadlock.
+
+
+API Documentation:
+------------------
+
+ * GENIVI_UserManual_DLT_Daemon.odt
+ API Documentaion and Programming HowTo
+ * Doxygen documentation, can be created with "make doxygen", will then be located at
+ doc/html/index.htm, or doc/rtf/refman.rtf
+
+Other Documents
+----------------
+
+ * GENIVI_UserManual_DLT_Client.odt
+ User Manual for DLT programs
+ * GENIVI_Specification_DLT_Daemon.odt
+ Internals of DLT daemon and DLT library
+
+Notes
+-----
+
+ * Moved to cmake build process
+
+Software/Hardware
+-----------------
+
+ * Developped with:
+ * Ubuntu Linux 9.10 32-bit / Intel PC
+
@@ -0,0 +1,259 @@ +TODO/Features: +============== +(19.1.2011) + +Tasks: +- dlt-daemon should support only output of --version +- dlt-receive serial does not set all serial port parameters, fails on nbtserver2 + +Old: + +- File transfer of Screenshots and other files over DLT +- Optimization of sizes: Pipes, TCP connection buffers +- UTF support +- Support for enabling and disabling optional header fields +- Support for pre-defined factory default settings in DLT daemon +- Store overflow messages in ring-buffer + (and signaling for discarded messages stored in ring-buffer) +- Doc of function groups in dlt_common.h +- Return values for Macros +- Traffic shaping within DLT daemon +- Verbose information of parameters including variable names and units +- DLT_LOG_PRINTF interface +- Remove buffer from DltContext, pass it as parameter to function calls.... + +- Review and rework from review + +DECLINED: +========= +- Individual Macros for specific log level: DLT_LOG_WARN +- DLT_LOG without mycontext +- Interface like printf(type, value, type, value, ...) + +DONE: +===== + +2.2.0: +- Changed contents of DltContext, added DltContextData, several changes in low level API functions +- Locking scheme changed, minimized usage of locks + +2.0.0: +- dlt-convert, -o option +- verbose mode, if applicable +- Ctrl-C Handler, delete pipes and close handles +- Log-output (as function) +- Handling of high data rates +- Send message buffer overflow marker +- Definition of paket format between user lib and daemon +- Set correct ecu id in storage header +- console tools, same options as in daemon +- Documentation + - Doxygen (lib, daemon) +- Compiling under Windows with mingw +- Console tools: + - dlt-receive: -m option missing +- Support for generic network traces +- Adaptor for forwarding input from UDP port to DLT daemon +- Adaptor for forwarding input from stdin to DLT daemon +- Documentation + - Doxygen + - Word/OpenOffice file + - Include last changes (removal of DltUser in all calls) + - Communication between User - Daemon + - Internal structure of DLT daemon + - Internal structure of DLT library + - Not MT safe +- History buffer in Daemon +- Review functional interface, remove DltUser* from each call. +- Viewer: New connection: Insert last used connection address/name +- Sparse ring buffer +- make dist works again +- Examination of transfer of dlt messages over serial link +- Support for serial link in dlt-receive (choosable, either TCP or serial connection) +- Support for serial link in dlt-daemon (optional, serial connection can be added) +- Information incl. package version, package version state and overall svn version added to all programs +- TCP Frameing header +- Synchronisation header between daemon and client +- Support for TCP/serial connection frameing header (auto-sense) +- Support for building packackge without development files: sudo make nodev_rpm bzw. sudo make nodev_deb +- Changed interface to latest common understanding +- Changed documentation to latest common understanding +- One spec file with multiple sub-packets +- MOST code to be removed due to license issues -> Plugins, can be enabled by configure --enable-most-plugin +- Revision number for make dist +- Control message: reset to factory default, set default log level and default trace status +- DLT library: Description handling (Save and transmit AppId, ContextId) +- Viewer: Filter in context-sensitive menu, when to show when to hide +- DLT library: dlt_filter_add(): Allow each apid/ctid combination only once. +- Viewer: If no plugin is loaded, hide menu and register tab +- Description handling (Store description) +- Control Message Get Log Info, Mode 7 response +- Viewer: Disable loading of default description / dialog if no plugins available +- Daemon: Support for Big-/Little endian, -> Flag DLT_HTYP_MSBF and access functions +- Test-Framework +- Viewer: Support for Big Endian (also in dlt-convert) +- Viewer: DATE, TIME in version info string (evtl. Architecture BE, LE) +- get_serial_speed->convert_serial_speed +- #include ..., without dlt/, set in configure environment +- Support for Non-Verbose Mode + +2.0.1: +- Support for serial interface + +2.0.2: +- Store and Load applications including descriptions +- DLT library: Queue (Ring-buffer) for injection messages +- Fixed 32 bit swap +- BE/LE support tested +- Implemented, but not tested: Support for 64 Bit plattforms +- Compiles now for Artis Box (all, without GUI) +- Compiles now with Visual C++ under Windows (GUI only) +- Sending optional timestamp (tmsp) in standardheader extras, + implemented in user library/daemon/viewer +- Showing optional timestamp (tmsp) from standardheader extras +- User library: History Buffer for Startup + Overflow +- Support for ECU ID settings +- Set maximum logged log level/trace status for application triggered by application +- DLT Library: If DLT daemon is not running, print dlt message as ASCII to stdout +- Support for more than one plugin description file +- GUI: Show, if plugin description is currently loaded +- GUI: RMB on plugin allows loading of plugin description +- Daemon: Store overflow message in history buffer +- Daemon: Open TODOs in source code +- dlt-convert: Fixed printing of filter ids (apid, ctid) +- Fixed: Writing local dlt files and reading them in is broken +- Write ECU ID only in DLT daemon; not in DLT lib/user + +2.0.3: +- Fixed bug in DLT_IMPORT_CONTEXT +- Fixed bug in handling of description strings +- Added several checks within dlt_user.c +- Moved declaration of DltMostMessageHeader type to seperate file +- Added several checks within dlt-daemon.c and dlt_daemon_common.c +- Reduced load in dlt-viewer if idle +- Fixed bug in RMB Click for loading plugin description +- Relaxed checks for passing messages to the plugin handler +- Tested MOST Plugin +- modified behaviour of settings in dlt-viewer +- always open tmpfile in dlt-viewer if nothing other is specified +- moved dlt protocol specificas to own header file +- enhanced local print modes: + a environment variable now can be used to control local print mode: + Variable: DLT_LOCAL_PRINT_MODE + Values : "AUTOMATIC" (local print only, if dlt-daemon connection is not + available at startup of dlt-user program) + "FORCE_ON" (always do local print) + "FORCE_OFF" (never do local print) + E.g. set in bash with 'export DLT_LOCAL_PRINT_MODE="FORCE_ON"' +- Support for float and double values +- Added client library code for linux +- Rewrote dlt-receiver and dlt-test-client to use the client library code +- Fixed bug in dlt_plugin_print() and dlt_most_payload() +- Added OnFileClear() in dlt-viewer +- Client Library: Test function to send an injection message +- fixed "make dist" +- First code fragments for winclientlib added +- Fixed parsing and printing of MOST messages + +2.0.4-Pre1 +- Fixed winclientlib and wintestclient +- Added dlt_message_print-* functions and used them in several files +- Initial support for FIBEX Parser for non-verbose mode (payload and header) +- Known Issue: Filtering of decoded non-verbose messages is not possible +- added event handler for windows version +- set default log level for adaptors to DLT_LOG_INFO +- print out number of arguments in non-verbose mode + +2.0.4: +- Plausibility check (byteLength) of parsed FIBEX file +- Check length of message against ĺength of FIBEX frame, if IDs matches +- Fixed bug in dlt_print_mixed_string() +- Changed license from ADRLPD to ADRLRM +- Added semaphore macros for locking to enable multi-threading +- Added multi-threading example in src/tests/dlt-test-user-multi +- Changed injection interface from direct usage to callback +- Set request log level and trace status immediately in dlt_set_application_ll_ts_limit() +- Implemented receiver thread in DLT user library +- Fixed bug in dlt_daemon_contexts_get_next_con_id() +- dlt_daemon_process_user_message_unregister_application() + also removes now all corresponding contexts +- Added security check to dlt_daemon_control_get_log_info() +- Fixed output of variable length strings in non-verbose mode +- Fix in daemon: Register app now open the connection to the user-library, unregister app closes the connection + (was before in Register context) +- Added -lrt to package config file +- Resolved dependency from dlt_client.h to dlt_common.h -> dlt_common.h is now public +- Added signal-handler and atexit-handler for cleanup in DLT user library (calls dlt_free();) + +2.0.5: +- Fixed bug in dlt_filter_delete() +- Fixed bug in viewerFrame::FilterDelete() +- Fixed bug in dlt daemon which leads to a crash, when starting/stoping application, then sending + new log level to context of this (now not running) application. Fix: Ignore PIPE signals in daemon +- Fixed bug in dlt_user_log_out2() and dlt_user_log_out3() +- Fixed bug in void viewerFrame::OnSetDefaultLogLevel() +- Enhanced dlt-viewer: Show default log level +- Optimized dlt_daemon_contexts_get_next_con_id() +- Fixed bug in dlt_daemon_process_user_message_unregister_application() +- Application/Context removal in dlt-daemon on crash/termination of application +- Renamed Filter->New.. to Filter->Delete all filter +- dlt_register_context_ll_ts() and Macro therefore added +- Changed daemon to support dlt_register_context_ll_ts() +- Moved DltUser from dlt_user_private.h to dlt_user.h +- Added dlt_common.h to dlt.h +- Enhanced performance of dlt-viewer +- dlt_message_payload() has now additional type DLT_OUTPUT_ASCII_LIMITED +- print warning, if context was already registered +- dlt daemon: Enhanced support for get_log_info + (all modes, 1 app all contexts, 1 app 1 context, all apps all contexts) +- reattach to daemon fixed in DLT user library +- dlt daemon: added -r option, for automatic sending context information to dlt client; + if no client connection is available, this information is stored in history buffer in dlt daemon +- optimized dlt_daemon_context_find(), dlt_daemon_application_find(): Now O(log n) instead O(n) +- dlt_message_header_flags() and flags implemented +- removed dlt_daemon_contexts_count_app_ids(), dlt_daemon_contexts_get_next_app_id() +- optimized dlt_daemon_control_get_log_info() +- optimized dlt_daemon_process_user_message_unregister_application() +- optimized dlt_daemon_process_user_message_set_app_ll_ts() +- removed dlt_daemon_contexts_count_con_ids(), dlt_daemon_contexts_get_next_con_id() +- optimized dlt_daemon_application_del() +- removed dlt_daemon_application_find_index(), dlt_daemon_context_find_index() +- optimized dlt_daemon_application_add(), dlt_daemon_context_add() +- removed dlt_daemon_application_find_insertpos(), dlt_daemon_context_find_insertpos() +- Extended dlt-test-user and dlt-test-client + +2.1.0-Pre1: +- Combined dlt-test-user-multi and dlt-test-many to dlt-test-stress +- Extended dlt-test-client +- Fixed minor bug, it's possible now to compile the dlt_viewer again under mingw under Windows +- Fixed minor bug in dlt-test-user, test3f: Wrong counter was used +- dlt_common.c: Functions dlt_file_read_raw() and dlt_file_read_header_raw() added +- Fixed minor bug in non-verbose parser +- Added support for raw messages in nonverbose mode +- Removed filtering of messages during writing to a file in dlt_viewer (wx version) +- Moved dlt_viewer (wx version) to seperate project +- Removed plugin support from dlt_receive and dlt_convert +- DLT library: Injection tables are now dynamically allocated +- DLT library: Contexts are now dynamically allocated +- Removed DLT_LOG calls in injection functions due to problems (application hangs) +- Added stress test3 to dlt-test-stress +- Added help to dlt-test-stress, printed if no test was selected +- Added dlt-test-internal +- Small optimization in get_log_info() for one searched application with one searched context, + which is existing in the context table of the dlt daemon + +2.1.0-Pre2: +- Added dlt_float_types.h, and used them in dlt_user.c and dlt_common.c +- Added security checks to functions using float32_t and float64_t +- Extended documentation + +2.1.0-Pre3: +- Added optional syncing to serial header in DLT daemon +- Removed signal handlers from dlt_user.c; ignore SIGPIPE signal; atexit() handler still exists + +2.1.0: +- Support for keep-alive messages, realized as thread, locking added to send functions +- Raw interface for DLT Embedded in DLT User Lib (function: int dlt_forward_msg()) + + + diff --git a/automotive-dlt.pc.cmake b/automotive-dlt.pc.cmake new file mode 100755 index 0000000..0284c5c --- /dev/null +++ b/automotive-dlt.pc.cmake @@ -0,0 +1,12 @@ +prefix=@prefix@ +exec_prefix=@prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: DLT +Description: Diagnostic Log and Trace +Version: @GENIVI_PROJECT_VERSION@ +Requires: +Libs: -L${libdir} -ldlt -lrt -lpthread +Cflags: -I${includedir}/dlt -DDLT_@PRINT_MAJOR_VERSION@_@PRINT_MINOR_VERSION@ + diff --git a/automotive-dlt.spec.cheetah b/automotive-dlt.spec.cheetah new file mode 100755 index 0000000..10c1866 --- /dev/null +++ b/automotive-dlt.spec.cheetah @@ -0,0 +1,103 @@ +Name: automotive-dlt +Summary: %{name} - Diagnostic Log and Trace +Version: 2.2.0 +Release: 1 +License: LGPLv2.1 with special exception +Group: System Environment/Base +Vendor: BMW Group AG +Source: %{name}-%{version}.tar.gz +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root +Requires: %{name} = %{version}-%{release}, pkgconfig + +%description +This component provides a standardised log and trace interface, based on the +standardised protocol specified in the AUTOSAR standard 4.0 DLT. +This component can be used by GENIVI components and other applications as +logging facility providing +- the DLT shared library +- the DLT daemon, including startup scripts +- the DLT daemon adaptors +- the DLT client console utilities +- the DLT test applications + +%package doc +Summary: %{name} - Diagnostic Log and Trace: Documentation +Group: Documentation + +%description doc +This component provides the documentation for %{name}. + +%package devel +Summary: %{name} - Diagnostic Log and Trace: Development files +Group: Development/Libraries +Requires: %{name} = %{version}-%{release}, pkgconfig + +%description devel +This component provides the development libraries and includes for %{name}. + +%prep +%setup +echo "building package automotive-dlt" + +%build +#if $BUILD_DOC == "ON" +%configure --enable-build-doc +#else +%configure +#end if +make + +%install +rm -rf \$RPM_BUILD_ROOT +make install DESTDIR=\$RPM_BUILD_ROOT +mkdir -p \$RPM_BUILD_ROOT/etc/init.d +/usr/bin/install -c -m 755 testscripts/dltdaemon \$RPM_BUILD_ROOT/etc/init.d + +%clean +rm -rf \$RPM_BUILD_ROOT + +%files +/etc/init.d/dltdaemon +%{_libdir}/libdlt.so.2 +%{_libdir}/libdlt.so.2.2.0 +%{_libdir}/libdlt.so +%attr(0755,root,root) %{_bindir}/dltinfo.sh +%{_bindir}/dlt-convert +%{_bindir}/dlt-receive +%{_bindir}/dlt-adaptor-stdin +%{_bindir}/dlt-adaptor-udp +%{_bindir}/dlt-test-client +%{_bindir}/dlt-test-user +%{_bindir}/dlt-test-stress +%{_bindir}/dlt-test-internal +%attr(0755,root,root) %{_bindir}/dlt-daemon +%{_bindir}/dlt-example-user +%{_bindir}/dlt-example-user-func +%{_bindir}/dltdaemon + + +%files doc +%{_usr}/doc/dlt2/LICENSE.txt +#if $BUILD_DOC == "ON" +/usr/local/doc/%{name}/GENIVI_UserManual_DLT_Daemon.odt +/usr/local/doc/%{name}/GENIVI_UserManual_DLT_Daemon.pdf +/usr/local/doc/%{name}/GENIVI_Specification_DLT_Daemon.odt +/usr/local/doc/%{name}/GENIVI_Specification_DLT_Daemon.pdf +/usr/local/doc/%{name}/GENIVI_UserManual_DLT_Client.odt +/usr/local/doc/%{name}/GENIVI_UserManual_DLT_Client.pdf +/usr/local/doc/%{name}/GENIVI_Specification_DLT_Daemon.vsd +#end if + + +%files devel +%{_libdir}/pkgconfig/*.pc +%{_includedir}/dlt/*.h +%{_libdir}/pkgconfig/automotive-dlt.pc + +%pre + +%post + +%changelog +* Wed Nov 24 2010 dlt_maintainer <dlt_maintainer@genivi.org> 2.2.0 +- Creation diff --git a/cmake_uninstall.cmake.in b/cmake_uninstall.cmake.in new file mode 100755 index 0000000..17376d2 --- /dev/null +++ b/cmake_uninstall.cmake.in @@ -0,0 +1,22 @@ +IF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") + MESSAGE(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"") +ENDIF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") + +FILE(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) +STRING(REGEX REPLACE "\n" ";" files "${files}") +FOREACH(file ${files}) + MESSAGE(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"") + IF(EXISTS "$ENV{DESTDIR}${file}") + EXEC_PROGRAM( + "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" + OUTPUT_VARIABLE rm_out + RETURN_VALUE rm_retval + ) + IF(NOT "${rm_retval}" STREQUAL 0) + MESSAGE(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"") + ENDIF(NOT "${rm_retval}" STREQUAL 0) + ELSE(EXISTS "$ENV{DESTDIR}${file}") + MESSAGE(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.") + ENDIF(EXISTS "$ENV{DESTDIR}${file}") +ENDFOREACH(file) + diff --git a/config.h.cmake b/config.h.cmake new file mode 100755 index 0000000..11f99c6 --- /dev/null +++ b/config.h.cmake @@ -0,0 +1,44 @@ +#cmakedefine01 HAVE_ARPAINET_H +#cmakedefine01 HAVE_FCNTL_H +#cmakedefine01 HAVE_FLOAT_H +#cmakedefine01 HAVE_LIMITS_H +#cmakedefine01 HAVE_NETDB_H +#cmakedefine01 HAVE_NETINETIN_H +#cmakedefine01 HAVE_STDDEF_H +#cmakedefine01 HAVE_STDINT_H +#cmakedefine01 HAVE_STDLIB_H +#cmakedefine01 HAVE_STRING_H +#cmakedefine01 HAVE_STRINGS_H +#cmakedefine01 HAVE_SYSIOCTL_H +#cmakedefine01 HAVE_SYSSOCKET_H +#cmakedefine01 HAVE_SYSTIME_H +#cmakedefine01 HAVE_UNISTD_H +#cmakedefine01 HAVE_SYSIPC_H +#cmakedefine01 HAVE_NETDB_H +#cmakedefine01 HAVE_CTYPE_H +#cmakedefine01 HAVE_SIGNAL_H +#cmakedefine01 HAVE_SYSLOG_H +#cmakedefine01 HAVE_SYSSTAT_H +#cmakedefine01 HAVE_LINUXSTAT_H +#cmakedefine01 HAVE_SYSUIO_H +#cmakedefine01 HAVE_TERMIOS_H +#cmakedefine01 HAVE_UNISTD_H + +#cmakedefine01 HAVE_FUNC_BZERO +#cmakedefine01 HAVE_FUNC_CLOCKGETTIME +#cmakedefine01 HAVE_FUNC_FLOOR +#cmakedefine01 HAVE_FUNC_FORK +#cmakedefine01 HAVE_FUNC_GETHOSTBYNAME +#cmakedefine01 HAVE_FUNC_GETTIMEBYDAY +#cmakedefine01 HAVE_FUNC_INETNTOA +#cmakedefine01 HAVE_FUNC_MALLOC +#cmakedefine01 HAVE_FUNC_MEMMOVE +#cmakedefine01 HAVE_FUNC_MEMSET +#cmakedefine01 HAVE_FUNC_MKFIFO +#cmakedefine01 HAVE_FUNC_SELECT +#cmakedefine01 HAVE_FUNC_SOCKET +#cmakedefine01 HAVE_FUNC_STRCHR +#cmakedefine01 HAVE_FUNC_STRERROR +#cmakedefine01 HAVE_FUNC_STRSTR +#cmakedefine01 HAVE_FUNC_STRTOL + diff --git a/distfiles b/distfiles new file mode 100755 index 0000000..98429a9 --- /dev/null +++ b/distfiles @@ -0,0 +1,15 @@ +CMakeLists.txt +(src|include|wxctb|testscripts|doc).*CMakeLists.txt +(src|include|wxctb|testscripts).*\.(cpp|h|c|cxx) +testscripts/dltdaemon +testscripts/dltinfo\.sh +doc/.*\.(odt|vsd) +configure +distfiles +#automotive-dlt.spec.cheetah +package/automotive-dlt.spec.in +cmake_uninstall.cmake.in +[^/]*\.cmake +create-svnversion +.*\.xpm +LICENSE\.txt diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt new file mode 100755 index 0000000..82f730c --- /dev/null +++ b/doc/CMakeLists.txt @@ -0,0 +1,67 @@ +####### +# 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@ +######## + +function(convert_odt ODT_FILE) + set(pdf "${CMAKE_CURRENT_BINARY_DIR}/${ODT_FILE}.pdf") + set(odt "${CMAKE_CURRENT_SOURCE_DIR}/${ODT_FILE}.odt") + add_custom_command( + OUTPUT ${pdf} + DEPENDS ${odt} + COMMAND unoconv + ARGS --format=pdf --stdout ${odt} > ${pdf} + ) +endfunction(convert_odt) + +convert_odt("GENIVI_UserManual_DLT_Client") +convert_odt("GENIVI_UserManual_DLT_Daemon") +convert_odt("GENIVI_Specification_DLT_Daemon") + +ADD_CUSTOM_TARGET(Documents ALL echo DEPENDS +${CMAKE_CURRENT_BINARY_DIR}/GENIVI_UserManual_DLT_Client.pdf +${CMAKE_CURRENT_BINARY_DIR}/GENIVI_UserManual_DLT_Daemon.pdf +${CMAKE_CURRENT_BINARY_DIR}/GENIVI_Specification_DLT_Daemon.pdf) + +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/GENIVI_UserManual_DLT_Client.odt + ${CMAKE_CURRENT_SOURCE_DIR}/GENIVI_UserManual_DLT_Daemon.odt + ${CMAKE_CURRENT_SOURCE_DIR}/GENIVI_Specification_DLT_Daemon.odt + ${CMAKE_CURRENT_BINARY_DIR}/GENIVI_UserManual_DLT_Client.pdf + ${CMAKE_CURRENT_BINARY_DIR}/GENIVI_UserManual_DLT_Daemon.pdf + ${CMAKE_CURRENT_BINARY_DIR}/GENIVI_Specification_DLT_Daemon.pdf + ${CMAKE_CURRENT_SOURCE_DIR}/GENIVI_Specification_DLT_Daemon.vsd + DESTINATION "doc/${CMAKE_PROJECT_NAME}" + COMPONENT doc) + diff --git a/doc/GENIVI_Specification_DLT_Daemon.odt b/doc/GENIVI_Specification_DLT_Daemon.odt Binary files differnew file mode 100755 index 0000000..1110997 --- /dev/null +++ b/doc/GENIVI_Specification_DLT_Daemon.odt diff --git a/doc/GENIVI_Specification_DLT_Daemon.vsd b/doc/GENIVI_Specification_DLT_Daemon.vsd Binary files differnew file mode 100755 index 0000000..a9ec7b0 --- /dev/null +++ b/doc/GENIVI_Specification_DLT_Daemon.vsd diff --git a/doc/GENIVI_UserManual_DLT_Client.odt b/doc/GENIVI_UserManual_DLT_Client.odt Binary files differnew file mode 100755 index 0000000..584f147 --- /dev/null +++ b/doc/GENIVI_UserManual_DLT_Client.odt diff --git a/doc/GENIVI_UserManual_DLT_Daemon.odt b/doc/GENIVI_UserManual_DLT_Daemon.odt Binary files differnew file mode 100755 index 0000000..a7dcb86 --- /dev/null +++ b/doc/GENIVI_UserManual_DLT_Daemon.odt diff --git a/doc/Message_Flow.odg b/doc/Message_Flow.odg Binary files differnew file mode 100755 index 0000000..487f9c2 --- /dev/null +++ b/doc/Message_Flow.odg diff --git a/doxygen.cfg.cmake b/doxygen.cfg.cmake new file mode 100755 index 0000000..b695b5a --- /dev/null +++ b/doxygen.cfg.cmake @@ -0,0 +1,1530 @@ +# Doxyfile 1.5.8 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = @PACKAGE@ + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = @VERSION@ + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = doc + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Farsi, Finnish, French, German, Greek, +# Hungarian, Italian, Japanese, Japanese-en (Japanese with English messages), +# Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, Polish, +# Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, Slovene, +# Spanish, Swedish, and Ukrainian. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = YES + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it parses. +# With this tag you can assign which parser to use for a given extension. +# Doxygen has a built-in mapping, but you can override or extend it using this tag. +# The format is ext=language, where ext is a file extension, and language is one of +# the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP, +# Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat +# .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran), +# use: inc=Fortran f=C + +EXTENSION_MAPPING = + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate getter +# and setter methods for a property. Setting this option to YES (the default) +# will make doxygen to replace the get and set methods by a property in the +# documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = NO + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + +# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to +# determine which symbols to keep in memory and which to flush to disk. +# When the cache is full, less often used symbols will be written to disk. +# For small to medium size projects (<1000 input files) the default value is +# probably good enough. For larger projects a too small cache size can cause +# doxygen to be busy swapping symbols to and from disk most of the time +# causing a significant performance penality. +# If the system has enough physical memory increasing the cache will improve the +# performance by keeping more symbols in memory. Note that the value works on +# a logarithmic scale so increasing the size by one will rougly double the +# memory usage. The cache size is given by this formula: +# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols + +SYMBOL_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = YES + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespace are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = YES + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = NO + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = NO + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command <command> <input-file>, where <command> is the value of +# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by +# doxygen. The layout file controls the global structure of the generated output files +# in an output format independent way. The create the layout file that represents +# doxygen's defaults, run doxygen with the -l option. You can optionally specify a +# file name after the option, if omitted DoxygenLayout.xml will be used as the name +# of the layout file. + +LAYOUT_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = src/ include/ + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 + +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.d \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ + + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = doc \ + examples \ + .git + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = * + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command <filter> <input-file>, where <filter> +# is the value of the INPUT_FILTER tag, and <input-file> is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. Otherwise they will link to the documentation. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). + +HTML_DYNAMIC_SECTIONS = NO + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = YES + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER +# are set, an additional index file will be generated that can be used as input for +# Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated +# HTML documentation. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#namespace + +QHP_NAMESPACE = + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#virtual-folders + +QHP_VIRTUAL_FOLDER = doc + +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add. +# For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see +# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">Qt Help Project / Custom Filters</a>. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's +# filter section matches. +# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">Qt Help Project / Filter Attributes</a>. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file. + +QHG_LOCATION = + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to FRAME, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. Other possible values +# for this tag are: HIERARCHIES, which will generate the Groups, Directories, +# and Class Hierarchy pages using a tree view instead of an ordered list; +# ALL, which combines the behavior of FRAME and HIERARCHIES; and NONE, which +# disables this behavior completely. For backwards compatibility with previous +# releases of Doxygen, the values YES and NO are equivalent to FRAME and NONE +# respectively. + +GENERATE_TREEVIEW = ALL + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = YES + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = YES + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = NO + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = NO + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = @HAVE_DOT@ + +# By default doxygen will write a font called FreeSans.ttf to the output +# directory and reference it in all dot files that doxygen generates. This +# font does not include all possible unicode characters however, so when you need +# these (or just want a differently looking font) you can specify the font name +# using DOT_FONTNAME. You need need to make sure dot is able to find the font, +# which can be done by putting it in a standard location or by setting the +# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory +# containing the font. + +DOT_FONTNAME = FreeSans + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the output directory to look for the +# FreeSans.ttf font (which doxygen will put there itself). If you specify a +# different font using DOT_FONTNAME you can set the path where dot +# can find it using this tag. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Options related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt new file mode 100755 index 0000000..26b97e9 --- /dev/null +++ b/include/CMakeLists.txt @@ -0,0 +1,39 @@ +####### +# 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( dlt ) + diff --git a/include/dlt/CMakeLists.txt b/include/dlt/CMakeLists.txt new file mode 100755 index 0000000..fcdbaea --- /dev/null +++ b/include/dlt/CMakeLists.txt @@ -0,0 +1,40 @@ +####### +# 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@ +######## + +install(FILES dlt.h dlt_user.h dlt_user_macros.h dlt_client.h dlt_protocol.h dlt_common.h dlt_types.h + DESTINATION include/dlt + COMPONENT devel) diff --git a/include/dlt/dlt.h b/include/dlt/dlt.h new file mode 100755 index 0000000..696fc46 --- /dev/null +++ b/include/dlt/dlt.h @@ -0,0 +1,89 @@ +/*
+ * 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.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 13.01.2010 initial
+ */
+
+#ifndef DLT_H
+#define DLT_H
+ +#include "dlt_common.h"
+#include "dlt_user.h"
+
+#endif /* DLT_H */
+
diff --git a/include/dlt/dlt_client.h b/include/dlt/dlt_client.h new file mode 100755 index 0000000..e589469 --- /dev/null +++ b/include/dlt/dlt_client.h @@ -0,0 +1,164 @@ +/*
+ * 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.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$
+ * $LastChangedDate$
+ * $LastChangedBy$
+ */
+
+#ifndef DLT_CLIENT_H
+#define DLT_CLIENT_H
+
+/**
+ \defgroup clientapi DLT Client API
+ \addtogroup clientapi
+ \{
+*/
+
+#include "dlt_types.h"
+#include "dlt_common.h"
+
+typedef struct
+{
+ DltReceiver receiver; /**< receiver pointer to dlt receiver structure */
+ int sock; /**< sock Connection handle/socket */
+ char *servIP; /**< servIP IP adress/Hostname of TCP/IP interface */
+ char *serialDevice; /**< serialDevice Devicename of serial device */
+ speed_t baudrate; /**< baudrate Baudrate of serial interface, as speed_t */
+ int serial_mode; /**< serial_mode Serial mode enabled =1, disabled =0 */
+} DltClient;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void dlt_client_register_message_callback(int (*registerd_callback) (DltMessage *message, void *data)); + +/** + * Initialising dlt client structure + * @param client pointer to dlt client structure + * @param verbose if set to true verbose information is printed out. + * @return negative value if there was an error + */
+int dlt_client_init(DltClient *client, int verbose); +/** + * Connect to dlt daemon using the information from the dlt client structure + * @param client pointer to dlt client structure + * @param verbose if set to true verbose information is printed out. + * @return negative value if there was an error + */
+int dlt_client_connect(DltClient *client, int verbose); +/** + * Cleanup dlt client structure + * @param client pointer to dlt client structure + * @param verbose if set to true verbose information is printed out. + * @return negative value if there was an error + */
+int dlt_client_cleanup(DltClient *client, int verbose); +/** + * Main Loop of dlt client application + * @param client pointer to dlt client structure + * @param data pointer to data to be provided to the main loop + * @param verbose if set to true verbose information is printed out. + * @return negative value if there was an error + */
+int dlt_client_main_loop(DltClient *client, void *data, int verbose); +/** + * Send an injection message to the dlt daemon + * @param client pointer to dlt client structure + * @param apid application id + * @param ctid context id + * @param serviceID service id + * @param buffer Buffer filled with injection message data + * @param size Size of injection data within buffer + * @return negative value if there was an error + */
+int dlt_client_send_inject_msg(DltClient *client, char *apid, char *ctid, uint32_t serviceID, uint8_t *buffer, uint32_t size); +/** + * Set baudrate within dlt client structure + * @param client pointer to dlt client structure + * @param baudrate Baudrate + * @return negative value if there was an error + */ +int dlt_client_setbaudrate(DltClient *client, int baudrate);
+
+#ifdef __cplusplus
+}
+#endif
+
+/**
+ \}
+*/
+
+#endif /* DLT_CLIENT_H */
diff --git a/include/dlt/dlt_common.h b/include/dlt/dlt_common.h new file mode 100755 index 0000000..a13787b --- /dev/null +++ b/include/dlt/dlt_common.h @@ -0,0 +1,1117 @@ +/* + * Dlt- 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_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 13.01.2010 initial + */ +#ifndef DLT_COMMON_H +#define DLT_COMMON_H + +/** + \defgroup commonapi DLT Common API + \addtogroup commonapi + \{ +*/ + +#include <stdio.h> + +#if !defined(_MSC_VER) +#include <unistd.h> +#include <time.h> +#endif + +#if !defined (__WIN32__) && !defined(_MSC_VER) +#include <termios.h> +#endif + +#include "dlt_types.h" +#include "dlt_protocol.h" + +#if !defined (PACKED) +#define PACKED __attribute__((aligned(1),packed)) +#endif + +#if defined (__MSDOS__) || defined (_MSC_VER) +/* set instead /Zp8 flag in Visual C++ configuration */ +#undef PACKED +#define PACKED +#endif + +/* + * Macros to swap the byte order. + */ +#define DLT_SWAP_64(value) ((((uint64_t)DLT_SWAP_32((value)&0xffffffffull))<<32) | (DLT_SWAP_32((value)>>32))) + +#define DLT_SWAP_16(value) ((((value) >> 8)&0xff) | (((value) << 8)&0xff00)) +#define DLT_SWAP_32(value) ((((value) >> 24)&0xff) | (((value) << 8)&0xff0000) | (((value) >> 8)&0xff00) | (((value) << 24)&0xff000000)) + +/* Set Big Endian and Little Endian to a initial value, if not defined */ +#ifndef LITTLE_ENDIAN +#define LITTLE_ENDIAN 1234 +#endif + +#ifndef BIG_ENDIAN +#define BIG_ENDIAN 4321 +#endif + +/* If byte order is not defined, default to little endian */ +#ifndef BYTE_ORDER +#define BYTE_ORDER LITTLE_ENDIAN +#endif + +/* Check for byte-order */ +#if (BYTE_ORDER==BIG_ENDIAN) +/* #warning "Big Endian Architecture!" */ +#define DLT_HTOBE_16(x) ((x)) +#define DLT_HTOLE_16(x) DLT_SWAP_16((x)) +#define DLT_BETOH_16(x) ((x)) +#define DLT_LETOH_16(x) DLT_SWAP_16((x)) + +#define DLT_HTOBE_32(x) ((x)) +#define DLT_HTOLE_32(x) DLT_SWAP_32((x)) +#define DLT_BETOH_32(x) ((x)) +#define DLT_LETOH_32(x) DLT_SWAP_32((x)) + +#define DLT_HTOBE_64(x) ((x)) +#define DLT_HTOLE_64(x) DLT_SWAP_64((x)) +#define DLT_BETOH_64(x) ((x)) +#define DLT_LETOH_64(x) DLT_SWAP_64((x)) +#else +/* #warning "Litte Endian Architecture!" */ +#define DLT_HTOBE_16(x) DLT_SWAP_16((x)) +#define DLT_HTOLE_16(x) ((x)) +#define DLT_BETOH_16(x) DLT_SWAP_16((x)) +#define DLT_LETOH_16(x) ((x)) + +#define DLT_HTOBE_32(x) DLT_SWAP_32((x)) +#define DLT_HTOLE_32(x) ((x)) +#define DLT_BETOH_32(x) DLT_SWAP_32((x)) +#define DLT_LETOH_32(x) ((x)) + +#define DLT_HTOBE_64(x) DLT_SWAP_64((x)) +#define DLT_HTOLE_64(x) ((x)) +#define DLT_BETOH_64(x) DLT_SWAP_64((x)) +#define DLT_LETOH_64(x) ((x)) +#endif + +#define DLT_ENDIAN_GET_16(htyp,x) ((((htyp) & DLT_HTYP_MSBF)>0)?DLT_BETOH_16(x):DLT_LETOH_16(x)) +#define DLT_ENDIAN_GET_32(htyp,x) ((((htyp) & DLT_HTYP_MSBF)>0)?DLT_BETOH_32(x):DLT_LETOH_32(x)) +#define DLT_ENDIAN_GET_64(htyp,x) ((((htyp) & DLT_HTYP_MSBF)>0)?DLT_BETOH_64(x):DLT_LETOH_64(x)) + +#if defined (__WIN32__) || defined (_MSC_VER) +#define LOG_EMERG 0 +#define LOG_ALERT 1 +#define LOG_CRIT 2 +#define LOG_ERR 3 +#define LOG_WARNING 4 +#define LOG_NOTICE 5 +#define LOG_INFO 6 +#define LOG_DEBUG 7 + +#define LOG_PID 0x01 +#define LOG_DAEMON (3<<3) +#endif + +/** + * The standard TCP Port used for DLT daemon + */ +#define DLT_DAEMON_TCP_PORT 3490 + +/** + * The size of a DLT ID + */ +#define DLT_ID_SIZE 4 + +#define DLT_SIZE_WEID DLT_ID_SIZE +#define DLT_SIZE_WSID (sizeof(uint32_t)) +#define DLT_SIZE_WTMS (sizeof(uint32_t)) + +/** + * Get the size of extra header parameters, depends on htyp. + */ +#define DLT_STANDARD_HEADER_EXTRA_SIZE(htyp) ( (DLT_IS_HTYP_WEID(htyp) ? DLT_SIZE_WEID : 0) + (DLT_IS_HTYP_WSID(htyp) ? DLT_SIZE_WSID : 0) + (DLT_IS_HTYP_WTMS(htyp) ? DLT_SIZE_WTMS : 0) ) + + +#if defined (__MSDOS__) || defined (_MSC_VER) +#define __func__ __FUNCTION__ +#endif + +#define PRINT_FUNCTION_VERBOSE(_verbose) \ +{ \ + static char _strbuf[255]; \ + \ + if(_verbose) \ + { \ + sprintf(_strbuf, "%s()\n",__func__); \ + dlt_log(LOG_INFO, _strbuf); \ + } \ +} + +#ifndef NULL +#define NULL (char*)0 +#endif + +#define DLT_MSG_IS_CONTROL(MSG) ((DLT_IS_HTYP_UEH((MSG)->standardheader->htyp)) && \ + (DLT_GET_MSIN_MSTP((MSG)->extendedheader->msin)==DLT_TYPE_CONTROL)) + +#define DLT_MSG_IS_CONTROL_REQUEST(MSG) ((DLT_IS_HTYP_UEH((MSG)->standardheader->htyp)) && \ + (DLT_GET_MSIN_MSTP((MSG)->extendedheader->msin)==DLT_TYPE_CONTROL) && \ + (DLT_GET_MSIN_MTIN((MSG)->extendedheader->msin)==DLT_CONTROL_REQUEST)) + +#define DLT_MSG_IS_CONTROL_RESPONSE(MSG) ((DLT_IS_HTYP_UEH((MSG)->standardheader->htyp)) && \ + (DLT_GET_MSIN_MSTP((MSG)->extendedheader->msin)==DLT_TYPE_CONTROL) && \ + (DLT_GET_MSIN_MTIN((MSG)->extendedheader->msin)==DLT_CONTROL_RESPONSE)) + +#define DLT_MSG_IS_CONTROL_TIME(MSG) ((DLT_IS_HTYP_UEH((MSG)->standardheader->htyp)) && \ + (DLT_GET_MSIN_MSTP((MSG)->extendedheader->msin)==DLT_TYPE_CONTROL) && \ + (DLT_GET_MSIN_MTIN((MSG)->extendedheader->msin)==DLT_CONTROL_TIME)) + +#define DLT_MSG_IS_NW_TRACE(MSG) ((DLT_IS_HTYP_UEH((MSG)->standardheader->htyp)) && \ + (DLT_GET_MSIN_MSTP((MSG)->extendedheader->msin)==DLT_TYPE_NW_TRACE)) + +#define DLT_MSG_IS_TRACE_MOST(MSG) ((DLT_IS_HTYP_UEH((MSG)->standardheader->htyp)) && \ + (DLT_GET_MSIN_MSTP((MSG)->extendedheader->msin)==DLT_TYPE_NW_TRACE) && \ + (DLT_GET_MSIN_MTIN((MSG)->extendedheader->msin)==DLT_NW_TRACE_MOST)) + +#define DLT_MSG_IS_NONVERBOSE(MSG) (!(DLT_IS_HTYP_UEH((MSG)->standardheader->htyp)) || \ + ((DLT_IS_HTYP_UEH((MSG)->standardheader->htyp)) && (!(DLT_IS_MSIN_VERB((MSG)->extendedheader->msin))))) + +/* + + * Definitions of DLT message buffer overflow + */ +#define DLT_MESSAGE_BUFFER_NO_OVERFLOW 0x00 /**< Buffer overflow has not occured */ +#define DLT_MESSAGE_BUFFER_OVERFLOW 0x01 /**< Buffer overflow has occured */ + +/* + * Definition of DLT output variants + */ +#define DLT_OUTPUT_HEX 1 +#define DLT_OUTPUT_ASCII 2 +#define DLT_OUTPUT_MIXED_FOR_PLAIN 3 +#define DLT_OUTPUT_MIXED_FOR_HTML 4 +#define DLT_OUTPUT_ASCII_LIMITED 5 + +#define DLT_FILTER_MAX 30 /**< Maximum number of filters */ + +#define DLT_MSG_READ_VALUE(dst,src,length,type) \ + { \ + if((length<0) || ((length)<((int32_t)sizeof(type)))) \ + { length = -1; } \ + else \ + { dst = *((type*)src);src+=sizeof(type);length-=sizeof(type); } \ + } + +#define DLT_MSG_READ_ID(dst,src,length) \ + { \ + if((length<0) || ((length)<DLT_ID_SIZE)) \ + { length = -1; } \ + else \ + { memcpy(dst,src,DLT_ID_SIZE);src+=DLT_ID_SIZE;length-=DLT_ID_SIZE; } \ + } + +#define DLT_MSG_READ_STRING(dst,src,maxlength,length) \ + { \ + if(((maxlength)<0) || ((length)<0) || ((maxlength)<(length))) \ + { maxlength = -1; } \ + else \ + { memcpy(dst,src,length);dlt_clean_string(dst,length);dst[length]=0; \ + src+=length;maxlength-=length; } \ + } + +#define DLT_MSG_READ_NULL(src,maxlength,length) \ + { \ + if(((maxlength)<0) || ((length)<0) || ((maxlength)<(length))) \ + { length = -1; } \ + else \ + { src+=length;maxlength-=length; } \ + } + +#define DLT_HEADER_SHOW_NONE 0x0000 +#define DLT_HEADER_SHOW_TIME 0x0001 +#define DLT_HEADER_SHOW_TMSTP 0x0002 +#define DLT_HEADER_SHOW_MSGCNT 0x0004 +#define DLT_HEADER_SHOW_ECUID 0x0008 +#define DLT_HEADER_SHOW_APID 0x0010 +#define DLT_HEADER_SHOW_CTID 0x0020 +#define DLT_HEADER_SHOW_MSGTYPE 0x0040 +#define DLT_HEADER_SHOW_MSGSUBTYPE 0x0080 +#define DLT_HEADER_SHOW_VNVSTATUS 0x0100 +#define DLT_HEADER_SHOW_NOARG 0x0200 +#define DLT_HEADER_SHOW_ALL 0xFFFF + +/** + * The definition of the serial header containing the characters "DLS" + 0x01. + */ +extern const char dltSerialHeader[DLT_ID_SIZE]; + +/** + * The definition of the serial header containing the characters "DLS" + 0x01 as char. + */ +extern char dltSerialHeaderChar[DLT_ID_SIZE]; + +/** + + * The type of a DLT ID (context id, application id, etc.) + */ +typedef char ID4[DLT_ID_SIZE]; + +/** + * The structure of the DLT file storage header. This header is used before each stored DLT message. + */ +typedef struct +{ + char pattern[DLT_ID_SIZE]; /**< This pattern should be DLT0x01 */ + time_t seconds; /**< seconds since 1.1.1970 */ + int32_t microseconds; /**< Microseconds */ + char ecu[DLT_ID_SIZE]; /**< The ECU id is added, if it is not already in the DLT message itself */ +} PACKED DltStorageHeader; + +/** + * The structure of the DLT standard header. This header is used in each DLT message. + */ +typedef struct +{ + uint8_t htyp; /**< This parameter contains several informations, see definitions below */ + uint8_t mcnt; /**< The message counter is increased with each sent DLT message */ + uint16_t len; /**< Length of the complete message, without storage header */ +} PACKED DltStandardHeader; + +/** + * The structure of the DLT extra header parameters. Each parameter is sent only if enabled in htyp. + */ +typedef struct +{ + char ecu[DLT_ID_SIZE]; /**< ECU id */ + uint32_t seid; /**< Session number */ + uint32_t tmsp; /**< Timestamp since system start in 0.1 milliseconds */ +} PACKED DltStandardHeaderExtra; + +/** + * The structure of the DLT extended header. This header is only sent if enabled in htyp parameter. + */ +typedef struct +{ + uint8_t msin; /**< messsage info */ + uint8_t noar; /**< number of arguments */ + char apid[DLT_ID_SIZE]; /**< application id */ + char ctid[DLT_ID_SIZE]; /**< context id */ +} PACKED DltExtendedHeader; + +/** + * The structure to organise the DLT messages. + * This structure is used by the corresponding functions. + */ +typedef struct sDltMessage +{ + /* flags */ + int8_t found_serialheader; + + /* offsets */ + int32_t resync_offset; + + /* size parameters */ + int32_t headersize; /**< size of complete header including storage header */ + int32_t datasize; /**< size of complete payload */ + + /* buffer for current loaded message */ + uint8_t headerbuffer[sizeof(DltStorageHeader)+ + sizeof(DltStandardHeader)+sizeof(DltStandardHeaderExtra)+sizeof(DltExtendedHeader)]; /**< buffer for loading complete header */ + uint8_t *databuffer; /**< buffer for loading payload */ + + /* header values of current loaded message */ + DltStorageHeader *storageheader; /**< pointer to storage header of current loaded header */ + DltStandardHeader *standardheader; /**< pointer to standard header of current loaded header */ + DltStandardHeaderExtra headerextra; /**< extra parameters of current loaded header */ + DltExtendedHeader *extendedheader; /**< pointer to extended of current loaded header */ +} DltMessage; + +/** + * The structure of the DLT Service Get Log Info. + */ +typedef struct +{ + uint32_t service_id; /**< service ID */ + uint8_t options; /**< type of request */ + char apid[DLT_ID_SIZE]; /**< application id */ + char ctid[DLT_ID_SIZE]; /**< context id */ + char com[DLT_ID_SIZE]; /**< communication interface */ +} PACKED DltServiceGetLogInfoRequest; + +/** + * The structure of the DLT Service Set Log Level. + */ +typedef struct +{ + uint32_t service_id; /**< service ID */ + char apid[DLT_ID_SIZE]; /**< application id */ + char ctid[DLT_ID_SIZE]; /**< context id */ + uint8_t log_level; /**< log level to be set */ + char com[DLT_ID_SIZE]; /**< communication interface */ +} PACKED DltServiceSetLogLevel; + +/** + * The structure of the DLT Service Set Default Log Level. + */ +typedef struct +{ + uint32_t service_id; /**< service ID */ + uint8_t log_level; /**< default log level to be set */ + char com[DLT_ID_SIZE]; /**< communication interface */ +} PACKED DltServiceSetDefaultLogLevel; + +/** + * The structure of the DLT Service Set Verbose Mode + */ +typedef struct +{ + uint32_t service_id; /**< service ID */ + uint8_t new_status; /**< new status to be set */ +} PACKED DltServiceSetVerboseMode; + +/** + * The structure of the DLT Service Set Communication Interface Status + */ +typedef struct +{ + uint32_t service_id; /**< service ID */ + char com[DLT_ID_SIZE]; /**< communication interface */ + uint8_t new_status; /**< new status to be set */ +} PACKED DltServiceSetCommunicationInterfaceStatus; + +/** + * The structure of the DLT Service Set Communication Maximum Bandwidth + */ +typedef struct +{ + uint32_t service_id; /**< service ID */ + char com[DLT_ID_SIZE]; /**< communication interface */ + uint32_t max_bandwidth; /**< maximum bandwith */ +} PACKED DltServiceSetCommunicationMaximumBandwidth; + +typedef struct +{ + uint32_t service_id; /**< service ID */ + uint8_t status; /**< reponse status */ +} PACKED DltServiceResponse; + +typedef struct +{ + uint32_t service_id; /**< service ID */ + uint8_t status; /**< reponse status */ + uint8_t log_level; /**< log level */ +} PACKED DltServiceGetDefaultLogLevelResponse; + +typedef struct +{ + uint32_t service_id; /**< service ID */ + uint8_t status; /**< reponse status */ + uint8_t overflow; /**< overflow status */ +} PACKED DltServiceMessageBufferOverflowResponse; + +typedef struct +{ + uint32_t service_id; /**< service ID */ + uint8_t status; /**< reponse status */ + uint32_t length; /**< length of following payload */ + /* char [] payload */ +} PACKED DltServiceGetSoftwareVersionResponse; + +/** + * Structure to store filter parameters. + * ID are maximal four characters. Unused values are filled with zeros. + * If every value as filter is valid, the id should be empty by having only zero values. + */ +typedef struct +{ + char apid[DLT_FILTER_MAX][DLT_ID_SIZE]; /**< application id */ + char ctid[DLT_FILTER_MAX][DLT_ID_SIZE]; /**< context id */ + int counter; /**< number of filters */ +} DltFilter; + +/** + * The structure to organise the access to DLT files. + * This structure is used by the corresponding functions. + */ +typedef struct sDltFile +{ + /* file handle and index for fast access */ + FILE *handle; /**< file handle of opened DLT file */ + long *index; /**< file positions of all DLT messages for fast access to file, only filtered messages */ + + /* size parameters */ + int32_t counter; /**< number of messages in DLT file with filter */ + int32_t counter_total; /**< number of messages in DLT file without filter */ + int32_t position; /**< current index to message parsed in DLT file starting at 0 */ + long file_length; /**< length of the file */ + long file_position; /**< current position in the file */ + + /* error counters */ + int32_t error_messages; /**< number of incomplete DLT messages found during file parsing */ + + /* filter parameters */ + DltFilter *filter; /**< pointer to filter list. Zero if no filter is set. */ + int32_t filter_counter; /**< number of filter set */ + + /* current loaded message */ + DltMessage msg; /**< pointer to message */ + +} DltFile; + +/** + * The structure is used to organise the receiving of data + * including buffer handling. + * This structure is used by the corresponding functions. + */ +typedef struct +{ + int32_t lastBytesRcvd; /**< bytes received in last receive call */ + int32_t bytesRcvd; /**< received bytes */ + int32_t totalBytesRcvd; /**< total number of received bytes */ + char *buffer; /**< pointer to receiver buffer */ + char *buf; /**< pointer to position within receiver buffer */ + int fd; /**< connection handle */ + int32_t buffersize; /**< size of receiver buffer */ +} DltReceiver; + +typedef struct +{ + char* buffer; /**< Ptr. to buffer */ + uint32_t size; /**< Maximum size of buffer */ + uint32_t pos_write; /**< current writing position in bytes*/ + uint32_t pos_read; /**< current reading position in bytes*/ + uint32_t count; /**< nr. of entries */ +} DltRingBuffer; + +#ifdef __cplusplus +extern "C" +{ +#endif + + /** + * Helper function to print a byte array in hex. + * @param ptr pointer to the byte array. + * @param size number of bytes to be printed. + */ + void dlt_print_hex(uint8_t *ptr,int size); + /** + * Helper function to print a byte array in hex into a string. + * @param text pointer to a ASCII string, in which the text is written + * @param textlength maximal size of text buffer + * @param ptr pointer to the byte array. + * @param size number of bytes to be printed. + * @return negative value if there was an error + */ + int dlt_print_hex_string(char *text,int textlength,uint8_t *ptr,int size); + /** + * Helper function to print a byte array in hex and ascii into a string. + * @param text pointer to a ASCII string, in which the text is written + * @param textlength maximal size of text buffer + * @param ptr pointer to the byte array. + * @param size number of bytes to be printed. + * @param html output is html? 0 - false, 1 - true + * @return negative value if there was an error + */ + int dlt_print_mixed_string(char *text,int textlength,uint8_t *ptr,int size,int html); + /** + * Helper function to print a byte array in ascii into a string. + * @param text pointer to a ASCII string, in which the text is written + * @param textlength maximal size of text buffer + * @param ptr pointer to the byte array. + * @param size number of bytes to be printed. + * @return negative value if there was an error + */ + int dlt_print_char_string(char **text,int textlength,uint8_t *ptr,int size); + + /** + * Helper function to print an id. + * @param text pointer to ASCII string where to write the id + * @param id four byte char array as used in DLT mesages as IDs. + */ + void dlt_print_id(char *text,const char *id); + + /** + * Helper function to set an ID parameter. + * @param id four byte char array as used in DLT mesages as IDs. + * @param text string to be copied into char array. + */ + void dlt_set_id(char *id,const char *text); + + /** + * Helper function to remove not nice to print characters, e.g. NULL or carage return. + * @param text pointer to string to be cleaned. + * @param length length of string excluding terminating zero. + */ + void dlt_clean_string(char *text,int length); + + /** + * Initialise the filter list. + * This function must be called before using further dlt filter. + * @param filter pointer to structure of organising DLT filter + * @param verbose if set to true verbose information is printed out. + * @return negative value if there was an error + */ + int dlt_filter_init(DltFilter *filter,int verbose); + /** + * Free the used memory by the organising structure of filter. + * @param filter pointer to structure of organising DLT filter + * @param verbose if set to true verbose information is printed out. + * @return negative value if there was an error + */ + int dlt_filter_free(DltFilter *filter,int verbose); + /** + * Load filter list from file. + * @param filter pointer to structure of organising DLT filter + * @param filename filename to load filters from + * @param verbose if set to true verbose information is printed out. + * @return negative value if there was an error + */ + int dlt_filter_load(DltFilter *filter,const char *filename,int verbose); + /** + * Save filter list to file. + * @param filter pointer to structure of organising DLT filter + * @param filename filename to load filters from + * @param verbose if set to true verbose information is printed out. + * @return negative value if there was an error + */ + int dlt_filter_save(DltFilter *filter,const char *filename,int verbose); + /** + * Find index of filter in filter list + * @param filter pointer to structure of organising DLT filter + * @param apid application id to be found in filter list + * @param ctid context id to be found in filter list + * @param verbose if set to true verbose information is printed out. + * @return negative value if there was an error (or not found), else return index of filter + */ + int dlt_filter_find(DltFilter *filter,const char *apid,const char *ctid, int verbose); + /** + * Add new filter to filter list. + * @param filter pointer to structure of organising DLT filter + * @param apid application id to be added to filter list (must always be set). + * @param ctid context id to be added to filter list. empty equals don't care. + * @param verbose if set to true verbose information is printed out. + * @return negative value if there was an error + */ + int dlt_filter_add(DltFilter *filter,const char *apid,const char *ctid,int verbose); + /** + * Delete filter from filter list + * @param filter pointer to structure of organising DLT filter + * @param apid application id to be deleted from filter list + * @param ctid context id to be deleted from filter list + * @param verbose if set to true verbose information is printed out. + * @return negative value if there was an error + */ + int dlt_filter_delete(DltFilter *filter,const char *apid,const char *ctid,int verbose); + + /** + * Initialise the structure used to access a DLT message. + * This function must be called before using further dlt_message functions. + * @param msg pointer to structure of organising access to DLT messages + * @param verbose if set to true verbose information is printed out. + * @return negative value if there was an error + */ + int dlt_message_init(DltMessage *msg,int verbose); + /** + * Free the used memory by the organising structure of file. + * @param msg pointer to structure of organising access to DLT messages + * @param verbose if set to true verbose information is printed out. + * @return negative value if there was an error + */ + int dlt_message_free(DltMessage *msg,int verbose); + /** + * Print Header into an ASCII string. + * This function calls dlt_message_header_flags() with flags=DLT_HEADER_SHOW_ALL + * @param msg pointer to structure of organising access to DLT messages + * @param text pointer to a ASCII string, in which the header is written + * @param textlength maximal size of text buffer + * @param verbose if set to true verbose information is printed out. + * @return negative value if there was an error + */ + int dlt_message_header(DltMessage *msg,char *text,int textlength,int verbose); + /** + * Print Header into an ASCII string, selective. + * @param msg pointer to structure of organising access to DLT messages + * @param text pointer to a ASCII string, in which the header is written + * @param textlength maximal size of text buffer + * @param flags select, bit-field to select, what should be printed (DLT_HEADER_SHOW_...) + * @param verbose if set to true verbose information is printed out. + * @return negative value if there was an error + */ + int dlt_message_header_flags(DltMessage *msg,char *text,int textlength,int flags, int verbose); + /** + * Print Payload into an ASCII string. + * @param msg pointer to structure of organising access to DLT messages + * @param text pointer to a ASCII string, in which the header is written + * @param textlength maximal size of text buffer + * @param type 1 = payload as hex, 2 = payload as ASCII. + * @param verbose if set to true verbose information is printed out. + * @return negative value if there was an error + */ + int dlt_message_payload(DltMessage *msg,char *text,int textlength,int type,int verbose); + /** + * Check if message is filtered or not. All filters are applied (logical OR). + * @param msg pointer to structure of organising access to DLT messages + * @param filter pointer to filter + * @param verbose if set to true verbose information is printed out. + * @return 1 = filter matches, 0 = filter does not match, negative value if there was an error + */ + int dlt_message_filter_check(DltMessage *msg,DltFilter *filter,int verbose); + + /** + * Read message from memory buffer. + * Message in buffer has no storage header. + * @param msg pointer to structure of organising access to DLT messages + * @param buffer pointer to memory buffer + * @param length length of message in buffer + * @param resync if set to true resync to serial header is enforced + * @param verbose if set to true verbose information is printed out. + * @return negative value if there was an error + */ + int dlt_message_read(DltMessage *msg,uint8_t *buffer,unsigned int length,int resync,int verbose); + + /** + * Get standard header extra parameters + * @param msg pointer to structure of organising access to DLT messages + * @param verbose if set to true verbose information is printed out. + * @return negative value if there was an error + */ + int dlt_message_get_extraparameters(DltMessage *msg,int verbose); + + /** + * Set standard header extra parameters + * @param msg pointer to structure of organising access to DLT messages + * @param verbose if set to true verbose information is printed out. + * @return negative value if there was an error + */ + int dlt_message_set_extraparameters(DltMessage *msg,int verbose); + + /** + * Initialise the structure used to access a DLT file. + * This function must be called before using further dlt_file functions. + * @param file pointer to structure of organising access to DLT file + * @param verbose if set to true verbose information is printed out. + * @return negative value if there was an error + */ + int dlt_file_init(DltFile *file,int verbose); + /** + * Set a list to filters. + * This function should be called before loading a DLT file, if filters should be used. + * A filter list is an array of filters. Several filters are combined logically by or operation. + * The filter list is not copied, so take care to keep list in memory. + * @param file pointer to structure of organising access to DLT file + * @param filter pointer to filter list array + * @param verbose if set to true verbose information is printed out. + * @return negative value if there was an error + */ + int dlt_file_set_filter(DltFile *file,DltFilter *filter,int verbose); + /** + * Initialising loading a DLT file. + * @param file pointer to structure of organising access to DLT file + * @param filename filename of DLT file + * @param verbose if set to true verbose information is printed out. + * @return negative value if there was an error + */ + int dlt_file_open(DltFile *file,const char *filename,int verbose); + /** + * Find next message in the DLT file and parse them. + * This function finds the next message in the DLT file. + * If a filter is set, the filter list is used. + * @param file pointer to structure of organising access to DLT file + * @param verbose if set to true verbose information is printed out. + * @return 0 = message does not match filter, 1 = message was read, negative value if there was an error + */ + int dlt_file_read(DltFile *file,int verbose); + /** + * Find next message in the DLT file in RAW format (without storage header) and parse them. + * This function finds the next message in the DLT file. + * If a filter is set, the filter list is used. + * @param file pointer to structure of organising access to DLT file + * @param resync Resync to serial header when set to true + * @param verbose if set to true verbose information is printed out. + * @return 0 = message does not match filter, 1 = message was read, negative value if there was an error + */ + int dlt_file_read_raw(DltFile *file,int resync,int verbose); + /** + * Closing loading a DLT file. + * @param file pointer to structure of organising access to DLT file + * @param verbose if set to true verbose information is printed out. + * @return negative value if there was an error + */ + int dlt_file_close(DltFile *file,int verbose); + /** + * Load standard header of a message from file + * @param file pointer to structure of organising access to DLT file + * @param verbose if set to true verbose information is printed out. + * @return negative value if there was an error + */ + int dlt_file_read_header(DltFile *file,int verbose); + /** + * Load standard header of a message from file in RAW format (without storage header) + * @param file pointer to structure of organising access to DLT file + * @param resync Resync to serial header when set to true + * @param verbose if set to true verbose information is printed out. + * @return negative value if there was an error + */ + int dlt_file_read_header_raw(DltFile *file,int resync,int verbose); + /** + * Load, if available in message, extra standard header fields and + * extended header of a message from file + * (dlt_file_read_header() must have been called before this call!) + * @param file pointer to structure of organising access to DLT file + * @param verbose if set to true verbose information is printed out. + * @return negative value if there was an error + */ + int dlt_file_read_header_extended(DltFile *file, int verbose); + /** + * Load payload of a message from file + * (dlt_file_read_header() must have been called before this call!) + * @param file pointer to structure of organising access to DLT file + * @param verbose if set to true verbose information is printed out. + * @return negative value if there was an error + */ + int dlt_file_read_data(DltFile *file, int verbose); + /** + * Load headers and payload of a message selected by the index. + * If filters are set, index is based on the filtered list. + * @param file pointer to structure of organising access to DLT file + * @param index position of message in the files beginning from zero + * @param verbose if set to true verbose information is printed out. + * @return number of messages loaded, negative value if there was an error + */ + int dlt_file_message(DltFile *file,int index,int verbose); + /** + * Free the used memory by the organising structure of file. + * @param file pointer to structure of organising access to DLT file + * @param verbose if set to true verbose information is printed out. + * @return negative value if there was an error + */ + int dlt_file_free(DltFile *file,int verbose); + + /** + * Initialize (external) logging facility + * @param mode positive, if syslog should be used; zero for console output + */ + void dlt_log_init(int mode); + /** + * Log ASCII string with null-termination to (external) logging facility + * @param prio priority (see syslog() call) + * @param s Pointer to ASCII string with null-termination + * @return negative value if there was an error + */ + int dlt_log(int prio, char *s); + /** + * De-Initialize (external) logging facility + */ + void dlt_log_free(void); + + /** + * Initialising a dlt receiver structure + * @param receiver pointer to dlt receiver structure + * @param _fd handle to file/socket/fifo, fram which the data should be received + * @param _buffersize size of data buffer for storing the received data + * @return negative value if there was an error + */ + int dlt_receiver_init(DltReceiver *receiver,int _fd, int _buffersize); + /** + * De-Initialize a dlt receiver structure + * @param receiver pointer to dlt receiver structure + * @return negative value if there was an error + */ + int dlt_receiver_free(DltReceiver *receiver); + /** + * Receive data from socket using the dlt receiver structure + * @param receiver pointer to dlt receiver structure + * @return negative value if there was an error + */ + int dlt_receiver_receive_socket(DltReceiver *receiver); + /** + * Receive data from file/fifo using the dlt receiver structure + * @param receiver pointer to dlt receiver structure + * @return negative value if there was an error + */ + int dlt_receiver_receive_fd(DltReceiver *receiver); + /** + * Remove a specific size of bytes from the received data + * @param receiver pointer to dlt receiver structure + * @param size amount of bytes to be removed + * @return negative value if there was an error + */ + int dlt_receiver_remove(DltReceiver *receiver,int size); + /** + * Move data from last receive call to front of receive buffer + * @param receiver pointer to dlt receiver structure + * @return negative value if there was an error + */ + int dlt_receiver_move_to_begin(DltReceiver *receiver); + + /** + * Fill out storage header of a dlt message + * @param storageheader pointer to storage header of a dlt message + * @param ecu name of ecu to be set in storage header + * @return negative value if there was an error + */ + int dlt_set_storageheader(DltStorageHeader *storageheader, const char *ecu); + /** + * Check if a storage header contains its marker + * @param storageheader pointer to storage header of a dlt message + * @return 0 no, 1 yes, negative value if there was an error + */ + int dlt_check_storageheader(DltStorageHeader *storageheader); + + /** + * Initialize ringbuffer of with a maximum size of size + * @param dltbuf Pointer to ringbuffer structure + * @param size Maximum size of buffer in bytes + * @return negative value if there was an error + */ + int dlt_ringbuffer_init(DltRingBuffer *dltbuf, uint32_t size); + + /** + * Release and free memory used by ringbuffer + * @param dltbuf Pointer to ringbuffer structure + * @return negative value if there was an error + */ + int dlt_ringbuffer_free(DltRingBuffer *dltbuf); + + /** + * Write one entry to ringbuffer + * @param dltbuf Pointer to ringbuffer structure + * @param data Pointer to data to be written to ringbuffer + * @param size Size of data in bytes to be written to ringbuffer + * @return negative value if there was an error + */ + int dlt_ringbuffer_put(DltRingBuffer *dltbuf, void *data, uint32_t size); + + /** + * Write one entry given as 3 chunks to ringbuffer + * @param dltbuf Pointer to ringbuffer structure + * @param data1 Pointer to data1 to be written to ringbuffer + * @param size1 Size of data1 in bytes to be written to ringbuffer + * @param data2 Pointer to data2 to be written to ringbuffer + * @param size2 Size of data2 in bytes to be written to ringbuffer + * @param data3 Pointer to data3 to be written to ringbuffer + * @param size3 Size of data3 in bytes to be written to ringbuffer + * @return negative value if there was an error + */ + int dlt_ringbuffer_put3(DltRingBuffer *dltbuf, void *data1, uint32_t size1, void *data2, uint32_t size2, void *data3, uint32_t size3); + + /** + * Read one entry from ringbuffer + * @param dltbuf Pointer to ringbuffer structure + * @param data Pointer to data read from ringbuffer + * @param size Size of read data in bytes from ringbuffer + * @return negative value if there was an error + */ + int dlt_ringbuffer_get(DltRingBuffer *dltbuf, void *data, size_t *size); + + /** + * Helper function: Skip one readable entry in ringbuffer + * @param dltbuf Pointer to ringbuffer structure + * @return negative value if there was an error + */ + int dlt_ringbuffer_get_skip(DltRingBuffer *dltbuf); + + /** + * Helper function: Get free space in bytes for writting between write and read position + * @param dltbuf Pointer to ringbuffer structure + * @param freespace Free Space in bytes for writting is returned + * @return negative value if there was an error + */ + int dlt_ringbuffer_freespacewrite(DltRingBuffer *dltbuf, uint32_t *freespace); + + /** + * Helper function: Check free space and if necessary discard entries, so that at least + * reqspace bytes are available for writting + * @param dltbuf Pointer to ringbuffer structure + * @param reqspace Requested space for writting in bytes + * @return negative value if there was an error + */ + int dlt_ringbuffer_checkandfreespace(DltRingBuffer *dltbuf, uint32_t reqspace); + +#if !defined (__WIN32__) + + /** + * Helper function: Setup serial connection + * @param fd File descriptor of serial tty device + * @param speed Serial line speed, as defined in termios.h + * @return negative value if there was an error + */ + int dlt_setup_serial(int fd, speed_t speed); + + /** + * Helper function: Convert serial line baudrate (as number) to line speed (as defined in termios.h) + * @param baudrate Serial line baudrate (as number) + * @return Serial line speed, as defined in termios.h + */ + speed_t dlt_convert_serial_speed(int baudrate); + + /** + * Print dlt version and dlt svn version to buffer + * @param buf Pointer to buffer + */ + void dlt_get_version(char *buf); + +#endif + + /* Function prototypes which should be used only internally */ + /* */ + + /** + * Common part of initialisation + * @return negative value if there was an error + */ + int dlt_init_common(void); + + /** + * Return the uptime of the system in 0.1 ms resolution + * @return 0 if there was an error + */ + uint32_t dlt_uptime(void); + + /** + * Print header of a DLT message + * @param message pointer to structure of organising access to DLT messages + * @param text pointer to a ASCII string, in which the header is written + * @param size maximal size of text buffer + * @param verbose if set to true verbose information is printed out. + * @return negative value if there was an error + */ + int dlt_message_print_header(DltMessage *message, char *text, uint32_t size, int verbose); + + /** + * Print payload of a DLT message as Hex-Output + * @param message pointer to structure of organising access to DLT messages + * @param text pointer to a ASCII string, in which the output is written + * @param size maximal size of text buffer + * @param verbose if set to true verbose information is printed out. + * @return negative value if there was an error + */ + int dlt_message_print_hex(DltMessage *message, char *text, uint32_t size, int verbose); + + /** + * Print payload of a DLT message as ASCII-Output + * @param message pointer to structure of organising access to DLT messages + * @param text pointer to a ASCII string, in which the output is written + * @param size maximal size of text buffer + * @param verbose if set to true verbose information is printed out. + * @return negative value if there was an error + */ + int dlt_message_print_ascii(DltMessage *message, char *text, uint32_t size, int verbose); + + /** + * Print payload of a DLT message as Mixed-Ouput (Hex and ASCII), for plain text output + * @param message pointer to structure of organising access to DLT messages + * @param text pointer to a ASCII string, in which the output is written + * @param size maximal size of text buffer + * @param verbose if set to true verbose information is printed out. + * @return negative value if there was an error + */ + int dlt_message_print_mixed_plain(DltMessage *message, char *text, uint32_t size, int verbose); + + /** + * Print payload of a DLT message as Mixed-Ouput (Hex and ASCII), for HTML text output + * @param message pointer to structure of organising access to DLT messages + * @param text pointer to a ASCII string, in which the output is written + * @param size maximal size of text buffer + * @param verbose if set to true verbose information is printed out. + * @return negative value if there was an error + */ + int dlt_message_print_mixed_html(DltMessage *message, char *text, uint32_t size, int verbose); + + /** + * Decode and print a argument of a DLT message + * @param msg pointer to structure of organising access to DLT messages + * @param type_info Type of argument + * @param ptr pointer to pointer to data (pointer to data is changed within this function) + * @param datalength pointer to datalength (datalength is changed within this function) + * @param text pointer to a ASCII string, in which the output is written + * @param textlength maximal size of text buffer + * @param byteLength If argument is a string, and this value is 0 or greater, this value will be taken as string length + * @param verbose if set to true verbose information is printed out. + * @return negative value if there was an error + */ + int dlt_message_argument_print(DltMessage *msg,uint32_t type_info,uint8_t **ptr,int32_t *datalength,char *text,int textlength,int byteLength,int verbose); + +#ifdef __cplusplus +} +#endif + +/** + \} +*/ + +#endif /* DLT_COMMON_H */ diff --git a/include/dlt/dlt_protocol.h b/include/dlt/dlt_protocol.h new file mode 100755 index 0000000..88f7d89 --- /dev/null +++ b/include/dlt/dlt_protocol.h @@ -0,0 +1,218 @@ +/*
+ * Dlt- Diagnostic Log and Trace protocol defines
+ * @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_protocol.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$
+ * $LastChangedDate$
+ * $LastChangedBy$
+ Initials Date Comment
+ aw 13.01.2010 initial
+ */
+#ifndef DLT_PROTOCOL_H
+#define DLT_PROTOCOL_H
+
+/**
+ \defgroup protocolapi DLT Protocol API
+ \addtogroup protocolapi
+ \{
+*/
+
+/*
+ * Definitions of the htyp parameter in standard header.
+ */
+#define DLT_HTYP_UEH 0x01 /**< use extended header */
+#define DLT_HTYP_MSBF 0x02 /**< MSB first */
+#define DLT_HTYP_WEID 0x04 /**< with ECU ID */
+#define DLT_HTYP_WSID 0x08 /**< with session ID */
+#define DLT_HTYP_WTMS 0x10 /**< with timestamp */
+#define DLT_HTYP_VERS 0xe0 /**< version number, 0x1 */
+
+#define DLT_IS_HTYP_UEH(htyp) ((htyp) & DLT_HTYP_UEH)
+#define DLT_IS_HTYP_MSBF(htyp) ((htyp) & DLT_HTYP_MSBF)
+#define DLT_IS_HTYP_WEID(htyp) ((htyp) & DLT_HTYP_WEID)
+#define DLT_IS_HTYP_WSID(htyp) ((htyp) & DLT_HTYP_WSID)
+#define DLT_IS_HTYP_WTMS(htyp) ((htyp) & DLT_HTYP_WTMS)
+
+#define DLT_HTYP_PROTOCOL_VERSION1 (1<<5)
+
+/*
+ * Definitions of msin parameter in extended header.
+ */
+#define DLT_MSIN_VERB 0x01 /**< verbose */
+#define DLT_MSIN_MSTP 0x0e /**< message type */
+#define DLT_MSIN_MTIN 0xf0 /**< message type info */
+
+#define DLT_MSIN_MSTP_SHIFT 1 /**< shift right offset to get mstp value */
+#define DLT_MSIN_MTIN_SHIFT 4 /**< shift right offset to get mtin value */
+
+#define DLT_IS_MSIN_VERB(msin) ((msin) & DLT_MSIN_VERB)
+#define DLT_GET_MSIN_MSTP(msin) (((msin) & DLT_MSIN_MSTP) >> DLT_MSIN_MSTP_SHIFT)
+#define DLT_GET_MSIN_MTIN(msin) (((msin) & DLT_MSIN_MTIN) >> DLT_MSIN_MTIN_SHIFT)
+
+/*
+ * Definitions of mstp parameter in extended header.
+ */
+#define DLT_TYPE_LOG 0x00 /**< Log message type */
+#define DLT_TYPE_APP_TRACE 0x01 /**< Application trace message type */
+#define DLT_TYPE_NW_TRACE 0x02 /**< Network trace message type */
+#define DLT_TYPE_CONTROL 0x03 /**< Control message type */
+
+/*
+ * Definitions of msti parameter in extended header.
+ */
+#define DLT_TRACE_VARIABLE 0x01 /**< tracing of a variable */
+#define DLT_TRACE_FUNCTION_IN 0x02 /**< tracing of function calls */
+#define DLT_TRACE_FUNCTION_OUT 0x03 /**< tracing of function return values */
+#define DLT_TRACE_STATE 0x04 /**< tracing of states of a state machine */
+#define DLT_TRACE_VFB 0x05 /**< tracing of virtual function bus */
+
+/*
+ * Definitions of msbi parameter in extended header.
+ */ + +/* see file dlt_user.h */ +
+/*
+ * Definitions of msci parameter in extended header.
+ */
+#define DLT_CONTROL_REQUEST 0x01 /**< Request message */
+#define DLT_CONTROL_RESPONSE 0x02 /**< Response to request message */
+#define DLT_CONTROL_TIME 0x03 /**< keep-alive message */
+
+#define DLT_MSIN_CONTROL_REQUEST ((DLT_TYPE_CONTROL << DLT_MSIN_MSTP_SHIFT) | (DLT_CONTROL_REQUEST << DLT_MSIN_MTIN_SHIFT))
+#define DLT_MSIN_CONTROL_RESPONSE ((DLT_TYPE_CONTROL << DLT_MSIN_MSTP_SHIFT) | (DLT_CONTROL_RESPONSE << DLT_MSIN_MTIN_SHIFT)) +#define DLT_MSIN_CONTROL_TIME ((DLT_TYPE_CONTROL << DLT_MSIN_MSTP_SHIFT) | (DLT_CONTROL_TIME << DLT_MSIN_MTIN_SHIFT))
+
+/*
+ * Definitions of types of arguments in payload.
+ */
+#define DLT_TYPE_INFO_TYLE 0x0000000f /**< Length of standard data: 1 = 8bit, 2 = 16bit, 3 = 32 bit, 4 = 64 bit, 5 = 128 bit */
+#define DLT_TYPE_INFO_BOOL 0x00000010 /**< Boolean data */
+#define DLT_TYPE_INFO_SINT 0x00000020 /**< Signed integer data */
+#define DLT_TYPE_INFO_UINT 0x00000040 /**< Unsigned integer data */
+#define DLT_TYPE_INFO_FLOA 0x00000080 /**< Float data */
+#define DLT_TYPE_INFO_ARAY 0x00000100 /**< Array of standard types */
+#define DLT_TYPE_INFO_STRG 0x00000200 /**< String */
+#define DLT_TYPE_INFO_RAWD 0x00000400 /**< Raw data */
+#define DLT_TYPE_INFO_VARI 0x00000800 /**< Set, if additional information to a variable is available */
+#define DLT_TYPE_INFO_FIXP 0x00001000 /**< Set, if quantization and offset are added */
+#define DLT_TYPE_INFO_TRAI 0x00002000 /**< Set, if additional trace information is added */
+#define DLT_TYPE_INFO_STRU 0x00004000 /**< Struct */
+#define DLT_TYPE_INFO_SCOD 0x00038000 /**< coding of the type string: 0 = ASCII, 1 = UTF-8 */
+
+#define DLT_TYLE_8BIT 1
+#define DLT_TYLE_16BIT 2
+#define DLT_TYLE_32BIT 3
+#define DLT_TYLE_64BIT 4
+#define DLT_TYLE_128BIT 5
+
+#define DLT_SCOD_ASCII 0
+#define DLT_SCOD_UTF8 1
+
+/*
+ * Definitions of DLT services.
+ */
+#define DLT_SERVICE_ID_SET_LOG_LEVEL 0x01 /**< Service ID: Set log level */
+#define DLT_SERVICE_ID_SET_TRACE_STATUS 0x02 /**< Service ID: Set trace status */
+#define DLT_SERVICE_ID_GET_LOG_INFO 0x03 /**< Service ID: Get log info */
+#define DLT_SERVICE_ID_GET_DEFAULT_LOG_LEVEL 0x04 /**< Service ID: Get dafault log level */
+#define DLT_SERVICE_ID_STORE_CONFIG 0x05 /**< Service ID: Store configuration */
+#define DLT_SERVICE_ID_RESET_TO_FACTORY_DEFAULT 0x06 /**< Service ID: Reset to factory defaults */
+#define DLT_SERVICE_ID_SET_COM_INTERFACE_STATUS 0x07 /**< Service ID: Set communication interface status */
+#define DLT_SERVICE_ID_SET_COM_INTERFACE_MAX_BANDWIDTH 0x08 /**< Service ID: Set communication interface maximum bandwidth */
+#define DLT_SERVICE_ID_SET_VERBOSE_MODE 0x09 /**< Service ID: Set verbose mode */
+#define DLT_SERVICE_ID_SET_MESSAGE_FILTERING 0x0A /**< Service ID: Set message filtering */
+#define DLT_SERVICE_ID_SET_TIMING_PACKETS 0x0B /**< Service ID: Set timing packets */
+#define DLT_SERVICE_ID_GET_LOCAL_TIME 0x0C /**< Service ID: Get local time */
+#define DLT_SERVICE_ID_USE_ECU_ID 0x0D /**< Service ID: Use ECU id */
+#define DLT_SERVICE_ID_USE_SESSION_ID 0x0E /**< Service ID: Use session id */
+#define DLT_SERVICE_ID_USE_TIMESTAMP 0x0F /**< Service ID: Use timestamp */
+#define DLT_SERVICE_ID_USE_EXTENDED_HEADER 0x10 /**< Service ID: Use extended header */
+#define DLT_SERVICE_ID_SET_DEFAULT_LOG_LEVEL 0x11 /**< Service ID: Set default log level */
+#define DLT_SERVICE_ID_SET_DEFAULT_TRACE_STATUS 0x12 /**< Service ID: Set default trace status */
+#define DLT_SERVICE_ID_GET_SOFTWARE_VERSION 0x13 /**< Service ID: Get software version */
+#define DLT_SERVICE_ID_MESSAGE_BUFFER_OVERFLOW 0x14 /**< Service ID: Message buffer overflow */
+#define DLT_SERVICE_ID_CALLSW_CINJECTION 0xFFF /**< Service ID: Message Injection (minimal ID) */
+
+/*
+ * Definitions of DLT service response status
+ */
+#define DLT_SERVICE_RESPONSE_OK 0x00 /**< Control message response: OK */
+#define DLT_SERVICE_RESPONSE_NOT_SUPPORTED 0x01 /**< Control message response: Not supported */
+#define DLT_SERVICE_RESPONSE_ERROR 0x02 /**< Control message response: Error */
+
+/**
+ \}
+*/
+
+#endif /* DLT_PROTOCOL_H */
diff --git a/include/dlt/dlt_types.h b/include/dlt/dlt_types.h new file mode 100755 index 0000000..e1372ef --- /dev/null +++ b/include/dlt/dlt_types.h @@ -0,0 +1,97 @@ +/*
+ * Dlt- 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_types.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 ** +*******************************************************************************/ + +#ifndef DLT_TYPES_H +#define DLT_TYPES_H + +#ifdef _MSC_VER
+ typedef __int64 int64_t;
+ typedef __int32 int32_t;
+ typedef __int16 int16_t;
+ typedef __int8 int8_t;
+
+ typedef unsigned __int64 uint64_t;
+ typedef unsigned __int32 uint32_t;
+ typedef unsigned __int16 uint16_t;
+ typedef unsigned __int8 uint8_t;
+
+ typedef int pid_t;
+ typedef unsigned int speed_t;
+ + #define UINT16_MAX 0xFFFF + + #include <varargs.h> +#else +#include <stdint.h> +#endif + +typedef float float32_t; +typedef double float64_t; + +#endif /* DLT_TYPES_H */ diff --git a/include/dlt/dlt_user.h b/include/dlt/dlt_user.h new file mode 100755 index 0000000..a1b6229 --- /dev/null +++ b/include/dlt/dlt_user.h @@ -0,0 +1,542 @@ +/* + * 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_user.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 13.01.2010 initial + */ + +#ifndef DLT_USER_H +#define DLT_USER_H + +/** + \defgroup userapi DLT User API + \addtogroup userapi + \{ +*/ + +#include "dlt_types.h" +#include "dlt_common.h" +#include "dlt_user_macros.h" + +#if !defined (__WIN32__) +#include <semaphore.h> +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Definitions of DLT log level + */ +typedef enum +{ + DLT_LOG_DEFAULT = -1, /**< Default log level */ + DLT_LOG_OFF = 0x00, /**< Log level off */ + DLT_LOG_FATAL = 0x01, /**< fatal system error */ + DLT_LOG_ERROR = 0x02, /**< error with impact to correct functionality */ + DLT_LOG_WARN = 0x03, /**< warning, correct behaviour could not be ensured */ + DLT_LOG_INFO = 0x04, /**< informational */ + DLT_LOG_DEBUG = 0x05, /**< debug */ + DLT_LOG_VERBOSE = 0x06 /**< highest grade of information */ +} DltLogLevelType; + +/** + * Definitions of DLT trace status + */ +typedef enum +{ + DLT_TRACE_STATUS_DEFAULT = -1, /**< Default trace status */ + DLT_TRACE_STATUS_OFF = 0x00, /**< Trace status: Off */ + DLT_TRACE_STATUS_ON = 0x01 /**< Trace status: On */ +} DltTraceStatusType; + +/** + * Definitions for dlt_user_trace_network/DLT_TRACE_NETWORK() + * as defined in the DLT protocol + */ +typedef enum +{ + DLT_NW_TRACE_IPC = 0x01, /**< Interprocess communication */ + DLT_NW_TRACE_CAN = 0x02, /**< Controller Area Network Bus */ + DLT_NW_TRACE_FLEXRAY = 0x03, /**< Flexray Bus */ + DLT_NW_TRACE_MOST = 0x04, /**< Media Oriented System Transport Bus */ + DLT_NW_TRACE_RESERVED0 = 0x05, + DLT_NW_TRACE_RESERVED1 = 0x06, + DLT_NW_TRACE_RESERVED2 = 0x07, + DLT_NW_TRACE_USER_DEFINED0 = 0x08, + DLT_NW_TRACE_USER_DEFINED1 = 0x09, + DLT_NW_TRACE_USER_DEFINED2 = 0x0A, + DLT_NW_TRACE_USER_DEFINED3 = 0x0B, + DLT_NW_TRACE_USER_DEFINED4 = 0x0C, + DLT_NW_TRACE_USER_DEFINED5 = 0x0D, + DLT_NW_TRACE_USER_DEFINED6 = 0x0E, + DLT_NW_TRACE_USER_DEFINED7 = 0x0F +} DltNetworkTraceType; + +#define DLT_USER_BUF_MAX_SIZE 2048 /**< maximum size of each user buffer, also used for injection buffer */ + +/* Use a semaphore or mutex from your OS to prevent concurrent access to the DLT buffer. */ +#define DLT_SEM_LOCK() { sem_wait(&dlt_mutex); } +#define DLT_SEM_FREE() { sem_post(&dlt_mutex); } + +/** + * This structure is used for every context used in an application. + */ +typedef struct +{ + char contextID[4]; /**< context id */ + int32_t log_level_pos; /**< offset in user-application context field */ +} DltContext; + +/** + * This structure is used for context data used in an application. + */ +typedef struct +{ + DltContext *handle; /**< pointer to DltContext */ + unsigned char buffer[DLT_USER_BUF_MAX_SIZE]; /**< buffer for building log message*/ + int32_t size; /**< payload size */ + int32_t log_level; /**< log level */ + int32_t trace_status; /**< trace status */ + int32_t args_num; /**< number of arguments for extended header*/ + uint8_t mcnt; /**< message counter */ + char* context_description; /**< description of context */ +} DltContextData; + +typedef struct +{ + uint32_t service_id; + int (*injection_callback)(uint32_t service_id, void *data, uint32_t length); +} DltUserInjectionCallback; + +/** + * This structure is used in a table managing all contexts and the corresponding log levels in an application. + */ +typedef struct +{ + char contextID[DLT_ID_SIZE]; /**< Context ID */ + int8_t log_level; /**< Log level */ + int8_t trace_status; /**< Trace status */ + char *context_description; /**< description of context */ + DltUserInjectionCallback *injection_table; /**< Table with pointer to injection functions and service ids */ + uint32_t nrcallbacks; +} dlt_ll_ts_type; + +/** + * This structure is used once for one application. + */ +typedef struct +{ + char ecuID[DLT_ID_SIZE]; /**< ECU ID */ + char appID[DLT_ID_SIZE]; /**< Application ID */ + int dlt_log_handle; /**< Handle to fifo of dlt daemon */ + int dlt_user_handle; /**< Handle to own fifo */ + + int8_t dlt_is_file; /**< Target of logging: 1 to file, 0 to daemon */ + + dlt_ll_ts_type *dlt_ll_ts; //[MAX_DLT_LL_TS_ENTRIES]; /**< Internal management struct for all contexts */ + uint32_t dlt_ll_ts_max_num_entries; /**< Maximum number of contexts */ + + uint32_t dlt_ll_ts_num_entries; /**< Number of used contexts */ + + int8_t overflow; /**< Overflow marker, set to 1 on overflow, 0 otherwise */ + + char *application_description; /**< description of application */ + + DltReceiver receiver; /**< Receiver for internal user-defined messages from daemon */ + + int8_t verbose_mode; /**< Verbose mode enabled: 1 enabled, 0 disabled */ + + int8_t enable_local_print; /**< Local printing of log messages: 1 enabled, 0 disabled */ + int8_t local_print_mode; /**< Local print mode, controlled by environment variable */ + + DltRingBuffer rbuf; /**< Ring-buffer for buffering messages during startup and missing connection */ +} DltUser; + +/************************************************************************************************** +* The folowing API functions define a low level function interface for DLT +**************************************************************************************************/ + +/** + * Initialise the generation of a DLT log message (intended for usage in non-verbose mode) + * This function has to be called first, when an application wants to send a new log messages. + * @param handle pointer to an object containing information about one special logging context + * @param log pointer to an object containing information about logging context data + * @param loglevel this is the current log level of the log message to be sent + * @return negative value if there was an error + */ +int dlt_user_log_write_start(DltContext *handle, DltContextData *log, DltLogLevelType loglevel); + +/** + * Initialise the generation of a DLT log message (intended for usage in verbose mode) + * This function has to be called first, when an application wants to send a new log messages. + * @param handle pointer to an object containing information about one special logging context + * @param log pointer to an object containing information about logging context data + * @param loglevel this is the current log level of the log message to be sent + * @param messageid message id of message + * @return negative value if there was an error + */ +int dlt_user_log_write_start_id(DltContext *handle, DltContextData *log, DltLogLevelType loglevel, uint32_t messageid); + +/** + * Finishing the generation of a DLT log message and sending it to the DLT daemon. + * This function has to be called after writing all the log attributes of a log message. + * @param log pointer to an object containing information about logging context data + * @return negative value if there was an error + */ +int dlt_user_log_write_finish(DltContextData *log); + +/** + * Write a boolean parameter into a DLT log message. + * dlt_user_log_write_start has to be called before adding any attributes to the log message. + * Finish sending log message by calling dlt_user_log_write_finish. + * @param log pointer to an object containing information about logging context data + * @param data boolean parameter written into log message (mapped to uint8) + * @return negative value if there was an error + */ +int dlt_user_log_write_bool(DltContextData *log, uint8_t data); + +/** + * Write a float parameter into a DLT log message. + * dlt_user_log_write_start has to be called before adding any attributes to the log message. + * Finish sending log message by calling dlt_user_log_write_finish. + * @param log pointer to an object containing information about logging context data + * @param data float32_t parameter written into log message. + * @return negative value if there was an error + */ +int dlt_user_log_write_float32(DltContextData *log, float32_t data); + +/** + * Write a double parameter into a DLT log message. + * dlt_user_log_write_start has to be called before adding any attributes to the log message. + * Finish sending log message by calling dlt_user_log_write_finish. + * @param log pointer to an object containing information about logging context data + * @param data float64_t parameter written into log message. + * @return negative value if there was an error + */ +int dlt_user_log_write_float64(DltContextData *log, double data); + +/** + * Write a uint parameter into a DLT log message. + * dlt_user_log_write_start has to be called before adding any attributes to the log message. + * Finish sending log message by calling dlt_user_log_write_finish. + * @param log pointer to an object containing information about logging context data + * @param data unsigned int parameter written into log message. + * @return negative value if there was an error + */ +int dlt_user_log_write_uint(DltContextData *log, unsigned int data); +int dlt_user_log_write_uint8(DltContextData *log, uint8_t data); +int dlt_user_log_write_uint16(DltContextData *log, uint16_t data); +int dlt_user_log_write_uint32(DltContextData *log, uint32_t data); +int dlt_user_log_write_uint64(DltContextData *log, uint64_t data); +/** + * Write a int parameter into a DLT log message. + * dlt_user_log_write_start has to be called before adding any attributes to the log message. + * Finish sending log message by calling dlt_user_log_write_finish. + * @param log pointer to an object containing information about logging context data + * @param data int parameter written into log message. + * @return negative value if there was an error + */ +int dlt_user_log_write_int(DltContextData *log, int data); +int dlt_user_log_write_int8(DltContextData *log, int8_t data); +int dlt_user_log_write_int16(DltContextData *log, int16_t data); +int dlt_user_log_write_int32(DltContextData *log, int32_t data); +int dlt_user_log_write_int64(DltContextData *log, int64_t data); +/** + * Write a null terminated ASCII string into a DLT log message. + * dlt_user_log_write_start has to be called before adding any attributes to the log message. + * Finish sending log message by calling dlt_user_log_write_finish. + * @param log pointer to an object containing information about logging context data + * @param text pointer to the parameter written into log message containing null termination. + * @return negative value if there was an error + */ +int dlt_user_log_write_string( DltContextData *log, const char *text); + +/** + * Write a binary memory block into a DLT log message. + * dlt_user_log_write_start has to be called before adding any attributes to the log message. + * Finish sending log message by calling dlt_user_log_write_finish. + * @param log pointer to an object containing information about logging context data + * @param data pointer to the parameter written into log message. + * @param length length in bytes of the parameter written into log message. + * @return negative value if there was an error + */ +int dlt_user_log_write_raw(DltContextData *log,void *data,uint16_t length); + +/** + * Trace network message + * @param handle pointer to an object containing information about one special logging context + * @param nw_trace_type type of network trace (DLT_NW_TRACE_IPC, DLT_NW_TRACE_CAN, DLT_NW_TRACE_FLEXRAY, or DLT_NW_TRACE_MOST) + * @param header_len length of network message header + * @param header pointer to network message header + * @param payload_len length of network message payload + * @param payload pointer to network message payload + * @return negative value if there was an error + */ +int dlt_user_trace_network(DltContext *handle, DltNetworkTraceType nw_trace_type, uint16_t header_len, void *header, uint16_t payload_len, void *payload); + +/************************************************************************************************** +* The folowing API functions define a high level function interface for DLT +**************************************************************************************************/ + +/** + * Initialise the user lib communication with daemon. + * This function has to be called first, before using any DLT user lib functions. + * @return negative value if there was an error + */ +int dlt_init(); + +/** + * Initialise the user lib writing only to file. + * This function has to be called first, before using any DLT user lib functions. + * @param name name of an optional log file + * @return negative value if there was an error + */ +int dlt_init_file(const char *name); + +/** + * Terminate the user lib. + * This function has to be called when finishing using the DLT user lib. + * @return negative value if there was an error + */ +int dlt_free(); + +/** + * Register an application in the daemon. + * @param appid four byte long character array with the application id + * @param description long name of the application + * @return negative value if there was an error + */ +int dlt_register_app(const char *appid, const char * description); + +/** + * Unregister an application in the daemon. + * This function has to be called when finishing using an application. + * @return negative value if there was an error + */ +int dlt_unregister_app(void); + +/** + * Register a context in the daemon. + * This function has to be called before first usage of the context. + * @param handle pointer to an object containing information about one special logging context + * @param contextid four byte long character array with the context id + * @param description long name of the context + * @return negative value if there was an error + */ +int dlt_register_context(DltContext *handle, const char *contextid, const char * description); + +/** + * Register a context in the daemon with pre-defined log level and pre-defined trace status. + * This function has to be called before first usage of the context. + * @param handle pointer to an object containing information about one special logging context + * @param contextid four byte long character array with the context id + * @param description long name of the context + * @param loglevel This is the log level to be pre-set for this context + (DLT_LOG_DEFAULT is not allowed here) + * @param tracestatus This is the trace status to be pre-set for this context + (DLT_TRACE_STATUS_DEFAULT is not allowed here) + * @return negative value if there was an error + */ +int dlt_register_context_ll_ts(DltContext *handle, const char *contextid, const char * description, int loglevel, int tracestatus); + +/** + * Unregister a context in the DLT daemon. + * This function has to be called when finishing using a context. + * @param handle pointer to an object containing information about one special logging context + * @return negative value if there was an error + */ +int dlt_unregister_context(DltContext *handle); + +/** + * Register callback function called when injection message was received + * @param handle pointer to an object containing information about one special logging context + * @param service_id the service id to be waited for + * @param (*dlt_injection_callback) function pointer to callback function + * @return negative value if there was an error + */ +int dlt_register_injection_callback(DltContext *handle, uint32_t service_id, + int (*dlt_injection_callback)(uint32_t service_id, void *data, uint32_t length)); + +/** + * Switch to verbose mode + * + */ +int dlt_verbose_mode(void); + +/** + * Switch to non-verbose mode + * + */ +int dlt_nonverbose_mode(void); + +/** + * Set maximum logged log level and trace status of application + * + * @param loglevel This is the log level to be set for the whole application + * @param tracestatus This is the trace status to be set for the whole application + * @return negative value if there was an error + */ +int dlt_set_application_ll_ts_limit(DltLogLevelType loglevel, DltTraceStatusType tracestatus); + +/** + * Enable local printing of messages + * + */ +int dlt_enable_local_print(void); + +/** + * Disable local printing of messages + * + */ +int dlt_disable_local_print(void); + +/** + * Write a null terminated ASCII string into a DLT log message. + * @param handle pointer to an object containing information about one special logging context + * @param loglevel this is the current log level of the log message to be sent + * @param text pointer to the ASCII string written into log message containing null termination. + * @return negative value if there was an error + */ +int dlt_log_string(DltContext *handle,DltLogLevelType loglevel, const char *text); + +/** + * Write a null terminated ASCII string and an integer value into a DLT log message. + * @param handle pointer to an object containing information about one special logging context + * @param loglevel this is the current log level of the log message to be sent + * @param text pointer to the ASCII string written into log message containing null termination. + * @param data integer value written into the log message + * @return negative value if there was an error + */ +int dlt_log_string_int(DltContext *handle,DltLogLevelType loglevel, const char *text, int data); + +/** + * Write a null terminated ASCII string and an unsigned integer value into a DLT log message. + * @param handle pointer to an object containing information about one special logging context + * @param loglevel this is the current log level of the log message to be sent + * @param text pointer to the ASCII string written into log message containing null termination. + * @param data unsigned integer value written into the log message + * @return negative value if there was an error + */ +int dlt_log_string_uint(DltContext *handle,DltLogLevelType loglevel, const char *text, unsigned int data); + +/** + * Write an integer value into a DLT log message. + * @param handle pointer to an object containing information about one special logging context + * @param loglevel this is the current log level of the log message to be sent + * @param data integer value written into the log message + * @return negative value if there was an error + */ +int dlt_log_int(DltContext *handle,DltLogLevelType loglevel, int data); + +/** + * Write an unsigned integer value into a DLT log message. + * @param handle pointer to an object containing information about one special logging context + * @param loglevel this is the current log level of the log message to be sent + * @param data unsigned integer value written into the log message + * @return negative value if there was an error + */ +int dlt_log_uint(DltContext *handle,DltLogLevelType loglevel, unsigned int data); + +/** + * Write an unsigned integer value into a DLT log message. + * @param handle pointer to an object containing information about one special logging context + * @param loglevel this is the current log level of the log message to be sent + * @param data pointer to the parameter written into log message. + * @param length length in bytes of the parameter written into log message. + * @return negative value if there was an error + */ +int dlt_log_raw(DltContext *handle,DltLogLevelType loglevel, void *data,uint16_t length); + +/** + * Forward a complete DLT message to the DLT daemon + * @param msgdata Message data of DLT message + * @param size Size of DLT message + * @return negative value if there was an error + */ +int dlt_forward_msg(void *msgdata,size_t size); + +#ifdef __cplusplus +} +#endif + +/** + \} +*/ + +#endif /* DLT_USER_H */ diff --git a/include/dlt/dlt_user_macros.h b/include/dlt/dlt_user_macros.h new file mode 100755 index 0000000..78ef66d --- /dev/null +++ b/include/dlt/dlt_user_macros.h @@ -0,0 +1,414 @@ +/* + * 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_user_macros.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: 1515 $ + * $LastChangedDate: 2010-12-13 09:18:54 +0100 (Mon, 13 Dec 2010) $ + * $LastChangedBy$ + Initials Date Comment + aw 13.01.2010 initial + */ + +#ifndef DLT_USER_MACROS_H +#define DLT_USER_MACORS_H + +/** + \defgroup userapi DLT User API + \addtogroup userapi + \{ +*/ + +/************************************************************************************************** +* The folowing macros define a macro interface for DLT +**************************************************************************************************/ + +/** + * Create an object for a new context. + * This macro has to be called first for every. + * @param CONTEXT object containing information about one special logging context + */ +#define DLT_DECLARE_CONTEXT(CONTEXT) \ +DltContext CONTEXT; + +/** + * Use an object of a new context created in another module. + * This macro has to be called first for every. + * @param CONTEXT object containing information about one special logging context + */ +#define DLT_IMPORT_CONTEXT(CONTEXT) \ +extern DltContext CONTEXT; + +/** + * Register application. + * @param APPID application id with maximal four characters + * @param DESCRIPTION ASCII string containing description + */ +#define DLT_REGISTER_APP(APPID,DESCRIPTION) \ + dlt_register_app( APPID, DESCRIPTION); + +/** + * Unregister application. + */ +#define DLT_UNREGISTER_APP() \ + dlt_unregister_app(); + +/** + * Register context (with default log level and default trace status) + * @param CONTEXT object containing information about one special logging context + * @param CONTEXTID context id with maximal four characters + * @param DESCRIPTION ASCII string containing description + */ +#define DLT_REGISTER_CONTEXT(CONTEXT,CONTEXTID,DESCRIPTION) \ + dlt_register_context(&(CONTEXT), CONTEXTID, DESCRIPTION); + +/** + * Register context with pre-defined log level and pre-defined trace status. + * @param CONTEXT object containing information about one special logging context + * @param CONTEXTID context id with maximal four characters + * @param DESCRIPTION ASCII string containing description + * @param LOGLEVEL log level to be pre-set for this context + (DLT_LOG_DEFAULT is not allowed here) + * @param TRACESTATUS trace status to be pre-set for this context + (DLT_TRACE_STATUS_DEFAULT is not allowed here) + */ +#define DLT_REGISTER_CONTEXT_LL_TS(CONTEXT,CONTEXTID,DESCRIPTION,LOGLEVEL,TRACESTATUS) \ + dlt_register_context_ll_ts(&(CONTEXT), CONTEXTID, DESCRIPTION, LOGLEVEL, TRACESTATUS); + +/** + * Unregister context. + * @param CONTEXT object containing information about one special logging context + */ +#define DLT_UNREGISTER_CONTEXT(CONTEXT) \ + dlt_unregister_context(&(CONTEXT)); + +/** + * Register callback function called when injection message was received + * @param CONTEXT object containing information about one special logging context + * @param SERVICEID service id of the injection message + * @param CALLBACK function pointer to callback function + */ +#define DLT_REGISTER_INJECTION_CALLBACK(CONTEXT, SERVICEID, CALLBACK) \ + dlt_register_injection_callback(&(CONTEXT),SERVICEID, CALLBACK); + +/** + * Send log message with variable list of messages (intended for verbose mode) + * @param CONTEXT object containing information about one special logging context + * @param LOGLEVEL the log level of the log message + * @param ARGS variable list of arguments + */ +#ifdef _MSC_VER + /* DLT_LOG is not supported by MS Visual C++ */ + /* use function interface instead */ +#else +#define DLT_LOG(CONTEXT,LOGLEVEL,ARGS...) \ + { \ + DltContextData log; \ + if (dlt_user_log_write_start(&CONTEXT,&log,LOGLEVEL)) \ + { \ + ARGS; \ + dlt_user_log_write_finish(&log); \ + } \ + } +#endif + +/** + * Send log message with variable list of messages (intended for non-verbose mode) + * @param CONTEXT object containing information about one special logging context + * @param LOGLEVEL the log level of the log message + * @param MSGID the message id of log message + * @param ARGS variable list of arguments: + calls to DLT_STRING(), DLT_BOOL(), DLT_FLOAT32(), DLT_FLOAT64(), + DLT_INT(), DLT_UINT(), DLT_RAW() + */ +#ifdef _MSC_VER + /* DLT_LOG_ID is not supported by MS Visual C++ */ + /* use function interface instead */ +#else +#define DLT_LOG_ID(CONTEXT,LOGLEVEL,MSGID,ARGS...) \ + { \ + DltContextData log; \ + if (dlt_user_log_write_start_id(&CONTEXT,&log,LOGLEVEL,MSGID)) \ + { \ + ARGS; \ + dlt_user_log_write_finish(&log); \ + } \ + } +#endif + +/** + * Add string parameter to the log messsage. + * @param TEXT ASCII string + */ +#define DLT_STRING(TEXT) ({ \ + dlt_user_log_write_string(&log,TEXT); \ + }) + +/** + * Add boolean parameter to the log messsage. + * @param BOOL_VAR Boolean value (mapped to uint8) + */ +#define DLT_BOOL(BOOL_VAR) ({ \ + dlt_user_log_write_bool(&log,BOOL_VAR); \ + }) + +/** + * Add float32 parameter to the log messsage. + * @param FLOAT32_VAR Float32 value (mapped to float) + */ +#define DLT_FLOAT32(FLOAT32_VAR) ({ \ + dlt_user_log_write_float32(&log,FLOAT32_VAR); \ + }) + +/** + * Add float64 parameter to the log messsage. + * @param FLOAT64_VAR Float64 value (mapped to double) + */ +#define DLT_FLOAT64(FLOAT64_VAR) ({ \ + dlt_user_log_write_float64(&log,FLOAT64_VAR); \ + }) + +/** + * Add integer parameter to the log messsage. + * @param INT_VAR integer value + */ +#define DLT_INT(INT_VAR) ({ \ + dlt_user_log_write_int(&log,INT_VAR); \ + }) +#define DLT_INT8(INT_VAR) ({ \ + dlt_user_log_write_int8(&log,INT_VAR); \ + }) +#define DLT_INT16(INT_VAR) ({ \ + dlt_user_log_write_int16(&log,INT_VAR); \ + }) +#define DLT_INT32(INT_VAR) ({ \ + dlt_user_log_write_int32(&log,INT_VAR); \ + }) +#define DLT_INT64(INT_VAR) ({ \ + dlt_user_log_write_int64(&log,INT_VAR); \ + }) + +/** + * Add unsigned integer parameter to the log messsage. + * @param UINT_VAR unsigned integer value + */ +#define DLT_UINT(UINT_VAR) ({ \ + dlt_user_log_write_uint(&log,UINT_VAR); \ + }) +#define DLT_UINT8(UINT_VAR) ({ \ + dlt_user_log_write_uint8(&log,UINT_VAR); \ + }) +#define DLT_UINT16(UINT_VAR) ({ \ + dlt_user_log_write_uint16(&log,UINT_VAR); \ + }) +#define DLT_UINT32(UINT_VAR) ({ \ + dlt_user_log_write_uint32(&log,UINT_VAR); \ + }) +#define DLT_UINT64(UINT_VAR) ({ \ + dlt_user_log_write_uint64(&log,UINT_VAR); \ + }) + +/** + * Add binary memory block to the log messages. + * @param BUF pointer to memory block + * @param LEN length of memory block + */ +#define DLT_RAW(BUF,LEN) ({ \ + dlt_user_log_write_raw(&log,BUF,LEN); \ + }) + +/** + * Trace network message + * @param CONTEXT object containing information about one special logging context + * @param TYPE type of network trace message + * @param HEADERLEN length of network message header + * @param HEADER pointer to network message header + * @param PAYLOADLEN length of network message payload + * @param PAYLOAD pointer to network message payload + */ +#define DLT_TRACE_NETWORK(CONTEXT,TYPE,HEADERLEN,HEADER,PAYLOADLEN,PAYLOAD) \ + { \ + dlt_user_trace_network(&(CONTEXT),TYPE,HEADERLEN,HEADER,PAYLOADLEN,PAYLOAD); \ + } + +/** + * Send log message with string parameter. + * @param CONTEXT object containing information about one special logging context + * @param LOGLEVEL the log level of the log message + * @param TEXT ASCII string + */ +#define DLT_LOG_STRING(CONTEXT,LOGLEVEL,TEXT) \ + { \ + dlt_log_string(&(CONTEXT), LOGLEVEL, TEXT); \ + } + + +/** + * Send log message with string parameter and integer parameter. + * @param CONTEXT object containing information about one special logging context + * @param LOGLEVEL the log level of the log messages + * @param TEXT ASCII string + * @param INT_VAR integer value + */ +#define DLT_LOG_STRING_INT(CONTEXT,LOGLEVEL,TEXT,INT_VAR) \ + { \ + dlt_log_string_int(&(CONTEXT), LOGLEVEL, TEXT, INT_VAR); \ + } + +/** + * Send log message with string parameter and unsigned integer parameter. + * @param CONTEXT object containing information about one special logging context + * @param LOGLEVEL the log level of the log message + * @param TEXT ASCII string + * @param UINT_VAR unsigned integer value + */ +#define DLT_LOG_STRING_UINT(CONTEXT,LOGLEVEL,TEXT,UINT_VAR) \ + { \ + dlt_log_string_uint(&(CONTEXT),LOGLEVEL,TEXT,UINT_VAR); \ + } + +/** + * Send log message with unsigned integer parameter. + * @param CONTEXT object containing information about one special logging context + * @param LOGLEVEL the log level of the log message + * @param UINT_VAR unsigned integer value + */ +#define DLT_LOG_UINT(CONTEXT,LOGLEVEL,UINT_VAR) \ + { \ + dlt_log_uint(&(CONTEXT),LOGLEVEL,UINT_VAR); \ + } + +/** + * Send log message with integer parameter. + * @param CONTEXT object containing information about one special logging context + * @param LOGLEVEL the log level of the log message + * @param INT_VAR integer value + */ +#define DLT_LOG_INT(CONTEXT,LOGLEVEL,INT_VAR) \ + { \ + dlt_log_int(&(CONTEXT),LOGLEVEL,INT_VAR); \ + } + +/** + * Send log message with binary memory block. + * @param CONTEXT object containing information about one special logging context + * @param LOGLEVEL the log level of the log message + * @param BUF pointer to memory block + * @param LEN length of memory block + */ +#define DLT_LOG_RAW(CONTEXT,LOGLEVEL,BUF,LEN) \ + { \ + dlt_log_raw(&(CONTEXT),LOGLEVEL,BUF,LEN); \ + } + +/** + * Switch to verbose mode + * + */ +#define DLT_VERBOSE_MODE() \ + dlt_verbose_mode(); + +/** + * Switch to non-verbose mode + * + */ +#define DLT_NONVERBOSE_MODE() \ + dlt_nonverbose_mode(); + +/** + * Set maximum logged log level and trace status of application + * + * @param LOGLEVEL This is the log level to be set for the whole application + * @param TRACESTATUS This is the trace status to be set for the whole application + */ +#define DLT_SET_APPLICATION_LL_TS_LIMIT(LOGLEVEL, TRACESTATUS) \ + dlt_set_application_ll_ts_limit(LOGLEVEL, TRACESTATUS); + +/** + * Enable local printing of messages + * + */ +#define DLT_ENABLE_LOCAL_PRINT() \ + dlt_enable_local_print(); + +/** + * Disable local printing of messages + * + */ +#define DLT_DISABLE_LOCAL_PRINT() \ + dlt_disable_local_print(); + +/** + \} +*/ + +#endif /* DLT_USER_MACROS_H */ 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>
diff --git a/svnversion.h.cmake b/svnversion.h.cmake new file mode 100755 index 0000000..d95074f --- /dev/null +++ b/svnversion.h.cmake @@ -0,0 +1,2 @@ +/* DO NOT EDIT! GENERATED AUTOMATICALLY! */ +#define SVN_VERSION "@PRINT_VERSION_REVISION@" diff --git a/systemd/dlt.service b/systemd/dlt.service new file mode 100755 index 0000000..5bee126 --- /dev/null +++ b/systemd/dlt.service @@ -0,0 +1,16 @@ +# This file is for starting the dlt-daemon as a service with systemd at the multi-user.target +# +# For more informations about starting options of dlt-daemon use the command +# "dlt-daemon -h". +# +# Multi-user.target is a special target unit for setting up a multi-user system (non-graphical). +# For more details about the multi-user.target see systemd.special(7). +[Unit] +Description=DLT Daemon for logging and tracing + +[Service] +ExecStart=/usr/local/bin/dlt-daemon -r +#Restart=always + +[Install] +WantedBy=multi-user.target
\ No newline at end of file diff --git a/testscripts/CMakeLists.txt b/testscripts/CMakeLists.txt new file mode 100755 index 0000000..28e75f7 --- /dev/null +++ b/testscripts/CMakeLists.txt @@ -0,0 +1,40 @@ +####### +# 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@ +######## + +install(PROGRAMS dltdaemon dltinfo.sh + DESTINATION bin + COMPONENT base) diff --git a/testscripts/dltdaemon b/testscripts/dltdaemon new file mode 100755 index 0000000..baf3b8e --- /dev/null +++ b/testscripts/dltdaemon @@ -0,0 +1,64 @@ +#!/bin/sh +# +# Starts the DLT Daemon +# +# chkconfig: 2345 21 87 +# description: Provides DLT Debug Logging & Trace functionality +# processname: dlt-daemon + +# Source function library. +. /etc/rc.d/init.d/functions + + +processname=dlt-daemon +processpath=/usr/bin +servicename=dlt-daemon + + +[ -x $processpath ] || exit 0 + +start() { + echo -n $"Starting $processname daemon: " + /usr/bin/dlt-daemon -d +} + +stop() { + echo -n $"Stopping $processname daemon: " + killproc $servicename -TERM + RETVAL=$? + echo + [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/$servicename +} + +RETVAL=0 + +case "$1" in + start) + start + ;; + stop) + stop + ;; + restart) + stop + start + ;; + condrestart) + if [ -f /var/lock/subsys/$servicename ]; then + stop + start + fi + ;; + reload) + restart + ;; + status) + status $processname + RETVAL=$? + ;; + *) + echo $"Usage: $0 {start|stop|status|restart|condrestart|reload}" + ;; +esac + +exit $RETVAL diff --git a/testscripts/dltinfo.sh b/testscripts/dltinfo.sh new file mode 100755 index 0000000..3e70ab5 --- /dev/null +++ b/testscripts/dltinfo.sh @@ -0,0 +1,24 @@ +#!/bin/sh +clear +processname="dlt-daemon" +pidofdlt=`pidof $processname` + +if [ $pidofdlt ] + then + echo "DLT Deamon is running with PID:$pidofdlt" + else + echo "DLT Daemon is NOT running" +fi + +if [ -f /var/log/messages ] + then +echo "------- messages ----------------" +cat /var/log/messages | grep -a DLT | tail +fi + +if [ -f /var/log/syslog ] + then + echo "------- SYSLOG -------------------" + cat /var/log/syslog | grep -a DLT | tail +fi + diff --git a/transform_spec_file.py b/transform_spec_file.py new file mode 100755 index 0000000..b474e6b --- /dev/null +++ b/transform_spec_file.py @@ -0,0 +1,11 @@ +import sys +from Cheetah.Template import Template + +output = sys.argv[2] +args = {} +for arg in sys.argv[3:]: + key, value = arg.split('=') + args[key] = value +t = Template(file=sys.argv[1], searchList=[args]) +with open(output, 'w') as f: + f.write(str(t)) diff --git a/version.h b/version.h new file mode 100755 index 0000000..776199f --- /dev/null +++ b/version.h @@ -0,0 +1,7 @@ +#ifndef __VERSION_H_ +#define __VERSION_H_ + +#define PACKAGE_VERSION_STATE "" +#define PACKAGE_VERSION "2.2.0" + +#endif diff --git a/version.h.cmake b/version.h.cmake new file mode 100755 index 0000000..d4fea8a --- /dev/null +++ b/version.h.cmake @@ -0,0 +1,7 @@ +#ifndef __VERSION_H_ +#define __VERSION_H_ + +#define PACKAGE_VERSION_STATE "@PRINT_VERSION_STATE@" +#define PACKAGE_VERSION "@PRINT_VERSION@" + +#endif |