summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Koch <mkoch@de.adit-jv.com>2020-01-07 11:22:30 +0100
committerMartin Koch <mkoch@de.adit-jv.com>2020-01-14 15:24:07 +0100
commit06bbfdafdef58891799c70d115c82a670488b09b (patch)
tree02666b7759b8b52d75255477d28cfaec52286ffc
parentce501a931e9eeb20013406373156bf70fb007cda (diff)
downloadaudiomanager-06bbfdafdef58891799c70d115c82a670488b09b.tar.gz
AM-Utils: Introduce new logging architecture, providing separate classes for each logging channel (DLT, file or stdout) and a channel-independent wrapper class. (first preparation step of AM for build without strong dependency to DLT library)
Signed-off-by: Martin Koch <mkoch@de.adit-jv.com>
-rw-r--r--AudioManagerUtilities/CMakeLists.txt7
-rwxr-xr-xAudioManagerUtilities/include/CAmLogWrapper.h128
-rwxr-xr-xAudioManagerUtilities/include/CAmLoggerDlt.h90
-rwxr-xr-xAudioManagerUtilities/include/CAmLoggerFile.h105
-rwxr-xr-xAudioManagerUtilities/include/CAmLoggerStdOut.h113
-rwxr-xr-xAudioManagerUtilities/include/CAmTimeUtility.h45
-rwxr-xr-xAudioManagerUtilities/include/IAmLogger.h342
-rwxr-xr-xAudioManagerUtilities/src/CAmLogWrapper.cpp125
-rwxr-xr-xAudioManagerUtilities/src/CAmLoggerDlt.cpp223
-rwxr-xr-xAudioManagerUtilities/src/CAmLoggerFile.cpp252
-rwxr-xr-xAudioManagerUtilities/src/CAmLoggerStdOut.cpp264
-rw-r--r--Foo/uncrustify_files.cfg10
12 files changed, 1704 insertions, 0 deletions
diff --git a/AudioManagerUtilities/CMakeLists.txt b/AudioManagerUtilities/CMakeLists.txt
index 7c502c5..51b5d74 100644
--- a/AudioManagerUtilities/CMakeLists.txt
+++ b/AudioManagerUtilities/CMakeLists.txt
@@ -40,6 +40,9 @@ ENDIF (WITH_SHARED_UTILITIES)
SET(AUDIO_MANAGER_UTILITIES_SRCS_CXX
src/CAmCommandLineSingleton.cpp
src/CAmDltWrapper.cpp
+ src/CAmLogWrapper.cpp
+ src/CAmLoggerFile.cpp
+ src/CAmLoggerStdOut.cpp
src/CAmSocketHandler.cpp)
if(WITH_SYSTEMD_WATCHDOG)
@@ -109,6 +112,10 @@ ENDIF (WITH_CAPI_WRAPPER)
IF (WITH_DLT)
pkg_check_modules(DLT REQUIRED "automotive-dlt >= 2.2.0")
+ SET(AUDIO_MANAGER_UTILITIES_SRCS_CXX
+ ${AUDIO_MANAGER_UTILITIES_SRCS_CXX}
+ src/CAmLoggerDlt.cpp)
+
add_definitions(${DLT_CFLAGS_OTHER})
set(AUDIO_MANAGER_UTILITIES_LIBS
diff --git a/AudioManagerUtilities/include/CAmLogWrapper.h b/AudioManagerUtilities/include/CAmLogWrapper.h
new file mode 100755
index 0000000..224c3ac
--- /dev/null
+++ b/AudioManagerUtilities/include/CAmLogWrapper.h
@@ -0,0 +1,128 @@
+/**
+ * SPDX license identifier: MPL-2.0
+ *
+ * Copyright (C) 2017, ADIT GmbH
+ *
+ * \author Mattia Guerra, mguerra@de.adit-jv.com ADIT 2017
+ * \author Jens Lorenz, jlorenz@de.adit-jv.com ADIT 2017
+ *
+ * \copyright
+ * This Source Code Form is subject to the terms of the
+ * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with
+ * this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * \file CAmLogWrapper.h
+ * For further information see http://www.genivi.org/.
+ */
+
+#ifndef LOGWRAPPER_H_
+#define LOGWRAPPER_H_
+
+#include <audiomanagerconfig.h>
+#include "pthread.h"
+#include "IAmLogger.h"
+#include "audiomanagertypes.h"
+
+namespace am
+{
+/**
+ * This class is instantiated as a singleton and offers logging to a default context (maincontext).
+ * Logging under the default context can simply be done with the logDebug/logInfo/logError/logWarning/logVerbose
+ * templates. For logging with a different context, you need to register a context with registerContext,
+ * method provided by backends implementing the IAmLogger interface. registerContext returns a logging context.
+ * To import this context into other classes use importContext, method provided by backends implementing the IAmLogger
+ * interface. To access the IAmLogger interface, simply ask CAmLogWrapper::instance().
+ */
+class CAmLogWrapper
+{
+public:
+ static IAmLogger *instantiateOnce(const char *appid, const char *description,
+ const am_LogStatus_e logStatus = LS_ON, const am_LogService_e logService = DEFAULT_LOG_SERVICE,
+ const std::string Filename = "", bool onlyError = false);
+ static IAmLogger *instance(const am_LogService_e logservice = DEFAULT_LOG_SERVICE);
+
+ inline static am_LogService_e getLogService()
+ {
+ return mLogService;
+ }
+
+ virtual ~CAmLogWrapper();
+
+private:
+ CAmLogWrapper(void); //!< is private because of singleton pattern
+ static IAmLogger *mpLogger; //!< pointer to the logger instance
+ static std::string mAppId;
+ static std::string mDescription;
+ static am_LogStatus_e mLogStatus;
+ static am_LogService_e mLogService;
+ static std::string mFilename;
+ static bool mOnlyError;
+};
+
+/**
+ * returns the instance of instantiated IAmLogger
+ * @return
+ */
+inline IAmLogger *getLogger()
+{
+ return (CAmLogWrapper::instance(CAmLogWrapper::getLogService()));
+}
+
+/**
+ * logs given values with debuglevel with the default context
+ * @param value
+ * @param ...
+ */
+template<typename T, typename... TArgs>
+void logDebug(const T &value, const TArgs & ... args)
+{
+ getLogger()->logToDefaultContext(LL_DEBUG, value, args...);
+}
+
+/**
+ * logs given values with infolevel with the default context
+ * @param value
+ * @param ...
+ */
+template<typename T, typename... TArgs>
+void logInfo(const T &value, const TArgs & ... args)
+{
+ getLogger()->logToDefaultContext(LL_INFO, value, args...);
+}
+
+/**
+ * logs given values with errorlevel with the default context
+ * @param value
+ * @param ...
+ */
+template<typename T, typename... TArgs>
+void logError(const T &value, const TArgs & ... args)
+{
+ getLogger()->logToDefaultContext(LL_ERROR, value, args...);
+}
+
+/**
+ * logs given values with warninglevel with the default context
+ * @param value
+ * @param ...
+ */
+template<typename T, typename... TArgs>
+void logWarning(const T &value, const TArgs & ... args)
+{
+ getLogger()->logToDefaultContext(LL_WARN, value, args...);
+}
+
+/**
+ * logs given values with verboselevel with the default context
+ * @param value
+ * @param ...
+ */
+template<typename T, typename... TArgs>
+void logVerbose(const T &value, const TArgs & ... args)
+{
+ getLogger()->logToDefaultContext(LL_VERBOSE, value, args...);
+}
+
+}
+
+#endif /* LOGWRAPPER_H_ */
diff --git a/AudioManagerUtilities/include/CAmLoggerDlt.h b/AudioManagerUtilities/include/CAmLoggerDlt.h
new file mode 100755
index 0000000..5af0aad
--- /dev/null
+++ b/AudioManagerUtilities/include/CAmLoggerDlt.h
@@ -0,0 +1,90 @@
+/**
+ * SPDX license identifier: MPL-2.0
+ *
+ * Copyright (C) 2017, ADIT GmbH
+ *
+ * This file is part of GENIVI Project AudioManager.
+ *
+ * Contributions are licensed to the GENIVI Alliance under one or more
+ * Contribution License Agreements.
+ *
+ * \copyright
+ * This Source Code Form is subject to the terms of the
+ * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with
+ * this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * \file CAmLoggerDlt.h
+ * For further information see http://www.genivi.org/.
+ */
+
+#ifndef LOGGERDLT_H_
+#define LOGGERDLT_H_
+
+#include "IAmLogger.h"
+#include <dlt/dlt.h>
+#include <map>
+#include <string>
+#include <string.h>
+#include <vector>
+
+namespace am
+{
+
+class CAmLogContextDlt : public IAmLogContext
+{
+public:
+ CAmLogContextDlt(const char *id);
+ virtual ~CAmLogContextDlt() {}
+ DltContext *getHandle();
+
+private:
+ /* IAmLogContext */
+ bool configure(const am_LogLevel_e loglevel) override;
+ void send() override;
+ void append(const int8_t value) override;
+ void append(const uint8_t value) override;
+ void append(const int16_t value) override;
+ void append(const uint16_t value) override;
+ void append(const int32_t value) override;
+ void append(const uint32_t value) override;
+ void append(const uint64_t value) override;
+ void append(const int64_t value) override;
+ void append(const bool value) override;
+ void append(const std::vector<uint8_t> &data) override;
+ void append(const char *value) override;
+
+ template<class T>
+ void append(T value);
+
+ bool checkLogLevel(const am_LogLevel_e logLevel) override;
+
+private:
+ const char *mId;
+ DltContext mDltContext;
+ DltContextData mDltContextData;
+};
+
+class CAmLoggerDlt : public IAmLogger
+{
+public:
+ ~CAmLoggerDlt();
+
+ /* IAmLogger */
+ void registerApp(const char *appid, const char *description) override;
+ void unregisterApp() override;
+ IAmLogContext &registerContext(const char *contextid, const char *description) override;
+ IAmLogContext &registerContext(const char *contextid, const char *description,
+ const am_LogLevel_e level, const am_LogStatus_e status) override;
+ IAmLogContext &importContext(const char *contextid = NULL) override;
+ void unregisterContext(const char *contextid) override;
+
+private:
+ CAmLogContextDlt &createContext(const char *contextid);
+
+private:
+ std::map<const char *, CAmLogContextDlt *> mCtxTable;
+};
+
+}
+
+#endif /* LOGGERDLT_H_ */
diff --git a/AudioManagerUtilities/include/CAmLoggerFile.h b/AudioManagerUtilities/include/CAmLoggerFile.h
new file mode 100755
index 0000000..de09a63
--- /dev/null
+++ b/AudioManagerUtilities/include/CAmLoggerFile.h
@@ -0,0 +1,105 @@
+/**
+ * SPDX license identifier: MPL-2.0
+ *
+ * Copyright (C) 2017, ADIT GmbH
+ *
+ * This file is part of GENIVI Project AudioManager.
+ *
+ * Contributions are licensed to the GENIVI Alliance under one or more
+ * Contribution License Agreements.
+ *
+ * \copyright
+ * This Source Code Form is subject to the terms of the
+ * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with
+ * this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * \file CAmLoggerFile.h
+ * For further information see http://www.genivi.org/.
+ */
+
+#ifndef LOGGERFILE_H_
+#define LOGGERFILE_H_
+
+#include "IAmLogger.h"
+#include <map>
+#include <string>
+#include <string.h>
+#include <fstream>
+
+namespace am
+{
+
+class CFileHeader
+{
+public:
+ CFileHeader(const char *ctx = "LOG")
+ : mCtx(ctx) {}
+ friend std ::ostream &operator <<(std::ostream &out, const CFileHeader &h);
+
+ const char *mCtx;
+};
+
+class CAmLogContextFile : public IAmLogContext
+{
+public:
+ CAmLogContextFile(const char *id, const am_LogLevel_e level, const am_LogStatus_e status, std::ofstream &filestream);
+ virtual ~CAmLogContextFile() {}
+
+ /* IAmLogContext */
+ bool checkLogLevel(const am_LogLevel_e logLevel) override;
+
+private:
+ /* IAmLogContext */
+ bool configure(const am_LogLevel_e loglevel) override;
+ void send() override;
+ void append(const int8_t value) override;
+ void append(const uint8_t value) override;
+ void append(const int16_t value) override;
+ void append(const uint16_t value) override;
+ void append(const int32_t value) override;
+ void append(const uint32_t value) override;
+ void append(const uint64_t value) override;
+ void append(const int64_t value) override;
+ void append(const bool value) override;
+ void append(const std::vector<uint8_t> &data) override;
+ void append(const char *value) override;
+
+ template<class T>
+ void appendFile(T value);
+
+private:
+ CFileHeader mHeader;
+ am_LogLevel_e mLogLevel;
+ am_LogStatus_e mLogStatus;
+ std::ofstream &mFilestream;
+};
+
+class CAmLoggerFile : public IAmLogger
+{
+public:
+ CAmLoggerFile(const am_LogStatus_e status, const bool onlyError = false, const std::string &filename = "");
+ ~CAmLoggerFile();
+
+ /* IAmLogger */
+ void registerApp(const char *appid, const char *description) override;
+ void unregisterApp() override;
+ IAmLogContext &registerContext(const char *contextid, const char *description) override;
+ IAmLogContext &registerContext(const char *contextid, const char *description,
+ const am_LogLevel_e level, const am_LogStatus_e status) override;
+ IAmLogContext &importContext(const char *contextid = NULL) override;
+ void unregisterContext(const char *contextid) override;
+
+private:
+ void print(std::string str);
+
+private:
+ CFileHeader mHeader;
+ const am_LogStatus_e mLogStatus;
+ const am_LogLevel_e mStandardLogLevel;
+ std::ofstream mFilestream;
+ std::map<const char *, CAmLogContextFile *> mCtxTable;
+};
+
+}
+
+#endif /* LOGGERFILE_H_ */
diff --git a/AudioManagerUtilities/include/CAmLoggerStdOut.h b/AudioManagerUtilities/include/CAmLoggerStdOut.h
new file mode 100755
index 0000000..3821aba
--- /dev/null
+++ b/AudioManagerUtilities/include/CAmLoggerStdOut.h
@@ -0,0 +1,113 @@
+/**
+ * SPDX license identifier: MPL-2.0
+ *
+ * Copyright (C) 2015, ADIT GmbH
+ *
+ * This file is part of GENIVI Project AudioManager.
+ *
+ * Contributions are licensed to the GENIVI Alliance under one or more
+ * Contribution License Agreements.
+ *
+ * \copyright
+ * This Source Code Form is subject to the terms of the
+ * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with
+ * this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * \file CAmLoggerStdOut.h
+ * For further information see http://www.genivi.org/.
+ */
+
+#ifndef LOGGERSTDOUT_H_
+#define LOGGERSTDOUT_H_
+
+#include "IAmLogger.h"
+#include <map>
+#include <string>
+#include <string.h>
+
+namespace am
+{
+
+static const std::string CC_BLACK = "\x1b[0;30m";
+static const std::string CC_RED = "\x1b[0;31m";
+static const std::string CC_GREEN = "\x1b[0;32m";
+static const std::string CC_YELLOW = "\x1b[0;33m";
+static const std::string CC_BLUE = "\x1b[0;34m";
+static const std::string CC_MAGENTA = "\x1b[0;35m";
+static const std::string CC_CYAN = "\x1b[0;36m";
+static const std::string CC_WHITE = "\x1b[0;37m";
+static const std::string CC_RESET = "\x1b[0;39m";
+
+class CStdOutHeader
+{
+public:
+ CStdOutHeader(const char *ctx = "LOG", const std::string &color = CC_BLUE)
+ : mCtx(ctx)
+ , mCc(color) {}
+ friend std ::ofstream &operator <<(std::ofstream &out, const CStdOutHeader &h);
+
+ const char *mCtx;
+ const std::string &mCc;
+};
+
+class CAmLogContextStdOut : public IAmLogContext
+{
+public:
+ CAmLogContextStdOut(const char *id, const am_LogLevel_e level, const am_LogStatus_e status);
+ virtual ~CAmLogContextStdOut() {}
+
+ void changeLogLS(const am_LogLevel_e level, const am_LogStatus_e status);
+
+ /* IAmLogContext */
+ bool checkLogLevel(const am_LogLevel_e logLevel) override;
+
+private:
+ /* IAmLogContext */
+ bool configure(const am_LogLevel_e loglevel) override;
+ void send() override;
+ void append(const int8_t value) override;
+ void append(const uint8_t value) override;
+ void append(const int16_t value) override;
+ void append(const uint16_t value) override;
+ void append(const int32_t value) override;
+ void append(const uint32_t value) override;
+ void append(const uint64_t value) override;
+ void append(const int64_t value) override;
+ void append(const bool value) override;
+ void append(const std::vector<uint8_t> &data) override;
+ void append(const char *value) override;
+
+ template<class T>
+ void appendStdOut(T value);
+
+private:
+ CStdOutHeader mHeader;
+ am_LogLevel_e mLogLevel;
+ am_LogStatus_e mLogStatus;
+};
+
+class CAmLoggerStdOut : public IAmLogger
+{
+public:
+ CAmLoggerStdOut(const am_LogStatus_e status, const bool onlyError = false);
+ ~CAmLoggerStdOut();
+
+ /* IAmLogger */
+ void registerApp(const char *appid, const char *description) override;
+ void unregisterApp() override;
+ IAmLogContext &registerContext(const char *contextid, const char *description) override;
+ IAmLogContext &registerContext(const char *contextid, const char *description,
+ const am_LogLevel_e level, const am_LogStatus_e status) override;
+ IAmLogContext &importContext(const char *contextid = NULL) override;
+ void unregisterContext(const char *contextid) override;
+
+private:
+ CStdOutHeader mHeader;
+ const am_LogStatus_e mLogStatus;
+ const am_LogLevel_e mStandardLogLevel;
+ std::map<const char *, CAmLogContextStdOut *> mCtxTable;
+};
+
+}
+
+#endif /* LOGGERSTDOUT_H_ */
diff --git a/AudioManagerUtilities/include/CAmTimeUtility.h b/AudioManagerUtilities/include/CAmTimeUtility.h
new file mode 100755
index 0000000..2f0a29d
--- /dev/null
+++ b/AudioManagerUtilities/include/CAmTimeUtility.h
@@ -0,0 +1,45 @@
+/**
+ * SPDX license identifier: MPL-2.0
+ *
+ * Copyright (C) 2016, ADIT GmbH
+ *
+ * This file is part of GENIVI Project AudioManager.
+ *
+ * Contributions are licensed to the GENIVI Alliance under one or more
+ * Contribution License Agreements.
+ *
+ * \copyright
+ * This Source Code Form is subject to the terms of the
+ * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with
+ * this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * \file CAmTimeUtility.h
+ * For further information see http://www.genivi.org/.
+ */
+
+#ifndef TIMEUTILITY_H_
+#define TIMEUTILITY_H_
+
+#include <string>
+
+namespace am
+{
+
+class CAmTimeUtility
+{
+public:
+ static inline std::string now()
+ {
+ time_t t(std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()));
+ struct tm *timeinfo(localtime(&t));
+ char buffer[80];
+ strftime(buffer, 80, "%D %T ", timeinfo);
+ return (std::string(buffer));
+ }
+
+ virtual ~CAmTimeUtility();
+};
+
+}
+
+#endif /* TIMEUTILITY_H_ */
diff --git a/AudioManagerUtilities/include/IAmLogger.h b/AudioManagerUtilities/include/IAmLogger.h
new file mode 100755
index 0000000..95af6b9
--- /dev/null
+++ b/AudioManagerUtilities/include/IAmLogger.h
@@ -0,0 +1,342 @@
+/**
+ * SPDX license identifier: MPL-2.0
+ *
+ * Copyright (C) 2015, ADIT GmbH
+ *
+ * \author Jens Lorenz, jlorenz@de.adit-jv.com ADIT 2015
+ *
+ * This file is part of GENIVI Project AudioManager.
+ *
+ * Contributions are licensed to the GENIVI Alliance under one or more
+ * Contribution License Agreements.
+ *
+ * \copyright
+ * This Source Code Form is subject to the terms of the
+ * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with
+ * this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * \file IAmLogger.h
+ * For further information see http://www.genivi.org/.
+ */
+
+#ifndef LOGGER_H_
+#define LOGGER_H_
+
+#include <pthread.h>
+#include <stdint.h>
+#include <sstream>
+#include <vector>
+#include <cassert>
+#include "audiomanagertypes.h"
+
+
+namespace am
+{
+
+#define DEFAULT_CONTEXT "DEF"
+#define DEFAULT_DESCRIPTION "default Context registered by DLT Logger Class"
+
+#define DEFAULT_LOG_SERVICE static_cast<am_LogService_e>(0)
+
+enum am_LogService_e
+{
+ LOG_SERVICE_DLT,
+ LOG_SERVICE_STDOUT,
+ LOG_SERVICE_FILE,
+ LOG_SERVICE_OFF
+};
+
+enum am_LogLevel_e
+{
+ LL_OFF = 0x00, /**< Log level off */
+ LL_FATAL = 0x01, /**< fatal system error */
+ LL_ERROR = 0x02, /**< error with impact to correct functionality */
+ LL_WARN = 0x03, /**< warning, correct behavior could not be ensured */
+ LL_INFO = 0x04, /**< informational */
+ LL_DEBUG = 0x05, /**< debug */
+ LL_VERBOSE = 0x06 /**< highest grade of information */
+};
+
+enum am_LogStatus_e
+{
+ LS_OFF = 0x00,
+ LS_ON = 0x01
+};
+
+class IAmLogContext
+{
+public:
+ virtual ~IAmLogContext() {}
+
+ /**
+ * logs given loglevel and given values
+ * @param loglevel
+ * @param ...
+ */
+ template<typename... TArgs>
+ void off(const TArgs & ... args)
+ {
+ this->log(LL_OFF, args...);
+ }
+
+ template<typename... TArgs>
+ void fatal(const TArgs & ... args)
+ {
+ this->log(LL_FATAL, args...);
+ }
+
+ template<typename... TArgs>
+ void error(const TArgs & ... args)
+ {
+ this->log(LL_ERROR, args...);
+ }
+
+ template<typename... TArgs>
+ void warn(const TArgs & ... args)
+ {
+ this->log(LL_WARN, args...);
+ }
+
+ template<typename... TArgs>
+ void info(const TArgs & ... args)
+ {
+ this->log(LL_INFO, args...);
+ }
+
+ template<typename... TArgs>
+ void debug(const TArgs & ... args)
+ {
+ this->log(LL_DEBUG, args...);
+ }
+
+ template<typename... TArgs>
+ void verbose(const TArgs & ... args)
+ {
+ this->log(LL_VERBOSE, args...);
+ }
+
+ template<typename... TArgs>
+ void log(const am_LogLevel_e loglevel, const TArgs & ... args)
+ {
+ if (!this->configure(loglevel))
+ {
+ return;
+ }
+
+ this->append(args...);
+ this->send();
+ }
+
+ virtual bool checkLogLevel(const am_LogLevel_e logLevel) = 0;
+
+ virtual bool configure(const am_LogLevel_e loglevel) = 0;
+
+private:
+ virtual void send() = 0;
+
+ virtual void append(const int8_t value) = 0;
+ virtual void append(const uint8_t value) = 0;
+ virtual void append(const int16_t value) = 0;
+ virtual void append(const uint16_t value) = 0;
+ virtual void append(const int32_t value) = 0;
+ virtual void append(const uint32_t value) = 0;
+ virtual void append(const uint64_t value) = 0;
+ virtual void append(const int64_t value) = 0;
+ virtual void append(const bool value) = 0;
+ virtual void append(const std::vector<uint8_t> &data) = 0;
+ virtual void append(const char *value) = 0;
+
+ template<typename T = std::string &>
+ void append(const std::string &value)
+ {
+ this->append(value.c_str());
+ }
+
+ template<typename T>
+ void append_enum(const T &value, const T &tmax, const std::vector<const char *> &text)
+ {
+ assert(tmax == text.size());
+ try
+ {
+ this->append(text.at(value));
+ }
+ catch (const std::out_of_range &)
+ {
+ this->append(__PRETTY_FUNCTION__);
+ this->append(static_cast<int32_t>(value));
+ this->append("out of range!");
+ }
+ }
+
+ template<typename T = am_Error_e>
+ void append(const am_Error_e value)
+ {
+ this->append_enum(value, E_MAX, std::vector<const char *> {
+ "E_OK",
+ "E_UNKNOWN",
+ "E_OUT_OF_RANGE",
+ "E_NOT_USED",
+ "E_DATABASE_ERROR",
+ "E_ALREADY_EXISTS",
+ "E_NO_CHANGE",
+ "E_NOT_POSSIBLE",
+ "E_NON_EXISTENT",
+ "E_ABORTED",
+ "E_WRONG_FORMAT",
+ "E_COMMUNICATION"
+ }
+ );
+ }
+
+ template<typename T = am_SourceState_e>
+ void append(const am_SourceState_e value)
+ {
+ this->append_enum(value, SS_MAX, std::vector<const char *> {
+ "SS_UNKNNOWN",
+ "SS_ON",
+ "SS_OFF",
+ "SS_PAUSED"
+ }
+ );
+ }
+
+ template<typename T = am_MuteState_e>
+ void append(const am_MuteState_e value)
+ {
+ this->append_enum(value, MS_MAX, std::vector<const char *> {
+ "MS_UNKNOWN",
+ "MS_MUTED",
+ "MS_UNMUTED"
+ }
+ );
+ }
+
+ template<typename T = am_DomainState_e>
+ void append(const am_DomainState_e value)
+ {
+ this->append_enum(value, DS_MAX, std::vector<const char *> {
+ "DS_UNKNOWN",
+ "DS_CONTROLLED",
+ "DS_INDEPENDENT_STARTUP",
+ "DS_INDEPENDENT_RUNDOWN"
+ }
+ );
+ }
+
+ template<typename T = am_ConnectionState_e>
+ void append(const am_ConnectionState_e value)
+ {
+ this->append_enum(value, CS_MAX, std::vector<const char *> {
+ "CS_UNKNOWN",
+ "CS_CONNECTING",
+ "CS_CONNECTED",
+ "CS_DISCONNECTING",
+ "CS_DISCONNECTED",
+ "CS_SUSPENDED"
+ }
+ );
+ }
+
+ template<typename T = am_Availability_e>
+ void append(const am_Availability_e value)
+ {
+ this->append_enum(value, A_MAX, std::vector<const char *> {
+ "A_UNKNOWN",
+ "A_AVAILABLE",
+ "A_UNAVAILABLE"
+ }
+ );
+ }
+
+ template<typename T = am_InterruptState_e>
+ void append(const am_InterruptState_e value)
+ {
+ this->append_enum(value, IS_MAX, std::vector<const char *> {
+ "IS_UNKNOWN",
+ "IS_OFF",
+ "IS_INTERRUPTED"
+ }
+ );
+ }
+
+ template<typename T = am_Handle_e>
+ void append(const am_Handle_e value)
+ {
+ this->append_enum(value, H_MAX, std::vector<const char *> {
+ "H_UNKNOWN",
+ "H_CONNECT",
+ "H_DISCONNECT",
+ "H_SETSOURCESTATE",
+ "H_SETSINKVOLUME",
+ "H_SETSOURCEVOLUME",
+ "H_SETSINKSOUNDPROPERTY",
+ "H_SETSOURCESOUNDPROPERTY",
+ "H_SETSINKSOUNDPROPERTIES",
+ "H_SETSOURCESOUNDPROPERTIES",
+ "H_CROSSFADE",
+ "H_SETVOLUMES",
+ "H_SETSINKNOTIFICATION",
+ "H_SETSOURCENOTIFICATION"
+ }
+ );
+ }
+
+ template<typename T = am_Handle_s>
+ void append(const am_Handle_s value)
+ {
+ this->append(value.handle);
+ this->append(value.handleType);
+ }
+
+ // Template to print unknown pointer types with their address
+ template<typename T>
+ void append(T *value)
+ {
+ std::ostringstream ss;
+ ss << "0x" << std::hex << (uint64_t)value;
+ this->append(ss.str().c_str());
+ }
+
+ // Template to print unknown types
+ template<typename T>
+ void append(T value)
+ {
+ std::ostringstream ss;
+ ss << std::dec << value;
+ this->append(ss.str().c_str());
+ }
+
+ // Template parameter pack to generate recursive code
+ void append(void) {}
+ template<typename T, typename... TArgs>
+ void append(const T &value, const TArgs & ... args)
+ {
+ this->append(value);
+ this->append(args...);
+ }
+
+};
+
+class IAmLogger
+{
+public:
+ virtual ~IAmLogger() {}
+ virtual void registerApp(const char *appid, const char *description) = 0;
+ virtual void unregisterApp() = 0;
+ virtual IAmLogContext &registerContext(const char *contextid, const char *description) = 0;
+ virtual IAmLogContext &registerContext(const char *contextid, const char *description,
+ const am_LogLevel_e level, const am_LogStatus_e status) = 0;
+ virtual IAmLogContext &importContext(const char *contextid = NULL) = 0;
+ virtual void unregisterContext(const char *contextid) = 0;
+
+ template<typename T, typename... TArgs>
+ void logToDefaultContext(const am_LogLevel_e loglevel, const T &value, const TArgs & ... args)
+ {
+ this->importContext().log(loglevel, value, args...);
+ }
+
+};
+
+}
+
+#endif // LOGGER_H_
diff --git a/AudioManagerUtilities/src/CAmLogWrapper.cpp b/AudioManagerUtilities/src/CAmLogWrapper.cpp
new file mode 100755
index 0000000..8bd6b0a
--- /dev/null
+++ b/AudioManagerUtilities/src/CAmLogWrapper.cpp
@@ -0,0 +1,125 @@
+/**
+ * SPDX license identifier: MPL-2.0
+ *
+ * Copyright (C) 2017, ADIT GmbH
+ *
+ * This file is part of GENIVI Project AudioManager.
+ *
+ * Contributions are licensed to the GENIVI Alliance under one or more
+ * Contribution License Agreements.
+ *
+ * \copyright
+ * This Source Code Form is subject to the terms of the
+ * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with
+ * this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ *
+ * \author Mattia Guerra, mguerra@de.adit-jv.com ADIT 2017
+ * \author Jens Lorenz, jlorenz@de.adit-jv.com ADIT 2017
+ *
+ * \file CAmLogWrapper.cpp
+ * For further information see http://www.genivi.org/.
+ *
+ */
+
+#include <iostream>
+#include <unistd.h>
+#include "CAmLogWrapper.h"
+#include "CAmLoggerStdOut.h"
+#include "CAmLoggerFile.h"
+#ifdef WITH_DLT
+# include "CAmLoggerDlt.h"
+#endif
+
+
+using namespace std;
+
+namespace am
+{
+
+IAmLogger *CAmLogWrapper::mpLogger = NULL;
+string CAmLogWrapper::mAppId = "";
+string CAmLogWrapper::mDescription = "";
+am_LogStatus_e CAmLogWrapper::mLogStatus = LS_ON;
+am_LogService_e CAmLogWrapper::mLogService = DEFAULT_LOG_SERVICE;
+string CAmLogWrapper::mFilename = "";
+bool CAmLogWrapper::mOnlyError = false;
+
+CAmLogWrapper::CAmLogWrapper(void)
+{
+}
+
+IAmLogger *CAmLogWrapper::instantiateOnce(const char *appid, const char *description,
+ const am_LogStatus_e logStatus, const am_LogService_e logService,
+ const string fileName, bool onlyError)
+{
+ if (mpLogger)
+ {
+ return mpLogger;
+ }
+
+ mAppId = string(appid);
+ mDescription = string(description);
+ mLogStatus = logStatus;
+ mLogService = logService;
+ mFilename = fileName;
+ mOnlyError = onlyError;
+ return instance(mLogService);
+}
+
+IAmLogger *CAmLogWrapper::instance(const am_LogService_e service)
+{
+ if (mpLogger)
+ {
+ return mpLogger;
+ }
+
+ switch (service)
+ {
+ case LOG_SERVICE_DLT:
+#ifdef WITH_DLT
+ mpLogger = new CAmLoggerDlt();
+#else
+ std::cerr << "Option WITH_DLT not enabled for CAmLogWrapper! "
+ << "Redirecting log output to stdout ..." << std::endl;
+ mLogService = LOG_SERVICE_STDOUT;
+ mpLogger = new CAmLoggerStdOut(mLogStatus, mOnlyError);
+#endif
+ break;
+ case LOG_SERVICE_STDOUT:
+ mpLogger = new CAmLoggerStdOut(mLogStatus, mOnlyError);
+ break;
+ case LOG_SERVICE_FILE:
+ mpLogger = new CAmLoggerFile(mLogStatus, mOnlyError, mFilename);
+ break;
+ default:
+ mpLogger = new CAmLoggerStdOut(LS_OFF);
+ break;
+ }
+
+ // an application seems not to use our CAmLogWrapper class properly therefore create default context
+ if ((mLogStatus == LS_ON) && mAppId.empty() && mDescription.empty())
+ {
+ mAppId = "AMDL";
+ std::ostringstream description;
+ description << "PID=" << getpid() << " _=" << getenv("_");
+ mDescription = description.str().c_str();
+ std::cerr << "Application doesn't call CAmLogWrapper::instantiateOnce!!!" << std::endl;
+ std::cerr << "-> CAmLogWrapper::instance registers DLT application [ AMDL | " << description.str() << " ]" << std::endl;
+ }
+
+ mpLogger->registerApp(mAppId.c_str(), mDescription.c_str());
+
+ return mpLogger;
+}
+
+CAmLogWrapper::~CAmLogWrapper()
+{
+ if (mpLogger)
+ {
+ mpLogger->unregisterApp();
+ delete mpLogger;
+ }
+}
+
+}
diff --git a/AudioManagerUtilities/src/CAmLoggerDlt.cpp b/AudioManagerUtilities/src/CAmLoggerDlt.cpp
new file mode 100755
index 0000000..8840916
--- /dev/null
+++ b/AudioManagerUtilities/src/CAmLoggerDlt.cpp
@@ -0,0 +1,223 @@
+/**
+ * SPDX license identifier: MPL-2.0
+ *
+ * Copyright (C) 2015, ADIT GmbH
+ *
+ * This file is part of GENIVI Project AudioManager.
+ *
+ * Contributions are licensed to the GENIVI Alliance under one or more
+ * Contribution License Agreements.
+ *
+ * \copyright
+ * This Source Code Form is subject to the terms of the
+ * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with
+ * this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ *
+ * \author Jens Lorenz, jlorenz@de.adit-jv.com ADIT 2017
+ * \author Mattia Guerra, mguerra@de.adit-jv.com ADIT 2017
+ * \author Martin Koch, mkoch@de.adit-jv.com ADIT 2020
+ *
+ * \file CAmLoggerDlt.cpp
+ * For further information see http://www.genivi.org/.
+ *
+ */
+
+#include "CAmLogWrapper.h"
+#include "CAmLoggerDlt.h"
+
+namespace am
+{
+
+pthread_mutex_t gDltMtx = PTHREAD_MUTEX_INITIALIZER;
+
+CAmLogContextDlt::CAmLogContextDlt(const char *id)
+ : mId(id)
+{
+}
+
+DltContext *CAmLogContextDlt::getHandle()
+{
+ return &mDltContext;
+}
+
+void CAmLogContextDlt::append(const int8_t value)
+{
+ dlt_user_log_write_int8(&mDltContextData, value);
+}
+
+void CAmLogContextDlt::append(const uint8_t value)
+{
+ dlt_user_log_write_uint8(&mDltContextData, value);
+}
+
+void CAmLogContextDlt::append(const int16_t value)
+{
+ dlt_user_log_write_int16(&mDltContextData, value);
+}
+
+void CAmLogContextDlt::append(const uint16_t value)
+{
+ dlt_user_log_write_uint16(&mDltContextData, value);
+}
+
+void CAmLogContextDlt::append(const int32_t value)
+{
+ dlt_user_log_write_int32(&mDltContextData, value);
+}
+
+void CAmLogContextDlt::append(const uint32_t value)
+{
+ dlt_user_log_write_uint32(&mDltContextData, value);
+}
+
+void CAmLogContextDlt::append(const bool value)
+{
+ dlt_user_log_write_bool(&mDltContextData, static_cast<uint8_t>(value));
+}
+
+void CAmLogContextDlt::append(const int64_t value)
+{
+ dlt_user_log_write_int64(&mDltContextData, value);
+}
+
+void CAmLogContextDlt::append(const uint64_t value)
+{
+ dlt_user_log_write_uint64(&mDltContextData, value);
+}
+
+void CAmLogContextDlt::append(const std::vector<uint8_t> &data)
+{
+ dlt_user_log_write_raw(&mDltContextData, (void *)data.data(), data.size());
+}
+
+void CAmLogContextDlt::append(const char *value)
+{
+ dlt_user_log_write_string(&mDltContextData, value);
+}
+
+bool CAmLogContextDlt::checkLogLevel(const am_LogLevel_e logLevel)
+{
+#ifdef DLT_IS_LOG_LEVEL_ENABLED
+ return (dlt_user_is_logLevel_enabled(&mDltContext, static_cast<DltLogLevelType>(logLevel)) == DLT_RETURN_TRUE);
+#else
+ (void)logLevel;
+ return true;
+#endif
+}
+
+bool CAmLogContextDlt::configure(const am_LogLevel_e loglevel)
+{
+ pthread_mutex_lock(&gDltMtx);
+
+ /* leave in case we are allowed to send messages */
+ if (dlt_user_log_write_start(&mDltContext, &mDltContextData, static_cast<DltLogLevelType>(loglevel)) > 0)
+ {
+ return true;
+ }
+
+ pthread_mutex_unlock(&gDltMtx);
+ return false;
+}
+
+void CAmLogContextDlt::send()
+{
+ dlt_user_log_write_finish(&mDltContextData);
+ pthread_mutex_unlock(&gDltMtx);
+}
+
+CAmLoggerDlt::~CAmLoggerDlt()
+{
+ unregisterApp();
+}
+
+void CAmLoggerDlt::registerApp(const char *appid, const char *description)
+{
+ dlt_register_app(appid, description);
+ registerContext(DEFAULT_CONTEXT, DEFAULT_DESCRIPTION);
+}
+
+void CAmLoggerDlt::unregisterApp()
+{
+ for (auto &&context : mCtxTable)
+ {
+ dlt_unregister_context(context.second->getHandle());
+ delete context.second;
+ delete context.first;
+ }
+ mCtxTable.clear();
+
+ dlt_unregister_app();
+}
+
+IAmLogContext &CAmLoggerDlt::registerContext(const char *contextid, const char *description)
+{
+ auto &&context = createContext(contextid);
+ dlt_register_context(context.getHandle(), contextid, description);
+ return context;
+}
+
+IAmLogContext &CAmLoggerDlt::registerContext(const char *contextid, const char *description, const am_LogLevel_e level, const am_LogStatus_e status)
+{
+ auto &&context = createContext(contextid);
+ dlt_register_context_ll_ts(context.getHandle(), contextid, description, static_cast<DltLogLevelType>(level), static_cast<DltTraceStatusType>(status));
+ return context;
+}
+
+IAmLogContext &CAmLoggerDlt::importContext(const char *contextid)
+{
+ // check, if we have this context
+ contextid = (contextid ? contextid : DEFAULT_CONTEXT);
+ for (auto &ctx : mCtxTable)
+ {
+ if (contextid && strncmp(ctx.first, contextid, DLT_ID_SIZE) == 0)
+ {
+ return *ctx.second;
+ }
+ }
+
+ // no match. Fall back to default context
+ return importContext(DEFAULT_CONTEXT);
+}
+
+void CAmLoggerDlt::unregisterContext(const char *contextid)
+{
+ for (auto it = mCtxTable.begin(); it != mCtxTable.end(); ++it)
+ {
+ if (contextid && strncmp(contextid, it->first, DLT_ID_SIZE) == 0)
+ {
+ dlt_unregister_context(it->second->getHandle());
+ delete it->second;
+
+ const char *pKey = it->first;
+ mCtxTable.erase(it);
+ delete pKey;
+
+ return;
+ }
+ }
+}
+
+CAmLogContextDlt &CAmLoggerDlt::createContext(const char *contextid)
+{
+ // check, if we already have this context
+ for (auto &ctx : mCtxTable)
+ {
+ if (contextid && strncmp(contextid, ctx.first, DLT_ID_SIZE) == 0)
+ {
+ return *ctx.second;
+ }
+ }
+
+ // Not in list. Create new
+ size_t len = (contextid ? strlen(contextid) : 0);
+ char *pKey = new char[1 + len];
+ strncpy(pKey, contextid, len);
+ pKey[len] = '\0';
+ auto *pContext = new CAmLogContextDlt(contextid);
+ mCtxTable[pKey] = pContext;
+
+ return *pContext;
+}
+
+}
diff --git a/AudioManagerUtilities/src/CAmLoggerFile.cpp b/AudioManagerUtilities/src/CAmLoggerFile.cpp
new file mode 100755
index 0000000..e3b4dbf
--- /dev/null
+++ b/AudioManagerUtilities/src/CAmLoggerFile.cpp
@@ -0,0 +1,252 @@
+/**
+ * SPDX license identifier: MPL-2.0
+ *
+ * Copyright (C) 2017, ADIT GmbH
+ *
+ * This file is part of GENIVI Project AudioManager.
+ *
+ * Contributions are licensed to the GENIVI Alliance under one or more
+ * Contribution License Agreements.
+ *
+ * \copyright
+ * This Source Code Form is subject to the terms of the
+ * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with
+ * this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * \author Jens Lorenz, jlorenz@de.adit-jv.com ADIT 2017
+ * \author Mattia Guerra, mguerra@de.adit-jv.com ADIT 2017
+ * \author Martin Koch, mkoch@de.adit-jv.com ADIT 2020
+ *
+ * \file CAmLoggerFile.cpp
+ * For further information see http://www.genivi.org/.
+ *
+ */
+
+#include <algorithm>
+#include <iostream>
+#include <sstream>
+#include <mutex>
+#include <iomanip>
+#include "CAmLogWrapper.h"
+#include "CAmLoggerFile.h"
+#include "CAmTimeUtility.h"
+
+using namespace std;
+
+namespace am
+{
+
+#define PADDING_WIDTH 4
+
+pthread_mutex_t gFileMtx = PTHREAD_MUTEX_INITIALIZER;
+
+ostream &operator <<(ostream &out, const class CFileHeader &h)
+{
+ out << CAmTimeUtility::now() << "[" << setw(PADDING_WIDTH) << left << string(h.mCtx, 0, PADDING_WIDTH) << "] ";
+ return out;
+}
+
+CAmLogContextFile::CAmLogContextFile(const char *id, const am_LogLevel_e level, const am_LogStatus_e status, ofstream &filestream)
+ : mHeader(id)
+ , mLogLevel(level)
+ , mLogStatus(status)
+ , mFilestream(filestream)
+{
+}
+
+void CAmLogContextFile::append(const int8_t value)
+{
+ appendFile(value);
+}
+
+void CAmLogContextFile::append(const uint8_t value)
+{
+ appendFile(value);
+}
+
+void CAmLogContextFile::append(const int16_t value)
+{
+ appendFile(value);
+}
+
+void CAmLogContextFile::append(const uint16_t value)
+{
+ appendFile(value);
+}
+
+void CAmLogContextFile::append(const int32_t value)
+{
+ appendFile(value);
+}
+
+void CAmLogContextFile::append(const uint32_t value)
+{
+ appendFile(value);
+}
+
+void CAmLogContextFile::append(const uint64_t value)
+{
+ appendFile(value);
+}
+
+void CAmLogContextFile::append(const int64_t value)
+{
+ appendFile(value);
+}
+
+void CAmLogContextFile::append(const bool value)
+{
+ appendFile(value);
+}
+
+void CAmLogContextFile::append(const char *value)
+{
+ appendFile(value);
+}
+
+void CAmLogContextFile::append(const vector<uint8_t> &data)
+{
+ mFilestream << data.data() << " ";
+}
+
+template<class T>
+void CAmLogContextFile::appendFile(T value)
+{
+ mFilestream << value << " ";
+}
+
+bool CAmLogContextFile::configure(const am_LogLevel_e loglevel)
+{
+ if (LS_OFF || loglevel > mLogLevel)
+ {
+ return false;
+ }
+
+ pthread_mutex_lock(&gFileMtx);
+ mFilestream << mHeader;
+
+ return true;
+}
+
+bool CAmLogContextFile::checkLogLevel(const am_LogLevel_e logLevel)
+{
+ return logLevel <= mLogLevel;
+}
+
+void CAmLogContextFile::send()
+{
+ mFilestream << endl;
+ pthread_mutex_unlock(&gFileMtx);
+}
+
+CAmLoggerFile::CAmLoggerFile(const am_LogStatus_e status, const bool onlyError, const string &filename)
+ : mLogStatus(status)
+ , mStandardLogLevel(onlyError ? LL_ERROR : LL_INFO)
+{
+ if (mLogStatus == LS_OFF)
+ {
+ cout << "Running without Logging support" << endl;
+ return;
+ }
+
+ mFilestream.open(filename.c_str(), ofstream::out | ofstream::trunc);
+ if (!mFilestream.is_open())
+ {
+ throw runtime_error("Cannot open log file: " + filename);
+ }
+}
+
+CAmLoggerFile::~CAmLoggerFile()
+{
+ mFilestream.close();
+ unregisterApp();
+}
+
+void CAmLoggerFile::unregisterApp()
+{
+ for (auto &&context : mCtxTable)
+ {
+ unregisterContext(context.first);
+ }
+}
+
+void CAmLoggerFile::registerApp(const char *appid, const char *description)
+{
+ if (mLogStatus == LS_ON)
+ {
+ mFilestream << mHeader << "Register Application " << string(appid, PADDING_WIDTH) << ", " << description << endl;
+ }
+
+ registerContext(DEFAULT_CONTEXT, DEFAULT_DESCRIPTION);
+}
+
+IAmLogContext &CAmLoggerFile::registerContext(const char *contextid, const char *description)
+{
+ return registerContext(contextid, description, mStandardLogLevel, mLogStatus);
+}
+
+IAmLogContext &CAmLoggerFile::registerContext(const char *contextid, const char *description,
+ const am_LogLevel_e level, const am_LogStatus_e status)
+{
+ // check, if we already have this context
+ for (auto &ctx : mCtxTable)
+ {
+ if (contextid && strncmp(contextid, ctx.first, PADDING_WIDTH) == 0)
+ {
+ return *ctx.second;
+ }
+ }
+
+ // Not in list. Create new
+ if (mLogStatus == LS_ON)
+ {
+ mFilestream << mHeader << "Registering Context " << string(contextid, PADDING_WIDTH) << ", " << description << endl;
+ }
+ size_t len = (contextid ? strlen(contextid) : 0);
+ char *pKey = new char[1 + len];
+ strncpy(pKey, contextid, len);
+ pKey[len] = '\0';
+ auto *pContext = new CAmLogContextFile(contextid, level, status, mFilestream);
+ mCtxTable[pKey] = pContext;
+
+ return *pContext;
+}
+
+IAmLogContext &CAmLoggerFile::importContext(const char *contextid)
+{
+ // check, if we have this context
+ contextid = (contextid ? contextid : DEFAULT_CONTEXT);
+ for (auto &ctx : mCtxTable)
+ {
+ if (contextid && strncmp(ctx.first, contextid, PADDING_WIDTH) == 0)
+ {
+ return *ctx.second;
+ }
+ }
+
+ // no match. Fall back to default context
+ return importContext(DEFAULT_CONTEXT);
+}
+
+void CAmLoggerFile::unregisterContext(const char *contextid)
+{
+ for (auto it = mCtxTable.begin(); it != mCtxTable.end(); ++it)
+ {
+ if (contextid && strncmp(contextid, it->first, PADDING_WIDTH) == 0)
+ {
+ delete it->second;
+ const char *key = it->first;
+ mCtxTable.erase(it);
+ delete key;
+
+ if (mLogStatus == LS_ON)
+ {
+ mFilestream << mHeader << "Context " << string(contextid, PADDING_WIDTH) << "unregistered" << endl;
+ }
+
+ return;
+ }
+ }
+}
+
+}
diff --git a/AudioManagerUtilities/src/CAmLoggerStdOut.cpp b/AudioManagerUtilities/src/CAmLoggerStdOut.cpp
new file mode 100755
index 0000000..0e3e4dd
--- /dev/null
+++ b/AudioManagerUtilities/src/CAmLoggerStdOut.cpp
@@ -0,0 +1,264 @@
+/**
+ * SPDX license identifier: MPL-2.0
+ *
+ * Copyright (C) 2017, ADIT GmbH
+ *
+ * This file is part of GENIVI Project AudioManager.
+ *
+ * Contributions are licensed to the GENIVI Alliance under one or more
+ * Contribution License Agreements.
+ *
+ * \copyright
+ * This Source Code Form is subject to the terms of the
+ * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with
+ * this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * \author Jens Lorenz, jlorenz@de.adit-jv.com ADIT 2017
+ * \author Mattia Guerra, mguerra@de.adit-jv.com ADIT 2017
+ * \author Martin Koch, mkoch@de.adit-jv.com ADIT 2020
+ *
+ * \file CAmLoggerStdOut.cpp
+ * For further information see http://www.genivi.org/.
+ *
+ */
+
+#include <algorithm>
+#include <iostream>
+#include <sstream>
+#include <mutex>
+#include <iomanip>
+#include "CAmLogWrapper.h"
+#include "CAmLoggerStdOut.h"
+#include "CAmTimeUtility.h"
+
+using namespace std;
+
+namespace am
+{
+
+#define PADDING_WIDTH 4
+
+pthread_mutex_t gStdOutMtx = PTHREAD_MUTEX_INITIALIZER;
+
+ostream &operator <<(ostream &out, const class CStdOutHeader &h)
+{
+ out << CAmTimeUtility::now() << h.mCc << "[" << setw(PADDING_WIDTH) << left << string(h.mCtx, 0, PADDING_WIDTH) << "] " << CC_RESET;
+ return out;
+}
+
+CAmLogContextStdOut::CAmLogContextStdOut(const char *id, const am_LogLevel_e level, const am_LogStatus_e status)
+ : mHeader(id, CC_GREEN)
+ , mLogLevel(level)
+ , mLogStatus(status)
+{
+}
+
+void CAmLogContextStdOut::changeLogLS(const am_LogLevel_e level, const am_LogStatus_e status)
+{
+ mLogLevel = level;
+ mLogStatus = status;
+}
+
+void CAmLogContextStdOut::append(const int8_t value)
+{
+ appendStdOut(value);
+}
+
+void CAmLogContextStdOut::append(const uint8_t value)
+{
+ appendStdOut(value);
+}
+
+void CAmLogContextStdOut::append(const int16_t value)
+{
+ appendStdOut(value);
+}
+
+void CAmLogContextStdOut::append(const uint16_t value)
+{
+ appendStdOut(value);
+}
+
+void CAmLogContextStdOut::append(const int32_t value)
+{
+ appendStdOut(value);
+}
+
+void CAmLogContextStdOut::append(const uint32_t value)
+{
+ appendStdOut(value);
+}
+
+void CAmLogContextStdOut::append(const uint64_t value)
+{
+ appendStdOut(value);
+}
+
+void CAmLogContextStdOut::append(const int64_t value)
+{
+ appendStdOut(value);
+}
+
+void CAmLogContextStdOut::append(const bool value)
+{
+ appendStdOut(value);
+}
+
+void CAmLogContextStdOut::append(const char *value)
+{
+ appendStdOut(value);
+}
+
+void CAmLogContextStdOut::append(const vector<uint8_t> &data)
+{
+ cout << data.data() << " ";
+}
+
+template<class T>
+void CAmLogContextStdOut::appendStdOut(T value)
+{
+ cout << value << " ";
+}
+
+bool CAmLogContextStdOut::configure(const am_LogLevel_e loglevel)
+{
+ if ((mLogStatus == LS_OFF) || (loglevel > mLogLevel))
+ {
+ return false;
+ }
+
+ pthread_mutex_lock(&gStdOutMtx);
+
+ switch (loglevel)
+ {
+ case LL_ERROR:
+ cout << mHeader << CC_RED;
+ break;
+ case LL_WARN:
+ cout << mHeader << CC_YELLOW;
+ break;
+ default:
+ cout << mHeader << CC_RESET;
+ break;
+ }
+
+ return true;
+}
+
+bool CAmLogContextStdOut::checkLogLevel(const am_LogLevel_e logLevel)
+{
+ return ((mLogStatus == LS_ON) && (logLevel <= mLogLevel));
+}
+
+void CAmLogContextStdOut::send()
+{
+ // NOTE: The color is set in the configure function
+ cout << CC_RESET << endl;
+ pthread_mutex_unlock(&gStdOutMtx);
+}
+
+CAmLoggerStdOut::CAmLoggerStdOut(const am_LogStatus_e status, const bool onlyError)
+ : mLogStatus(status)
+ , mStandardLogLevel(onlyError ? LL_ERROR : LL_INFO)
+{
+ if (mLogStatus == LS_OFF)
+ {
+ cout << mHeader << "Running without Logging support" << endl;
+ }
+}
+
+CAmLoggerStdOut::~CAmLoggerStdOut()
+{
+ unregisterApp();
+}
+
+void CAmLoggerStdOut::unregisterApp()
+{
+ for (auto &&context : mCtxTable)
+ {
+ unregisterContext(context.first);
+ }
+}
+
+void CAmLoggerStdOut::registerApp(const char *appid, const char *description)
+{
+ if (mLogStatus == LS_ON)
+ {
+ cout << mHeader << "Register Application " << string(appid, PADDING_WIDTH) << ", " << description << endl;
+ }
+
+ registerContext(DEFAULT_CONTEXT, DEFAULT_DESCRIPTION);
+}
+
+IAmLogContext &CAmLoggerStdOut::registerContext(const char *contextid, const char *description)
+{
+ return registerContext(contextid, description, mStandardLogLevel, mLogStatus);
+}
+
+IAmLogContext &CAmLoggerStdOut::registerContext(const char *contextid, const char *description,
+ const am_LogLevel_e level, const am_LogStatus_e status)
+{
+ // check, if we already have this context
+ for (auto &ctx : mCtxTable)
+ {
+ if (contextid && strncmp(contextid, ctx.first, PADDING_WIDTH) == 0)
+ {
+ ctx.second->changeLogLS(level, status);
+ return *ctx.second;
+ }
+ }
+
+ // Not in list. Create new
+ if (mLogStatus == LS_ON)
+ {
+ cout << mHeader << "Registering Context " << string(contextid, PADDING_WIDTH) << ", " << description << endl;
+ }
+ size_t len = (contextid ? strlen(contextid) : 0);
+ char *pKey = new char[1 + len];
+ strncpy(pKey, contextid, len);
+ pKey[len] = '\0';
+ auto *pContext = new CAmLogContextStdOut(contextid, level, status);
+ pContext->changeLogLS(level, status);
+ mCtxTable[pKey] = pContext;
+
+ return *pContext;
+}
+
+IAmLogContext &CAmLoggerStdOut::importContext(const char *contextid)
+{
+ // check, if we have this context
+ contextid = (contextid ? contextid : DEFAULT_CONTEXT);
+ for (auto &ctx : mCtxTable)
+ {
+ if (contextid && strncmp(ctx.first, contextid, PADDING_WIDTH) == 0)
+ {
+ return *ctx.second;
+ }
+ }
+
+ // no match. Fall back to default context
+ return importContext(DEFAULT_CONTEXT);
+}
+
+void CAmLoggerStdOut::unregisterContext(const char *contextid)
+{
+ for (auto it = mCtxTable.begin(); it != mCtxTable.end(); ++it)
+ {
+ if (contextid && strncmp(contextid, it->first, PADDING_WIDTH) == 0)
+ {
+ delete it->second;
+ const char *key = it->first;
+ mCtxTable.erase(it);
+ delete key;
+
+ if (mLogStatus == LS_ON)
+ {
+ cout << mHeader << string(contextid, PADDING_WIDTH) << " unregistered" << endl;
+ }
+
+ return;
+ }
+ }
+}
+
+}
diff --git a/Foo/uncrustify_files.cfg b/Foo/uncrustify_files.cfg
index c422173..b0ca445 100644
--- a/Foo/uncrustify_files.cfg
+++ b/Foo/uncrustify_files.cfg
@@ -1,5 +1,9 @@
./AudioManagerUtilities/src/CAmCommonAPIWrapper.cpp
./AudioManagerUtilities/src/CAmDltWrapper.cpp
+./AudioManagerUtilities/src/CAmLogWrapper.cpp
+./AudioManagerUtilities/src/CAmLoggerDlt.cpp
+./AudioManagerUtilities/src/CAmLoggerFile.cpp
+./AudioManagerUtilities/src/CAmLoggerStdOut.cpp
./AudioManagerUtilities/src/CAmSocketHandler.cpp
./AudioManagerUtilities/src/CAmDbusWrapper.cpp
./AudioManagerUtilities/src/CAmCommandLineSingleton.cpp
@@ -18,6 +22,12 @@
./AudioManagerUtilities/include/CAmDbusWrapper.h
./AudioManagerUtilities/include/CAmSerializer.h
./AudioManagerUtilities/include/CAmDltWrapper.h
+./AudioManagerUtilities/include/IAmLogger.h
+./AudioManagerUtilities/include/CAmLogWrapper.h
+./AudioManagerUtilities/include/CAmTimeUtility.h
+./AudioManagerUtilities/include/CAmLoggerDlt.h
+./AudioManagerUtilities/include/CAmLoggerFile.h
+./AudioManagerUtilities/include/CAmLoggerStdOut.h
./AudioManagerUtilities/include/CAmWatchdog.h
./AudioManagerUtilities/include/TAmPluginTemplate.h
./AudioManagerUtilities/include/CAmCommandLineSingleton.h