From de452ebdcfe9ca3cd3b2467c3e25960e7a58e49e Mon Sep 17 00:00:00 2001 From: Aleksander Donchev Date: Mon, 8 Jul 2013 11:27:30 +0200 Subject: Added 'Dump' method to the database handler and to the telnet server (Info -> Dump). Unit tests for the database handler splited into separate file. Base log class added in order to support logging into a file. Signed-off-by: Christian Linke --- .../include/CAmDatabaseHandlerInterface.h | 3 + AudioManagerDaemon/include/CAmLog.h | 134 ++++++++++ AudioManagerDaemon/include/CAmMapHandler.h | 278 ++++++++------------- AudioManagerDaemon/include/CAmTelnetMenuHelper.h | 2 + AudioManagerDaemon/include/CAmTelnetServer.h | 2 +- 5 files changed, 240 insertions(+), 179 deletions(-) create mode 100644 AudioManagerDaemon/include/CAmLog.h (limited to 'AudioManagerDaemon/include') diff --git a/AudioManagerDaemon/include/CAmDatabaseHandlerInterface.h b/AudioManagerDaemon/include/CAmDatabaseHandlerInterface.h index 58d97bc..de50511 100644 --- a/AudioManagerDaemon/include/CAmDatabaseHandlerInterface.h +++ b/AudioManagerDaemon/include/CAmDatabaseHandlerInterface.h @@ -26,6 +26,7 @@ #include #include #include +#include namespace am { @@ -185,6 +186,8 @@ public: virtual void registerObserver(CAmDatabaseObserver *iObserver) = 0; virtual bool sourceVisible(const am_sourceID_t sourceID) const = 0; virtual bool sinkVisible(const am_sinkID_t sinkID) const = 0; + + virtual void dump( std::ostream & output) { output << __FUNCTION__ << " not implemented!"; }; }; } diff --git a/AudioManagerDaemon/include/CAmLog.h b/AudioManagerDaemon/include/CAmLog.h new file mode 100644 index 0000000..2cbf68a --- /dev/null +++ b/AudioManagerDaemon/include/CAmLog.h @@ -0,0 +1,134 @@ +/* + * CAmLog.h + * + * Created on: Jul 2, 2013 + * Author: genius + */ + +/** + * Copyright (C) 2012, BMW AG + * + * 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 Aleksandar Donchev, aleksander.donchev@partner.bmw.de BMW 2013 + * + * \file CAmLog.h + * For further information see http://www.genivi.org/. + * + */ + +#ifndef CAMLOG_H_ +#define CAMLOG_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * Implements a basic logging mechanism that can be used to print debug information into a file or to the console. + * It can be used either as singleton through the appropriate method getDefaultLog() or as independent instantiated object. + * The default initializer sets the console as output for newly created objects. + * Example: CAmLogger << "Text"; //to print out through the singleton object directly to the console + */ + +#define DEFAULT_LOG_FOLDER "/tmp/" +#define DEFAULT_LOGFILE_PREFIX "am_dump_" +#define DEFAULT_LOGFILE_EXT ".log" + +#define DEL( aPointer ) delete aPointer, aPointer = NULL; + +/* */ +typedef enum { eCAmLogNone = 0, eCAmLogStdout = 1, eCAmLogFile = 2 } eCAmLogType; + +class CAmLog +{ +private: + /** + * Private classes which usually own (wrap) a stream object. They are responsible for creating and deleting it. + */ + class CAmLogger + { + protected: + std::ostream* mOutputStream; + public: + CAmLogger ():mOutputStream(NULL) {}; + virtual ~CAmLogger () { }; + virtual void log(const std::string& _s) + { + (*mOutputStream) << _s; + mOutputStream->flush(); + } + template + CAmLogger & operator << (const T & t) + { + (*mOutputStream) << t; + return (*this); + } + }; + + class CAmFileLogger : public CAmLogger + { + std::string mFilename; + public: + static void generateLogFilename(std::string &result); + explicit CAmFileLogger(const std::string& _s) : CAmLogger() + { + mFilename = _s; + mOutputStream = new std::ofstream(mFilename.c_str()); + } + ~CAmFileLogger(); + }; + + class CAmStdOutLogger : public CAmLogger + { + public: + CAmStdOutLogger() + { + mOutputStream = &std::cout; + } + }; + +private: + eCAmLogType mLogType; + CAmLogger* mLogger; + +protected: + void releaseLogger(); + void instantiateLogger( const eCAmLogType type); +public: + CAmLog(const eCAmLogType type ); + CAmLog(); + ~CAmLog(); + + static CAmLog *getDefaultLog(); + + void setLogType( const eCAmLogType type); + eCAmLogType getLogType() const; + + template + CAmLog & operator << (const T & t) + { + assert(mLogger!=NULL); + (*mLogger) << t; + return (*this); + } + }; + +#define CAmLogger (*CAmLog::getDefaultLog()) + + +#endif /* CAMLOG_H_ */ diff --git a/AudioManagerDaemon/include/CAmMapHandler.h b/AudioManagerDaemon/include/CAmMapHandler.h index 47bd0ec..510d368 100644 --- a/AudioManagerDaemon/include/CAmMapHandler.h +++ b/AudioManagerDaemon/include/CAmMapHandler.h @@ -14,7 +14,7 @@ * * \author Aleksandar Donchev, aleksander.donchev@partner.bmw.de BMW 2013 * - * \file CAmDatabaseHandler.h + * \file CAmMapHandler.h * For further information see http://www.genivi.org/. * */ @@ -23,13 +23,19 @@ #define MAPHANDLER_H_ #include "CAmDatabaseHandlerInterface.h" -#include -#include #include #include +#include +#include +#include + + namespace am { + +#define AM_MAP std::unordered_map + //todo: check the enum values before entering & changing in the database. //todo: change asserts for dynamic boundary checks into failure answers.# //todo: check autoincrement boundary and set to 16bit limits @@ -158,169 +164,102 @@ public: bool sourceVisible(const am_sourceID_t sourceID) const; bool sinkVisible(const am_sinkID_t sinkID) const; - void printSources(); - void printSinks(); - void printSinkClasses(); - void printSourceClasses(); - + void dump( std::ostream & output ); + template void print (const TPrintObject & t, std::ostream & output) const; + template void printMap (const AM_MAP & t, std::ostream & output) const; /** * The following structures extend the base structures with the field 'reserved'. */ - struct am_Sink_Database_s : public am_Sink_s - { - bool reserved; - am_Sink_Database_s():am_Sink_s(), reserved(false) - {}; - void getSinkType(am_SinkType_s & sinkType) const - { - sinkType.name = name; - sinkType.sinkID = sinkID; - sinkType.availability = available; - sinkType.muteState = muteState; - sinkType.volume = mainVolume; - sinkType.sinkClassID = sinkClassID; - }; - am_Sink_Database_s & operator=(const am_Sink_Database_s & anObject) - { - if (this != &anObject) - { - am_Sink_s::operator=(anObject); - reserved = anObject.reserved; - } - return *this; - }; - am_Sink_Database_s & operator=(const am_Sink_s & anObject) - { - if (this != &anObject) - am_Sink_s::operator=(anObject); - return *this; - }; - void print() const - { - printf("\n Sink(%s) id(%d)\n", name.c_str() ,sinkID); - printf("\t availability(%d) availabilityReason(%d) sinkClassID(%d) domainID(%d) visible(%d) volume(%d) mainVolume(%d) muteState(%d) reserved(%d)\n", - available.availability, available.availabilityReason, sinkClassID, domainID, visible, volume, mainVolume, muteState,reserved); - }; - }; - - struct am_Source_Database_s : public am_Source_s - { - bool reserved; - am_Source_Database_s():am_Source_s(), reserved(false) - {}; - void getSourceType(am_SourceType_s & sourceType) const - { - sourceType.name = name; - sourceType.sourceClassID = sourceClassID; - sourceType.availability = available; - sourceType.sourceID = sourceID; - }; - am_Source_Database_s & operator=(const am_Source_Database_s & anObject) - { - if (this != &anObject) - { - am_Source_s::operator=(anObject); - reserved = anObject.reserved; - } - return *this; - }; - am_Source_Database_s & operator=(const am_Source_s & anObject) - { - if (this != &anObject) - { - am_Source_s::operator=(anObject); - } - return *this; - }; - void print() const - { - printf("\n Source(%s) id(%d)\n", name.c_str() ,sourceID); - printf("\t availability(%d) availabilityReason(%d) sourceClassID(%d) domainID(%d) visible(%d) volume(%d) interruptState(%d) sourceState(%d) reserved(%d)\n", - available.availability, available.availabilityReason, sourceClassID, domainID, visible, volume, interruptState, sourceState,reserved); - }; - }; - - struct am_Connection_Database_s : public am_Connection_s - { - bool reserved; - am_Connection_Database_s():am_Connection_s(), reserved(true) - {}; - am_Connection_Database_s & operator=(const am_Connection_Database_s & anObject) - { - if (this != &anObject) - { - am_Connection_s::operator=(anObject); - reserved = anObject.reserved; - } - return *this; - }; - am_Connection_Database_s & operator=(const am_Connection_s & anObject) - { - if (this != &anObject) - am_Connection_s::operator=(anObject); - return *this; - }; - }; - - struct am_Domain_Database_s : public am_Domain_s - { - bool reserved; - am_Domain_Database_s():am_Domain_s(), reserved(false) - {}; - am_Domain_Database_s & operator=(const am_Domain_Database_s & anObject) - { - if (this != &anObject) - { - am_Domain_s::operator=(anObject); - reserved = anObject.reserved; - } - return *this; - }; - am_Domain_Database_s & operator=(const am_Domain_s & anObject) - { - if (this != &anObject) - am_Domain_s::operator=(anObject); - return *this; - }; - }; - - struct am_MainConnection_Database_s : public am_MainConnection_s - { - am_MainConnection_Database_s():am_MainConnection_s() - {}; - void getMainConnectionType(am_MainConnectionType_s & connectionType) const - { - connectionType.mainConnectionID = mainConnectionID; - connectionType.sourceID = sourceID; - connectionType.sinkID = sinkID; - connectionType.connectionState = connectionState; - connectionType.delay = delay; - }; - am_MainConnection_Database_s & operator=(const am_MainConnection_Database_s & anObject) - { - am_MainConnection_s::operator=(anObject); - return *this; - }; - am_MainConnection_Database_s & operator=(const am_MainConnection_s & anObject) - { - am_MainConnection_s::operator=(anObject); - return *this; - }; - }; +#define AM_TYPEDEF_SUBCLASS_BEGIN(Subclass, Class) \ + typedef struct Subclass : public Class\ + {\ + Subclass & operator=(const Subclass & anObject) \ + {\ + if (this != &anObject)\ + {\ + Class::operator=(anObject);\ + }\ + return *this;\ + };\ + Subclass & operator=(const Class & anObject)\ + {\ + if (this != &anObject)\ + Class::operator=(anObject);\ + return *this;\ + };\ + void getDescription (std::string & outString) const;\ + +#define AM_TYPEDEF_SUBCLASS_RESERVED_FLAG_BEGIN(Subclass, Class) \ + typedef struct Subclass : public Class\ + {\ + bool reserved;\ + Subclass():Class(), reserved(false)\ + {};\ + Subclass & operator=(const Subclass & anObject)\ + {\ + if (this != &anObject)\ + {\ + Class::operator=(anObject);\ + reserved = anObject.reserved;\ + }\ + return *this;\ + };\ + Subclass & operator=(const Class & anObject)\ + {\ + if (this != &anObject)\ + Class::operator=(anObject);\ + return *this;\ + };\ + void getDescription (std::string & outString) const;\ + +#define AM_TYPEDEF_SUBCLASS_END(Typedef) } Typedef; \ + + AM_TYPEDEF_SUBCLASS_RESERVED_FLAG_BEGIN(am_Domain_Database_s,am_Domain_s) + AM_TYPEDEF_SUBCLASS_END(CAmDomain) + + AM_TYPEDEF_SUBCLASS_RESERVED_FLAG_BEGIN(am_Sink_Database_s,am_Sink_s) + void getSinkType(am_SinkType_s & sinkType) const;\ + AM_TYPEDEF_SUBCLASS_END(CAmSink) + + AM_TYPEDEF_SUBCLASS_RESERVED_FLAG_BEGIN(am_Source_Database_s,am_Source_s) + void getSourceType(am_SourceType_s & sourceType) const;\ + AM_TYPEDEF_SUBCLASS_END(CAmSource) + + AM_TYPEDEF_SUBCLASS_RESERVED_FLAG_BEGIN(am_Connection_Database_s,am_Connection_s) + AM_TYPEDEF_SUBCLASS_END(CAmConnection) + + /** + * The following structures extend the base structures with print capabilities. + */ + AM_TYPEDEF_SUBCLASS_BEGIN(am_MainConnection_Database_s, am_MainConnection_s) + void getMainConnectionType(am_MainConnectionType_s & connectionType) const;\ + AM_TYPEDEF_SUBCLASS_END(CAmMainConnection) + + AM_TYPEDEF_SUBCLASS_BEGIN(am_SourceClass_Database_s, am_SourceClass_s) + AM_TYPEDEF_SUBCLASS_END(CAmSourceClass) + + AM_TYPEDEF_SUBCLASS_BEGIN(am_SinkClass_Database_s, am_SinkClass_s) + AM_TYPEDEF_SUBCLASS_END(CAmSinkClass) + + AM_TYPEDEF_SUBCLASS_BEGIN(am_Gateway_Database_s, am_Gateway_s) + AM_TYPEDEF_SUBCLASS_END(CAmGateway) + + AM_TYPEDEF_SUBCLASS_BEGIN(am_Crossfader_Database_s, am_Crossfader_s) + AM_TYPEDEF_SUBCLASS_END(CAmCrossfader) private: - typedef std::map CAmMapDomain; - typedef std::map CAmMapSourceClass; - typedef std::map CAmMapSinkClass; - typedef std::map CAmMapSink; - typedef std::map CAmMapSource; - typedef std::map CAmMapGateway; - typedef std::map CAmMapCrossfader; - typedef std::map CAmMapConnection; - typedef std::map CAmMapMainConnection; - typedef std::vector CAmVectorSystemProperties; + typedef AM_MAP CAmMapDomain; + typedef AM_MAP CAmMapSourceClass; + typedef AM_MAP CAmMapSinkClass; + typedef AM_MAP CAmMapSink; + typedef AM_MAP CAmMapSource; + typedef AM_MAP CAmMapGateway; + typedef AM_MAP CAmMapCrossfader; + typedef AM_MAP CAmMapConnection; + typedef AM_MAP CAmMapMainConnection; + typedef std::vector CAmVectorSystemProperties; typedef struct CAmMappedData { int16_t mCurrentDomainID; @@ -356,27 +295,10 @@ public: mGatewayMap(), mCrossfaderMap(), mConnectionMap(), mMainConnectionMap() {}; - bool increaseID(int16_t * resultID, int16_t * sourceID, int16_t const desiredStaticID = 0, int16_t const preferedStaticIDBoundary = DYNAMIC_ID_BOUNDARY) - { - if( desiredStaticID > 0 && desiredStaticID < preferedStaticIDBoundary ) - { - *resultID = desiredStaticID; - return true; - } - else if( *sourceID < mDefaultIDLimit-1 ) //SHRT_MAX or the max limit is reserved and not used!!! - { - *resultID = (*sourceID)++; - return true; - } - else - { - *resultID = -1; - return false; - } - }; + bool increaseID(int16_t * resultID, int16_t * sourceID, + int16_t const desiredStaticID, int16_t const preferedStaticIDBoundary ); } CAmMappedData; - CAmMappedData mMappedData; am_timeSync_t calculateMainConnectionDelay(const am_mainConnectionID_t mainConnectionID) const; //!< calculates a new main connection delay diff --git a/AudioManagerDaemon/include/CAmTelnetMenuHelper.h b/AudioManagerDaemon/include/CAmTelnetMenuHelper.h index 249d6d7..b73bf56 100644 --- a/AudioManagerDaemon/include/CAmTelnetMenuHelper.h +++ b/AudioManagerDaemon/include/CAmTelnetMenuHelper.h @@ -149,6 +149,8 @@ private: // INFO commands static void infoSystempropertiesCommand(std::queue & CmdQueue, int & filedescriptor); void infoSystempropertiesCommandExec(std::queue & CmdQueue, int & filedescriptor); + static void infoDumpCommand(std::queue& CmdQueue, int& filedescriptor); + void infoDumpCommandExec(std::queue& CmdQueue, int& filedescriptor); private: diff --git a/AudioManagerDaemon/include/CAmTelnetServer.h b/AudioManagerDaemon/include/CAmTelnetServer.h index 755ade3..8e590ee 100644 --- a/AudioManagerDaemon/include/CAmTelnetServer.h +++ b/AudioManagerDaemon/include/CAmTelnetServer.h @@ -42,7 +42,7 @@ class CAmRouter; class CAmTelnetMenuHelper; /** - * Implements a telnetserver that can be used to connect to the audiomanager, retrieve some information and use it. For debugginp purposes. + * Implements a telnetserver that can be used to connect to the audiomanager, retrieve some information and use it. For debugging purposes. * For example, launch a telnet session on port 6060: * \code telnet localhost 6060 \endcode * more details can be found at the README -- cgit v1.2.1