* routing algorithm improvements
authorchristian mueller <christian.ei.mueller@bmw.de>
Wed, 25 Jan 2012 15:34:37 +0000 (16:34 +0100)
committerchristian mueller <christian.ei.mueller@bmw.de>
Wed, 25 Jan 2012 15:34:37 +0000 (16:34 +0100)
* routing algorithms first tests

15 files changed:
AudioManagerDaemon/include/DatabaseHandler.h
AudioManagerDaemon/include/Router.h
AudioManagerDaemon/src/DatabaseHandler.cpp
AudioManagerDaemon/src/Router.cpp
AudioManagerDaemon/src/main.cpp
AudioManagerDaemon/test/CMakeLists.txt
AudioManagerDaemon/test/controlInterface/MockInterfaces.h
AudioManagerDaemon/test/database/CMakeLists.txt
AudioManagerDaemon/test/database/databaseTest.cpp
AudioManagerDaemon/test/routing/CMakeLists.txt [new file with mode: 0644]
AudioManagerDaemon/test/routing/MockInterfaces.h [new file with mode: 0644]
AudioManagerDaemon/test/routing/routingTest.cpp [new file with mode: 0644]
AudioManagerDaemon/test/routing/routingTest.h [new file with mode: 0644]
AudioManagerDaemon/test/routingInterface/CMakeLists.txt
includes/config.h

index 5d1cac7..96065bd 100644 (file)
@@ -28,6 +28,7 @@
 #include "audiomanagertypes.h"
 #include <sqlite3.h>
 #include <map>
+#include <list>
 
 namespace am
 {
@@ -130,7 +131,7 @@ public:
     am_Error_e getDomainOfSink(const am_sinkID_t sinkID, am_domainID_t& domainID) const;
     am_Error_e getSoureState(const am_sourceID_t sourceID, am_SourceState_e& sourceState) const;
     am_Error_e getDomainState(const am_domainID_t domainID, am_DomainState_e state) const;
-    am_Error_e getRoutingTree(bool onlyfree, RoutingTree* tree, std::vector<RoutingTreeItem*>* flatTree);
+    am_Error_e getRoutingTree(bool onlyfree, RoutingTree& tree, std::vector<RoutingTreeItem*>& flatTree);
     am_Error_e peekDomain(const std::string& name, am_domainID_t& domainID);
     am_Error_e peekSink(const std::string& name, am_sinkID_t& sinkID);
     am_Error_e peekSource(const std::string& name, am_sourceID_t& sourceID);
index 8fb859b..68e33b6 100644 (file)
@@ -31,11 +31,12 @@ namespace am
 {
 
 class DatabaseHandler;
+class ControlSender;
 
 class Router
 {
 public:
-    Router(DatabaseHandler* iDatabaseHandler);
+    Router(DatabaseHandler* iDatabaseHandler,ControlSender* iSender);
     am_Error_e getRoute(const bool onlyfree, const am_sourceID_t sourceID, const am_sinkID_t sinkID, std::vector<am_Route_s>& returnList);
     virtual ~Router();
 
@@ -44,6 +45,7 @@ private:
     void listPossibleConnectionFormats(const am_sourceID_t sourceID, const am_sinkID_t sinkID, std::vector<am_ConnectionFormat_e>& listFormats) const;
     void listRestrictedOutputFormatsGateways(const am_gatewayID_t gatewayID, const am_ConnectionFormat_e sinkConnectionFormat, std::vector<am_ConnectionFormat_e>& listFormats) const;
     DatabaseHandler* mDatabaseHandler;
+    ControlSender* mControlSender;
 };
 
 class RoutingTreeItem
@@ -68,7 +70,7 @@ class RoutingTree
 public:
     RoutingTree(const am_domainID_t rootDomainID);
     RoutingTreeItem* insertItem(const am_domainID_t domainID, const am_gatewayID_t gatewayID, RoutingTreeItem *parent);
-    void getRoute(RoutingTreeItem* targetItem, std::vector<am_gatewayID_t>* listGateways);
+    void getRoute(RoutingTreeItem* targetItem, std::vector<am_gatewayID_t>& listGateways);
     am_domainID_t returnRootDomainID() const;
     RoutingTreeItem* returnRootItem();
     virtual ~RoutingTree();
index 6a17b2b..5c834ee 100644 (file)
@@ -169,7 +169,8 @@ am_Error_e DatabaseHandler::enterDomainDB(const am_Domain_s & domainData, am_dom
 
     am_Domain_s domain = domainData;
     domain.domainID = domainID;
-    if (mDatabaseObserver) mDatabaseObserver->newDomain(domain);
+    if (mDatabaseObserver)
+        mDatabaseObserver->newDomain(domain);
 
     return E_OK;
 }
@@ -271,7 +272,8 @@ am_Error_e DatabaseHandler::enterMainConnectionDB(const am_MainConnection_s & ma
     }
 
     //finally, we update the delay value for the maintable
-    if (delay == 0) delay = -1;
+    if (delay == 0)
+        delay = -1;
     return changeDelayMainConnection(delay, connectionID);
 }
 
@@ -444,7 +446,8 @@ am_Error_e DatabaseHandler::enterSinkDB(const am_Sink_s & sinkData, am_sinkID_t
 
     am_Sink_s sink = sinkData;
     sink.sinkID = sinkID;
-    if (mDatabaseObserver != NULL) mDatabaseObserver->newSink(sink);
+    if (mDatabaseObserver != NULL)
+        mDatabaseObserver->newSink(sink);
 
     return E_OK;
 }
@@ -482,7 +485,8 @@ am_Error_e DatabaseHandler::enterGatewayDB(const am_Gateway_s & gatewayData, am_
     else
     {
         //check if the ID already exists
-        if (existGateway(gatewayData.gatewayID)) return E_ALREADY_EXISTS;
+        if (existGateway(gatewayData.gatewayID))
+            return E_ALREADY_EXISTS;
         command = "INSERT INTO " + std::string(GATEWAY_TABLE) + "(name, sinkID, sourceID, domainSinkID, domainSourceID, controlDomainID, gatewayID, inUse) VALUES (?,?,?,?,?,?,?,0)";
     }
 
@@ -562,7 +566,8 @@ am_Error_e DatabaseHandler::enterGatewayDB(const am_Gateway_s & gatewayData, am_
 
     am_Gateway_s gateway = gatewayData;
     gateway.gatewayID = gatewayID;
-    if (mDatabaseObserver) mDatabaseObserver->newGateway(gateway);
+    if (mDatabaseObserver)
+        mDatabaseObserver->newGateway(gateway);
     return E_OK;
 }
 
@@ -736,7 +741,8 @@ am_Error_e DatabaseHandler::enterSourceDB(const am_Source_s & sourceData, am_sou
 
     am_Source_s source = sourceData;
     source.sourceID = sourceID;
-    if (mDatabaseObserver) mDatabaseObserver->newSource(source);
+    if (mDatabaseObserver)
+        mDatabaseObserver->newSource(source);
     return E_OK;
 }
 
@@ -837,7 +843,8 @@ am_Error_e DatabaseHandler::changeMainConnectionStateDB(const am_mainConnectionI
         return E_DATABASE_ERROR;
     }DLT_LOG(AudioManager, DLT_LOG_INFO, DLT_STRING("DatabaseHandler::changeMainConnectionStateDB changed mainConnectionState of MainConnection:"), DLT_INT(mainconnectionID), DLT_STRING("to:"), DLT_INT(connectionState));
 
-    if (mDatabaseObserver) mDatabaseObserver->mainConnectionStateChanged(mainconnectionID, connectionState);
+    if (mDatabaseObserver)
+        mDatabaseObserver->mainConnectionStateChanged(mainconnectionID, connectionState);
     return E_OK;
 }
 
@@ -869,7 +876,8 @@ am_Error_e DatabaseHandler::changeSinkMainVolumeDB(const am_mainVolume_t mainVol
 
     DLT_LOG(AudioManager, DLT_LOG_INFO, DLT_STRING("DatabaseHandler::changeSinkMainVolumeDB changed mainVolume of sink:"), DLT_INT(sinkID), DLT_STRING("to:"), DLT_INT(mainVolume));
 
-    if (mDatabaseObserver) mDatabaseObserver->volumeChanged(sinkID, mainVolume);
+    if (mDatabaseObserver)
+        mDatabaseObserver->volumeChanged(sinkID, mainVolume);
 
     return E_OK;
 }
@@ -904,7 +912,8 @@ am_Error_e DatabaseHandler::changeSinkAvailabilityDB(const am_Availability_s & a
 
     DLT_LOG(AudioManager, DLT_LOG_INFO, DLT_STRING("DatabaseHandler::changeSinkAvailabilityDB changed sinkAvailability of sink:"), DLT_INT(sinkID), DLT_STRING("to:"), DLT_INT(availability.availability), DLT_STRING("Reason:"), DLT_INT(availability.availabilityReason));
 
-    if (mDatabaseObserver && sourceVisible(sinkID)) mDatabaseObserver->sinkAvailabilityChanged(sinkID, availability);
+    if (mDatabaseObserver && sourceVisible(sinkID))
+        mDatabaseObserver->sinkAvailabilityChanged(sinkID, availability);
     return E_OK;
 }
 
@@ -968,7 +977,8 @@ am_Error_e DatabaseHandler::changeSinkMuteStateDB(const am_MuteState_e muteState
 
     DLT_LOG(AudioManager, DLT_LOG_INFO, DLT_STRING("DatabaseHandler::changeSinkMuteStateDB changed sinkMuteState of sink:"), DLT_INT(sinkID), DLT_STRING("to:"), DLT_INT(muteState));
 
-    if (mDatabaseObserver) mDatabaseObserver->sinkMuteStateChanged(sinkID, muteState);
+    if (mDatabaseObserver)
+        mDatabaseObserver->sinkMuteStateChanged(sinkID, muteState);
 
     return E_OK;
 }
@@ -1002,7 +1012,8 @@ am_Error_e DatabaseHandler::changeMainSinkSoundPropertyDB(const am_MainSoundProp
     }
 
     DLT_LOG(AudioManager, DLT_LOG_INFO, DLT_STRING("DatabaseHandler::changeMainSinkSoundPropertyDB changed MainSinkSoundProperty of sink:"), DLT_INT(sinkID), DLT_STRING("type:"), DLT_INT(soundProperty.type), DLT_STRING("to:"), DLT_INT(soundProperty.value));
-    if (mDatabaseObserver) mDatabaseObserver->mainSinkSoundPropertyChanged(sinkID, soundProperty);
+    if (mDatabaseObserver)
+        mDatabaseObserver->mainSinkSoundPropertyChanged(sinkID, soundProperty);
     return E_OK;
 }
 
@@ -1036,7 +1047,8 @@ am_Error_e DatabaseHandler::changeMainSourceSoundPropertyDB(const am_MainSoundPr
 
     DLT_LOG(AudioManager, DLT_LOG_INFO, DLT_STRING("DatabaseHandler::changeMainSourceSoundPropertyDB changed MainSinkSoundProperty of source:"), DLT_INT(sourceID), DLT_STRING("type:"), DLT_INT(soundProperty.type), DLT_STRING("to:"), DLT_INT(soundProperty.value));
 
-    if (mDatabaseObserver) mDatabaseObserver->mainSourceSoundPropertyChanged(sourceID, soundProperty);
+    if (mDatabaseObserver)
+        mDatabaseObserver->mainSourceSoundPropertyChanged(sourceID, soundProperty);
     return E_OK;
 }
 
@@ -1070,7 +1082,8 @@ am_Error_e DatabaseHandler::changeSourceAvailabilityDB(const am_Availability_s &
 
     DLT_LOG(AudioManager, DLT_LOG_INFO, DLT_STRING("DatabaseHandler::changeSourceAvailabilityDB changed changeSourceAvailabilityDB of source:"), DLT_INT(sourceID), DLT_STRING("to:"), DLT_INT(availability.availability), DLT_STRING("Reason:"), DLT_INT(availability.availabilityReason));
 
-    if (mDatabaseObserver && sourceVisible(sourceID)) mDatabaseObserver->sourceAvailabilityChanged(sourceID, availability);
+    if (mDatabaseObserver && sourceVisible(sourceID))
+        mDatabaseObserver->sourceAvailabilityChanged(sourceID, availability);
     return E_OK;
 }
 
@@ -1098,7 +1111,8 @@ am_Error_e DatabaseHandler::changeSystemPropertyDB(const am_SystemProperty_s & p
 
     DLT_LOG(AudioManager, DLT_LOG_INFO, DLT_STRING("DatabaseHandler::changeSystemPropertyDB changed system property"));
 
-    if (mDatabaseObserver) mDatabaseObserver->systemPropertyChanged(property);
+    if (mDatabaseObserver)
+        mDatabaseObserver->systemPropertyChanged(property);
 
     return E_OK;
 }
@@ -1113,8 +1127,10 @@ am_Error_e DatabaseHandler::removeMainConnectionDB(const am_mainConnectionID_t m
     }
     std::string command = "DELETE from " + std::string(MAINCONNECTION_TABLE) + " WHERE mainConnectionID=" + i2s(mainConnectionID);
     std::string command1 = "DROP table MainConnectionRoute" + i2s(mainConnectionID);
-    if (!sqQuery(command)) return E_DATABASE_ERROR;
-    if (!sqQuery(command1)) return E_DATABASE_ERROR;DLT_LOG(AudioManager, DLT_LOG_INFO, DLT_STRING("DatabaseHandler::removeMainConnectionDB removed:"), DLT_INT(mainConnectionID));
+    if (!sqQuery(command))
+        return E_DATABASE_ERROR;
+    if (!sqQuery(command1))
+        return E_DATABASE_ERROR;DLT_LOG(AudioManager, DLT_LOG_INFO, DLT_STRING("DatabaseHandler::removeMainConnectionDB removed:"), DLT_INT(mainConnectionID));
     if (mDatabaseObserver)
     {
         mDatabaseObserver->mainConnectionStateChanged(mainConnectionID, CS_DISCONNECTED);
@@ -1135,12 +1151,17 @@ am_Error_e DatabaseHandler::removeSinkDB(const am_sinkID_t sinkID)
     std::string command1 = "DROP table SinkConnectionFormat" + i2s(sinkID);
     std::string command2 = "DROP table SinkMainSoundProperty" + i2s(sinkID);
     std::string command3 = "DROP table SinkSoundProperty" + i2s(sinkID);
-    if (!sqQuery(command)) return E_DATABASE_ERROR;
-    if (!sqQuery(command1)) return E_DATABASE_ERROR;
-    if (!sqQuery(command2)) return E_DATABASE_ERROR;
-    if (!sqQuery(command3)) return E_DATABASE_ERROR;DLT_LOG(AudioManager, DLT_LOG_INFO, DLT_STRING("DatabaseHandler::removeSinkDB removed:"), DLT_INT(sinkID));
+    if (!sqQuery(command))
+        return E_DATABASE_ERROR;
+    if (!sqQuery(command1))
+        return E_DATABASE_ERROR;
+    if (!sqQuery(command2))
+        return E_DATABASE_ERROR;
+    if (!sqQuery(command3))
+        return E_DATABASE_ERROR;DLT_LOG(AudioManager, DLT_LOG_INFO, DLT_STRING("DatabaseHandler::removeSinkDB removed:"), DLT_INT(sinkID));
 
-    if (mDatabaseObserver != NULL) mDatabaseObserver->removedSink(sinkID);
+    if (mDatabaseObserver != NULL)
+        mDatabaseObserver->removedSink(sinkID);
 
     return E_OK;
 }
@@ -1157,11 +1178,16 @@ am_Error_e DatabaseHandler::removeSourceDB(const am_sourceID_t sourceID)
     std::string command1 = "DROP table SourceConnectionFormat" + i2s(sourceID);
     std::string command2 = "DROP table SourceMainSoundProperty" + i2s(sourceID);
     std::string command3 = "DROP table SourceSoundProperty" + i2s(sourceID);
-    if (!sqQuery(command)) return E_DATABASE_ERROR;
-    if (!sqQuery(command1)) return E_DATABASE_ERROR;
-    if (!sqQuery(command2)) return E_DATABASE_ERROR;
-    if (!sqQuery(command3)) return E_DATABASE_ERROR;DLT_LOG(AudioManager, DLT_LOG_INFO, DLT_STRING("DatabaseHandler::removeSourceDB removed:"), DLT_INT(sourceID));
-    if (mDatabaseObserver) mDatabaseObserver->removedSource(sourceID);
+    if (!sqQuery(command))
+        return E_DATABASE_ERROR;
+    if (!sqQuery(command1))
+        return E_DATABASE_ERROR;
+    if (!sqQuery(command2))
+        return E_DATABASE_ERROR;
+    if (!sqQuery(command3))
+        return E_DATABASE_ERROR;DLT_LOG(AudioManager, DLT_LOG_INFO, DLT_STRING("DatabaseHandler::removeSourceDB removed:"), DLT_INT(sourceID));
+    if (mDatabaseObserver)
+        mDatabaseObserver->removedSource(sourceID);
     return E_OK;
 }
 
@@ -1174,8 +1200,10 @@ am_Error_e DatabaseHandler::removeGatewayDB(const am_gatewayID_t gatewayID)
         return E_NON_EXISTENT;
     }
     std::string command = "DELETE from " + std::string(GATEWAY_TABLE) + " WHERE gatewayID=" + i2s(gatewayID);
-    if (!sqQuery(command)) return E_DATABASE_ERROR;DLT_LOG(AudioManager, DLT_LOG_INFO, DLT_STRING("DatabaseHandler::removeGatewayDB removed:"), DLT_INT(gatewayID));
-    if (mDatabaseObserver) mDatabaseObserver->removeGateway(gatewayID);
+    if (!sqQuery(command))
+        return E_DATABASE_ERROR;DLT_LOG(AudioManager, DLT_LOG_INFO, DLT_STRING("DatabaseHandler::removeGatewayDB removed:"), DLT_INT(gatewayID));
+    if (mDatabaseObserver)
+        mDatabaseObserver->removeGateway(gatewayID);
     return E_OK;
 }
 
@@ -1195,8 +1223,10 @@ am_Error_e DatabaseHandler::removeDomainDB(const am_domainID_t domainID)
         return E_NON_EXISTENT;
     }
     std::string command = "DELETE from " + std::string(DOMAIN_TABLE) + " WHERE domainID=" + i2s(domainID);
-    if (!sqQuery(command)) return E_DATABASE_ERROR;DLT_LOG(AudioManager, DLT_LOG_INFO, DLT_STRING("DatabaseHandler::removeDomainDB removed:"), DLT_INT(domainID));
-    if (mDatabaseObserver) mDatabaseObserver->removeDomain(domainID);
+    if (!sqQuery(command))
+        return E_DATABASE_ERROR;DLT_LOG(AudioManager, DLT_LOG_INFO, DLT_STRING("DatabaseHandler::removeDomainDB removed:"), DLT_INT(domainID));
+    if (mDatabaseObserver)
+        mDatabaseObserver->removeDomain(domainID);
     return E_OK;
 }
 
@@ -1210,11 +1240,14 @@ am_Error_e DatabaseHandler::removeSinkClassDB(const am_sinkClass_t sinkClassID)
     }
     std::string command = "DELETE from " + std::string(SINK_CLASS_TABLE) + " WHERE sinkClassID=" + i2s(sinkClassID);
     std::string command1 = "DROP table SinkClassProperties" + i2s(sinkClassID);
-    if (!sqQuery(command)) return E_DATABASE_ERROR;
-    if (!sqQuery(command1)) return E_DATABASE_ERROR;
+    if (!sqQuery(command))
+        return E_DATABASE_ERROR;
+    if (!sqQuery(command1))
+        return E_DATABASE_ERROR;
 
     DLT_LOG(AudioManager, DLT_LOG_INFO, DLT_STRING("DatabaseHandler::removeSinkClassDB removed:"), DLT_INT(sinkClassID));
-    if (mDatabaseObserver) mDatabaseObserver->numberOfSinkClassesChanged();
+    if (mDatabaseObserver)
+        mDatabaseObserver->numberOfSinkClassesChanged();
 
     return E_OK;
 }
@@ -1229,10 +1262,13 @@ am_Error_e DatabaseHandler::removeSourceClassDB(const am_sourceClass_t sourceCla
     }
     std::string command = "DELETE from " + std::string(SOURCE_CLASS_TABLE) + " WHERE sourceClassID=" + i2s(sourceClassID);
     std::string command1 = "DROP table SourceClassProperties" + i2s(sourceClassID);
-    if (!sqQuery(command)) return E_DATABASE_ERROR;
-    if (!sqQuery(command1)) return E_DATABASE_ERROR;DLT_LOG(AudioManager, DLT_LOG_INFO, DLT_STRING("DatabaseHandler::removeSourceClassDB removed:"), DLT_INT(sourceClassID));
+    if (!sqQuery(command))
+        return E_DATABASE_ERROR;
+    if (!sqQuery(command1))
+        return E_DATABASE_ERROR;DLT_LOG(AudioManager, DLT_LOG_INFO, DLT_STRING("DatabaseHandler::removeSourceClassDB removed:"), DLT_INT(sourceClassID));
 
-    if (mDatabaseObserver) mDatabaseObserver->numberOfSourceClassesChanged();
+    if (mDatabaseObserver)
+        mDatabaseObserver->numberOfSourceClassesChanged();
     return E_OK;
 }
 
@@ -1242,8 +1278,10 @@ am_Error_e DatabaseHandler::removeConnection(const am_connectionID_t connectionI
 
     std::string command = "DELETE from " + std::string(CONNECTION_TABLE) + " WHERE connectionID=" + i2s(connectionID);
     std::string command1 = "DROP table SourceClassProperties" + i2s(connectionID);
-    if (!sqQuery(command)) return E_DATABASE_ERROR;
-    if (!sqQuery(command1)) return E_DATABASE_ERROR;DLT_LOG(AudioManager, DLT_LOG_INFO, DLT_STRING("DatabaseHandler::removeConnection removed:"), DLT_INT(connectionID));
+    if (!sqQuery(command))
+        return E_DATABASE_ERROR;
+    if (!sqQuery(command1))
+        return E_DATABASE_ERROR;DLT_LOG(AudioManager, DLT_LOG_INFO, DLT_STRING("DatabaseHandler::removeConnection removed:"), DLT_INT(connectionID));
 
     return E_OK;
 }
@@ -1332,7 +1370,8 @@ am_Error_e DatabaseHandler::changeSinkClassInfoDB(const am_SinkClass_s& sinkClas
     int eCode = 0;
 
     //check if the ID already exists
-    if (!existSinkClass(sinkClass.sinkClassID)) return E_NON_EXISTENT;
+    if (!existSinkClass(sinkClass.sinkClassID))
+        return E_NON_EXISTENT;
 
     //fill ConnectionFormats
     std::string command = "UPDATE SinkClassProperties" + i2s(sinkClass.sinkClassID) + " set value=? WHERE classProperty=?;";
@@ -1369,7 +1408,8 @@ am_Error_e DatabaseHandler::changeSourceClassInfoDB(const am_SourceClass_s& sour
     int eCode = 0;
 
     //check if the ID already exists
-    if (!existSourceClass(sourceClass.sourceClassID)) return E_NON_EXISTENT;
+    if (!existSourceClass(sourceClass.sourceClassID))
+        return E_NON_EXISTENT;
 
     //fill ConnectionFormats
     std::string command = "UPDATE SourceClassProperties" + i2s(sourceClass.sourceClassID) + " set value=? WHERE classProperty=?;";
@@ -2300,7 +2340,8 @@ am_Error_e DatabaseHandler::getListMainSources(std::vector<am_SourceType_s> & li
 am_Error_e DatabaseHandler::getListMainSinkSoundProperties(const am_sinkID_t sinkID, std::vector<am_MainSoundProperty_s> & listSoundProperties) const
 {
     assert(sinkID!=0);
-    if (!existSink(sinkID)) return E_DATABASE_ERROR; // todo: here we could change to non existen, but not shown in sequences
+    if (!existSink(sinkID))
+        return E_DATABASE_ERROR; // todo: here we could change to non existen, but not shown in sequences
     listSoundProperties.clear();
 
     sqlite3_stmt* query = NULL;
@@ -2334,7 +2375,8 @@ am_Error_e DatabaseHandler::getListMainSinkSoundProperties(const am_sinkID_t sin
 am_Error_e DatabaseHandler::getListMainSourceSoundProperties(const am_sourceID_t sourceID, std::vector<am_MainSoundProperty_s> & listSourceProperties) const
 {
     assert(sourceID!=0);
-    if (!existSource(sourceID)) return E_DATABASE_ERROR; // todo: here we could change to non existen, but not shown in sequences
+    if (!existSource(sourceID))
+        return E_DATABASE_ERROR; // todo: here we could change to non existen, but not shown in sequences
     listSourceProperties.clear();
 
     sqlite3_stmt* query = NULL;
@@ -2486,7 +2528,8 @@ am_Error_e DatabaseHandler::getTimingInformation(const am_mainConnectionID_t mai
         return E_DATABASE_ERROR;
     }
 
-    if (delay == -1) return E_NOT_POSSIBLE;
+    if (delay == -1)
+        return E_NOT_POSSIBLE;
 
     return E_OK;
 }
@@ -2545,7 +2588,8 @@ am_Error_e DatabaseHandler::changeDelayMainConnection(const am_timeSync_t & dela
         return E_DATABASE_ERROR;
     }
 
-    if (mDatabaseObserver) mDatabaseObserver->timingInformationChanged(connectionID, delay);
+    if (mDatabaseObserver)
+        mDatabaseObserver->timingInformationChanged(connectionID, delay);
 
     return E_OK;
 }
@@ -2604,7 +2648,8 @@ am_Error_e DatabaseHandler::enterSinkClassDB(const am_SinkClass_s & sinkClass, a
     else
     {
         //check if the ID already exists
-        if (existSinkClass(sinkClass.sinkClassID)) return E_ALREADY_EXISTS;
+        if (existSinkClass(sinkClass.sinkClassID))
+            return E_ALREADY_EXISTS;
         command = "INSERT INTO " + std::string(SINK_CLASS_TABLE) + "(name, sinkClassID) VALUES (?,?)";
     }
 
@@ -2665,7 +2710,8 @@ am_Error_e DatabaseHandler::enterSinkClassDB(const am_SinkClass_s & sinkClass, a
     }
 
     DLT_LOG(AudioManager, DLT_LOG_INFO, DLT_STRING("DatabaseHandler::enterSinkClassDB entered new sinkClass"));
-    if (mDatabaseObserver) mDatabaseObserver->numberOfSinkClassesChanged();
+    if (mDatabaseObserver)
+        mDatabaseObserver->numberOfSinkClassesChanged();
     return E_OK;
 }
 
@@ -2687,7 +2733,8 @@ am_Error_e DatabaseHandler::enterSourceClassDB(am_sourceClass_t & sourceClassID,
     else
     {
         //check if the ID already exists
-        if (existSourceClass(sourceClass.sourceClassID)) return E_ALREADY_EXISTS;
+        if (existSourceClass(sourceClass.sourceClassID))
+            return E_ALREADY_EXISTS;
         command = "INSERT INTO " + std::string(SOURCE_CLASS_TABLE) + "(name, sourceClassID) VALUES (?,?)";
     }
 
@@ -2749,7 +2796,8 @@ am_Error_e DatabaseHandler::enterSourceClassDB(am_sourceClass_t & sourceClassID,
 
     DLT_LOG(AudioManager, DLT_LOG_INFO, DLT_STRING("DatabaseHandler::enterSourceClassDB entered new sourceClass"));
 
-    if (mDatabaseObserver) mDatabaseObserver->numberOfSourceClassesChanged();
+    if (mDatabaseObserver)
+        mDatabaseObserver->numberOfSourceClassesChanged();
     return E_OK;
 }
 
@@ -3153,7 +3201,8 @@ am_timeSync_t DatabaseHandler::calculateMainConnectionDelay(const am_mainConnect
         DLT_LOG(AudioManager, DLT_LOG_ERROR, DLT_STRING("DatabaseHandler::calculateMainConnectionDelay SQLITE Finalize error code:"), DLT_INT(eCode));
         return E_DATABASE_ERROR;
     }
-    if (min < 0) delay = -1;
+    if (min < 0)
+        delay = -1;
     return delay;
 
 }
@@ -3351,7 +3400,8 @@ am_Error_e DatabaseHandler::getSourceVolume(const am_sourceID_t sourceID, am_vol
 am_Error_e DatabaseHandler::getSinkSoundPropertyValue(const am_sinkID_t sinkID, const am_SoundPropertyType_e propertyType, uint16_t & value) const
 {
     assert(sinkID!=0);
-    if (!existSink(sinkID)) return E_DATABASE_ERROR; // todo: here we could change to non existent, but not shown in sequences
+    if (!existSink(sinkID))
+        return E_DATABASE_ERROR; // todo: here we could change to non existent, but not shown in sequences
 
     sqlite3_stmt* query = NULL;
     int eCode = 0;
@@ -3381,7 +3431,8 @@ am_Error_e DatabaseHandler::getSinkSoundPropertyValue(const am_sinkID_t sinkID,
 am_Error_e DatabaseHandler::getSourceSoundPropertyValue(const am_sourceID_t sourceID, const am_SoundPropertyType_e propertyType, uint16_t & value) const
 {
     assert(sourceID!=0);
-    if (!existSource(sourceID)) return E_DATABASE_ERROR; // todo: here we could change to non existent, but not shown in sequences
+    if (!existSource(sourceID))
+        return E_DATABASE_ERROR; // todo: here we could change to non existent, but not shown in sequences
 
     sqlite3_stmt* query = NULL;
     int eCode = 0;
@@ -3722,25 +3773,31 @@ am_Error_e DatabaseHandler::changeCrossFaderHotSink(const am_crossfaderID_t cros
     return E_OK;
 }
 
-am_Error_e am::DatabaseHandler::getRoutingTree(bool onlyfree, RoutingTree *tree, std::vector<RoutingTreeItem*> *flatTree)
+am_Error_e DatabaseHandler::getRoutingTree(bool onlyfree, RoutingTree& tree, std::vector<RoutingTreeItem*>& flatTree)
 {
     sqlite3_stmt* query = NULL;
     int eCode = 0;
     size_t i = 0;
     std::string command;
-    am_domainID_t rootID = tree->returnRootDomainID();
-    RoutingTreeItem *parent = tree->returnRootItem();
+    am_domainID_t rootID = tree.returnRootDomainID();
+    RoutingTreeItem *parent = tree.returnRootItem();
 
     command = "SELECT domainSourceID,gatewayID FROM " + std::string(GATEWAY_TABLE) + " WHERE domainSinkID=? AND inUse=?";
 
-    sqlite3_prepare_v2(mDatabase, command.c_str(), -1, &query, NULL);
     do
     {
+        if (i != 0)
+        {
+            parent = flatTree.at(i - 1);
+            rootID = parent->returnDomainID();
+        }
+        sqlite3_prepare_v2(mDatabase, command.c_str(), -1, &query, NULL);
         sqlite3_bind_int(query, 1, rootID);
         sqlite3_bind_int(query, 2, onlyfree);
+
         while ((eCode = sqlite3_step(query)) == SQLITE_ROW)
         {
-            flatTree->push_back(tree->insertItem(sqlite3_column_int(query, 0), sqlite3_column_int(query, 1), parent));
+            flatTree.push_back(tree.insertItem(sqlite3_column_int(query, 0), sqlite3_column_int(query, 1), parent));
         }
 
         if (eCode != SQLITE_DONE)
@@ -3748,16 +3805,14 @@ am_Error_e am::DatabaseHandler::getRoutingTree(bool onlyfree, RoutingTree *tree,
             DLT_LOG(AudioManager, DLT_LOG_ERROR, DLT_STRING("DatabaseHandler::getRoutingTree SQLITE error code:"), DLT_INT(eCode));
             return (E_DATABASE_ERROR);
         }
-        parent = flatTree->at(i);
-        rootID = parent->returnDomainID();
-        i++;
-    } while (flatTree->size() > i);
 
-    if ((eCode = sqlite3_finalize(query)) != SQLITE_OK)
-    {
-        DLT_LOG(AudioManager, DLT_LOG_ERROR, DLT_STRING("DatabaseHandler::getRoutingTree SQLITE Finalize error code:"), DLT_INT(eCode));
-        return (E_DATABASE_ERROR);
-    }
+        if ((eCode = sqlite3_finalize(query)) != SQLITE_OK)
+        {
+            DLT_LOG(AudioManager, DLT_LOG_ERROR, DLT_STRING("DatabaseHandler::getRoutingTree SQLITE Finalize error code:"), DLT_INT(eCode));
+            return (E_DATABASE_ERROR);
+        }
+        i++;
+    } while (flatTree.size() > (i - 1));
 
     return (E_OK);
 }
index e7c9096..aec487c 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "Router.h"
 #include "DatabaseHandler.h"
+#include "ControlSender.h"
 #include <assert.h>
 #include <algorithm>
 #include <vector>
 
 using namespace am;
 
-am_Error_e getConnectionFormatChoice(const am_sinkID_t, const am_sourceID_t, const std::vector<am_ConnectionFormat_e>& listPossibleConnectionFormats, std::vector<am_ConnectionFormat_e>& listPriorityConnectionFormats)
-{
-    listPriorityConnectionFormats = listPossibleConnectionFormats;
-    return (E_OK);
-}
-
-Router::Router(DatabaseHandler *iDatabaseHandler) :
-        mDatabaseHandler(iDatabaseHandler)
+Router::Router(DatabaseHandler* iDatabaseHandler, ControlSender* iSender) :
+        mDatabaseHandler(iDatabaseHandler), //
+        mControlSender(iSender)
 {
     assert(mDatabaseHandler);
+    assert(mControlSender);
 }
 
 am_Error_e Router::getRoute(const bool onlyfree, const am_sourceID_t sourceID, const am_sinkID_t sinkID, std::vector<am_Route_s> & returnList)
@@ -55,7 +52,7 @@ am_Error_e Router::getRoute(const bool onlyfree, const am_sourceID_t sourceID, c
 
     RoutingTree routingtree(sourceDomainID); //Build up a Tree from the Source_Domain to every other domain.
     std::vector<RoutingTreeItem*> flattree; //This list is the flat tree
-    std::vector<RoutingTreeItem*> matchtree; //This List holds all TreeItems which have the right Domain Sink IDs
+    std::vector<RoutingTreeItem*> matchtree;
     std::vector<am_gatewayID_t> listGatewayID; //holds all gateway ids of the route
     am_RoutingElement_s routingElement;
     std::vector<am_RoutingElement_s> actualRoutingElement; //intermediate list of current routing pairs
@@ -63,24 +60,24 @@ am_Error_e Router::getRoute(const bool onlyfree, const am_sourceID_t sourceID, c
     am_sourceID_t lastSource = 0;
 
     //TODO: kind of unclean. The separation between database and router could be better.
-    mDatabaseHandler->getRoutingTree(onlyfree, &routingtree, &flattree); //Build up the tree out of the database as
+    mDatabaseHandler->getRoutingTree(onlyfree, routingtree, flattree); //Build up the tree out of the database as
 
     //we go through the returned flattree and look for our sink, after that flattree holds only treeItems that match
-    std::vector<RoutingTreeItem*>::iterator flatIterator = flattree.begin();
-    for (; flatIterator != flattree.end(); ++flatIterator)
+    std::vector<RoutingTreeItem*>::iterator iterator = flattree.begin();
+    for (; iterator != flattree.end(); ++iterator)
     {
-        if ((*flatIterator)->returnDomainID() != sinkDomainID)
+        if ((*iterator)->returnDomainID() == sinkDomainID)
         {
-            flatIterator = flattree.erase(flatIterator);
+            matchtree.push_back(*iterator);
         }
     }
 
     //No we need to trace back the routes for each entry in matchtree
-    flatIterator = flattree.begin();
-    for (; flatIterator != flattree.end(); ++flatIterator)
+    iterator = matchtree.begin();
+    for (; iterator != matchtree.end(); ++iterator)
     {
         //getting the route for the actual item
-        routingtree.getRoute(*flatIterator, &listGatewayID); //This gives only the Gateway IDs we need more
+        routingtree.getRoute(*iterator, listGatewayID); //This gives only the Gateway IDs we need more
 
         //go throught the gatewayids and get more information
         std::vector<am_gatewayID_t>::iterator gatewayIterator = listGatewayID.begin();
@@ -136,6 +133,7 @@ void Router::listPossibleConnectionFormats(const am_sourceID_t sourceID, const a
     mDatabaseHandler->getListSourceConnectionFormats(sourceID, listSourceFormats);
     std::insert_iterator<std::vector<am_ConnectionFormat_e> > inserter(listFormats, listFormats.begin());
     set_intersection(listSourceFormats.begin(), listSourceFormats.end(), listSinkFormats.begin(), listSinkFormats.end(), inserter);
+    std::vector<am_ConnectionFormat_e>::iterator it = listSourceFormats.begin();
 }
 
 am_Error_e Router::findBestWay(std::vector<am_RoutingElement_s> & listRoute, std::vector<am_RoutingElement_s>::iterator routeIterator, std::vector<am_gatewayID_t>::iterator gatewayIterator, int choiceNumber)
@@ -163,7 +161,7 @@ am_Error_e Router::findBestWay(std::vector<am_RoutingElement_s> & listRoute, std
     }
 
     //let the controller decide:
-    getConnectionFormatChoice(routeIterator->sinkID, routeIterator->sourceID, listConnectionFormats, listPriorityConnectionFormats);
+    mControlSender->getConnectionFormatChoice(routeIterator->sourceID, routeIterator->sinkID, listConnectionFormats, listPriorityConnectionFormats);
 
     //go back one step, if we cannot find a format and take the next best!
     if (listPriorityConnectionFormats.empty())
@@ -263,14 +261,16 @@ RoutingTreeItem *RoutingTree::insertItem(const am_domainID_t domainID, const am_
     return newTree;
 }
 
-void RoutingTree::getRoute(RoutingTreeItem *targetItem, std::vector<am_gatewayID_t> *listGateways)
+void RoutingTree::getRoute(RoutingTreeItem *targetItem, std::vector<am_gatewayID_t>listGateways)
 {
+    listGateways.clear();
     RoutingTreeItem *parentItem = targetItem;
     while (parentItem != &mRootItem)
     {
-        listGateways->push_back(parentItem->returnGatewayID());
+        listGateways.push_back(parentItem->returnGatewayID());
         parentItem = parentItem->returnParent();
     }
+    std::reverse(listGateways.begin(), listGateways.end());
 }
 
 am_domainID_t RoutingTree::returnRootDomainID() const
index d2ff042..ab51cee 100644 (file)
@@ -48,6 +48,7 @@
 #include "ControlReceiver.h"
 #include "DatabaseObserver.h"
 #include "TelnetServer.h"
+#include "Router.h"
 #include <sys/resource.h>
 #include <sys/stat.h>
 #include <unistd.h>
@@ -287,6 +288,8 @@ int main(int argc, char *argv[])
     DatabaseObserver iObserver(&iCommandSender, &iRoutingSender);
 #endif
 
+    Router iRouter(&iDatabaseHandler,&iControlSender);
+
     //since the plugins have been loaded by the *Senders before, we can tell the Controller this:
     iControlSender.hookAllPluginsLoaded();
 
index f00ec41..7450c99 100644 (file)
@@ -16,6 +16,7 @@ set(EXECUTABLE_OUTPUT_PATH ${TEST_EXECUTABLE_OUTPUT_PATH})
 FIND_PACKAGE(GTest REQUIRED) 
 
 add_subdirectory (database)
+add_subdirectory (routing)
 add_subdirectory (routingInterface)
 add_subdirectory (controlInterface)
 add_subdirectory (sockethandler)
index b4a4eec..9ac325f 100644 (file)
@@ -155,6 +155,8 @@ class MockControlSendInterface : public ControlSendInterface {
       void(const am_Handle_s handle, const am_Error_e error));
   MOCK_METHOD2(cbAckSetSinkSoundProperty,
       void(const am_Handle_s handle, const am_Error_e error));
+  MOCK_METHOD4(getConnectionFormatChoice,
+      am_Error_e(const am_sourceID_t sourceID, const am_sinkID_t sinkID, const std::vector<am_ConnectionFormat_e> listPossibleConnectionFormats, std::vector<am_ConnectionFormat_e>& listPrioConnectionFormats));
   MOCK_CONST_METHOD0(getInterfaceVersion,
       uint16_t());
 };
index 9e870d7..79aff0e 100644 (file)
@@ -49,6 +49,7 @@ file(GLOB DATABASE_SRCS_CXX
     "../../src/CommandSender.cpp"
     "../../src/RoutingSender.cpp"
     "../../src/ControlReceiver.cpp"
+    "../../src/ControlSender.cpp"
     "../../src/Router.cpp"
     "../CommonFunctions.cpp" 
     "*.cpp"
index 5d53610..9913011 100644 (file)
@@ -52,7 +52,7 @@ routingTest::routingTest() :
         pRoutingSender(plistRoutingPluginDirs), //
         pCommandSender(plistCommandPluginDirs), //
         pMockInterface(), //
-        pRoutingInterfaceBackdoor(),//
+        pRoutingInterfaceBackdoor(), //
         pCommandInterfaceBackdoor(), //
         pControlReceiver(&pDatabaseHandler, &pRoutingSender, &pCommandSender), //
         pObserver(&pCommandSender, &pRoutingSender)
diff --git a/AudioManagerDaemon/test/routing/CMakeLists.txt b/AudioManagerDaemon/test/routing/CMakeLists.txt
new file mode 100644 (file)
index 0000000..07d9b04
--- /dev/null
@@ -0,0 +1,77 @@
+#
+# Copyright (C) 2011, BMW AG
+#
+# GeniviAudioMananger DatbaseTest
+#
+# \file CMakeLists.txt
+#
+# \date 20-Oct-2011 3:42:04 PM
+# \author Christian Mueller (christian.ei.mueller@bmw.de)
+#
+# \section License
+# GNU Lesser General Public License, version 2.1, with special exception (GENIVI clause)
+# Copyright (C) 2011, BMW AG Christian Mueller  Christian.ei.mueller@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 AudioManager statically or dynamically with other modules is making a combined work based on AudioManager. 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 AudioManager give you permission to combine AudioManager 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 AudioManager and the licenses of the other code concerned.
+# Note that people who make modified versions of AudioManager 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.
+#
+
+cmake_minimum_required(VERSION 2.6)
+
+PROJECT(routingTest)
+
+set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -DUNIT_TEST=1 -DDLT_CONTEXT=AudioManager")
+
+FIND_PACKAGE(PkgConfig)
+pkg_check_modules(SQLITE REQUIRED sqlite3)
+pkg_check_modules(DLT REQUIRED automotive-dlt)
+
+INCLUDE_DIRECTORIES(   
+    ${CMAKE_CURRENT_BINARY_DIR}
+    ${AUDIO_INCLUDES_FOLDER}
+    ${DBUS_ARCH_INCLUDE_DIR}
+    ${DBUS_INCLUDES_FOLDER} 
+    ${CMAKE_SOURCE_DIR} 
+    ${STD_INCLUDE_DIRS}
+    ${DLT_INCLUDE_DIRS}
+    ${DBUS_INCLUDE_DIR}
+    ${INCLUDES_FOLDER}
+)
+
+file(GLOB ROUTING_SRCS_CXX 
+    "../../src/DatabaseHandler.cpp"
+    "../../src/DatabaseObserver.cpp"
+    "../../src/CommandSender.cpp"
+    "../../src/RoutingSender.cpp"
+    "../../src/ControlReceiver.cpp"
+    "../../src/ControlSender.cpp"
+    "../../src/Router.cpp"
+    "../CommonFunctions.cpp" 
+    "*.cpp"
+    )
+
+ADD_EXECUTABLE( routingtest ${ROUTING_SRCS_CXX})
+
+TARGET_LINK_LIBRARIES( routingtest 
+       ${SQLITE_LIBRARIES}
+       ${DLT_LIBRARIES}
+       ${DBUS_LIBRARY}
+       ${CMAKE_THREAD_LIBS_INIT}
+       ${GTEST_LIBRARIES}
+       gmock
+)
+
+INSTALL(TARGETS routingtest 
+        DESTINATION "~/AudioManagerTest/"
+        PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_EXECUTE WORLD_READ
+        COMPONENT tests
+)
+
+SET(ADD_DEPEND "audiomanager-bin" "sqlite3(>=3.6.22)" "dlt" "libdbus-1-3(>=1.2.16)" "libgtest-dev(>=1.6.0-1)" "google-mock" "libpthread-stubs0")
+set_property(GLOBAL APPEND PROPERTY tests_prop "${ADD_DEPEND}")
+
diff --git a/AudioManagerDaemon/test/routing/MockInterfaces.h b/AudioManagerDaemon/test/routing/MockInterfaces.h
new file mode 100644 (file)
index 0000000..9ece31c
--- /dev/null
@@ -0,0 +1,174 @@
+/**
+ * Copyright (C) 2011, BMW AG
+ *
+ * GeniviAudioMananger AudioManagerDaemon
+ *
+ * \file MockInterfaces.h
+ *
+ * \date 20-Oct-2011 3:42:04 PM
+ * \author Christian Mueller (christian.ei.mueller@bmw.de)
+ *
+ * \section License
+ * GNU Lesser General Public License, version 2.1, with special exception (GENIVI clause)
+ * Copyright (C) 2011, BMW AG Christian Mueller  Christian.ei.mueller@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 AudioManager statically or dynamically with other modules is making a combined work based on AudioManager. 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 AudioManager give you permission to combine AudioManager 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 AudioManager and the licenses of the other code concerned.
+ * Note that people who make modified versions of AudioManager 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.
+ *
+ * THIS CODE HAS BEEN GENERATED BY ENTERPRISE ARCHITECT GENIVI MODEL. PLEASE CHANGE ONLY IN ENTERPRISE ARCHITECT AND GENERATE AGAIN
+ */
+
+#ifndef MOCKROUTINGINTERFACE_H_
+#define MOCKROUTINGINTERFACE_H_
+
+#include <control/ControlSendInterface.h>
+#include <command/CommandSendInterface.h>
+#include <gtest/gtest.h>
+#include <gmock/gmock.h>
+
+namespace am
+{
+
+class MockCommandSendInterface : public CommandSendInterface {
+ public:
+  MOCK_METHOD1(startupInterface,
+      am_Error_e(CommandReceiveInterface* commandreceiveinterface));
+  MOCK_METHOD0(stopInterface,
+      am_Error_e());
+  MOCK_METHOD0(cbCommunicationReady,
+      am_Error_e());
+  MOCK_METHOD0(cbCommunicationRundown,
+      am_Error_e());
+  MOCK_METHOD0(cbNumberOfMainConnectionsChanged,
+      void());
+  MOCK_METHOD0(cbNumberOfSinksChanged,
+      void());
+  MOCK_METHOD0(cbNumberOfSourcesChanged,
+      void());
+  MOCK_METHOD0(cbNumberOfSinkClassesChanged,
+      void());
+  MOCK_METHOD0(cbNumberOfSourceClassesChanged,
+      void());
+  MOCK_METHOD2(cbMainConnectionStateChanged,
+      void(const am_mainConnectionID_t connectionID, const am_ConnectionState_e connectionState));
+  MOCK_METHOD2(cbMainSinkSoundPropertyChanged,
+      void(const am_sinkID_t sinkID, const am_MainSoundProperty_s soundProperty));
+  MOCK_METHOD2(cbMainSourceSoundPropertyChanged,
+      void(const am_sourceID_t sourceID, const am_MainSoundProperty_s& soundProperty));
+  MOCK_METHOD2(cbSinkAvailabilityChanged,
+      void(const am_sinkID_t sinkID, const am_Availability_s& availability));
+  MOCK_METHOD2(cbSourceAvailabilityChanged,
+      void(const am_sourceID_t sourceID, const am_Availability_s& availability));
+  MOCK_METHOD2(cbVolumeChanged,
+      void(const am_sinkID_t sinkID, const am_mainVolume_t volume));
+  MOCK_METHOD2(cbSinkMuteStateChanged,
+      void(const am_sinkID_t sinkID, const am_MuteState_e muteState));
+  MOCK_METHOD1(cbSystemPropertyChanged,
+      void(const am_SystemProperty_s& systemProperty));
+  MOCK_METHOD2(cbTimingInformationChanged,
+      void(const am_timeSync_t time, const am_mainConnectionID_t mainConnectionID));
+  MOCK_CONST_METHOD0(getInterfaceVersion,
+      uint16_t());
+};
+
+
+class MockControlSendInterface: public ControlSendInterface
+{
+public:
+    MOCK_METHOD1(startupController,
+        am_Error_e(ControlReceiveInterface* controlreceiveinterface));
+    MOCK_METHOD0(stopController,
+        am_Error_e());
+    MOCK_METHOD0(hookAllPluginsLoaded,
+        void());
+    MOCK_METHOD3(hookUserConnectionRequest,
+        am_Error_e(const am_sourceID_t sourceID, const am_sinkID_t sinkID, am_mainConnectionID_t& mainConnectionID));
+    MOCK_METHOD1(hookUserDisconnectionRequest,
+        am_Error_e(const am_mainConnectionID_t connectionID));
+    MOCK_METHOD2(hookUserSetMainSinkSoundProperty,
+        am_Error_e(const am_sinkID_t sinkID, const am_MainSoundProperty_s& soundProperty));
+    MOCK_METHOD2(hookUserSetMainSourceSoundProperty,
+        am_Error_e(const am_sourceID_t sourceID, const am_MainSoundProperty_s& soundProperty));
+    MOCK_METHOD1(hookUserSetSystemProperty,
+        am_Error_e(const am_SystemProperty_s& property));
+    MOCK_METHOD2(hookUserVolumeChange,
+        am_Error_e(const am_sinkID_t SinkID, const am_mainVolume_t newVolume));
+    MOCK_METHOD2(hookUserVolumeStep,
+        am_Error_e(const am_sinkID_t SinkID, const int16_t increment));
+    MOCK_METHOD2(hookUserSetSinkMuteState,
+        am_Error_e(const am_sinkID_t sinkID, const am_MuteState_e muteState));
+    MOCK_METHOD2(hookSystemRegisterDomain,
+        am_Error_e(const am_Domain_s& domainData, am_domainID_t& domainID));
+    MOCK_METHOD1(hookSystemDeregisterDomain,
+        am_Error_e(const am_domainID_t domainID));
+    MOCK_METHOD1(hookSystemDomainRegistrationComplete,
+        void(const am_domainID_t domainID));
+    MOCK_METHOD2(hookSystemRegisterSink,
+        am_Error_e(const am_Sink_s& sinkData, am_sinkID_t& sinkID));
+    MOCK_METHOD1(hookSystemDeregisterSink,
+        am_Error_e(const am_sinkID_t sinkID));
+    MOCK_METHOD2(hookSystemRegisterSource,
+        am_Error_e(const am_Source_s& sourceData, am_sourceID_t& sourceID));
+    MOCK_METHOD1(hookSystemDeregisterSource,
+        am_Error_e(const am_sourceID_t sourceID));
+    MOCK_METHOD2(hookSystemRegisterGateway,
+        am_Error_e(const am_Gateway_s& gatewayData, am_gatewayID_t& gatewayID));
+    MOCK_METHOD1(hookSystemDeregisterGateway,
+        am_Error_e(const am_gatewayID_t gatewayID));
+    MOCK_METHOD2(hookSystemRegisterCrossfader,
+        am_Error_e(const am_Crossfader_s& crossfaderData, am_crossfaderID_t& crossfaderID));
+    MOCK_METHOD1(hookSystemDeregisterCrossfader,
+        am_Error_e(const am_crossfaderID_t crossfaderID));
+    MOCK_METHOD3(hookSystemSinkVolumeTick,
+        void(const am_Handle_s handle, const am_sinkID_t sinkID, const am_volume_t volume));
+    MOCK_METHOD3(hookSystemSourceVolumeTick,
+        void(const am_Handle_s handle, const am_sourceID_t sourceID, const am_volume_t volume));
+    MOCK_METHOD2(hookSystemInterruptStateChange,
+        void(const am_sourceID_t sourceID, const am_InterruptState_e interruptState));
+    MOCK_METHOD2(hookSystemSinkAvailablityStateChange,
+        void(const am_sinkID_t sinkID, const am_Availability_s& availability));
+    MOCK_METHOD2(hookSystemSourceAvailablityStateChange,
+        void(const am_sourceID_t sourceID, const am_Availability_s& availability));
+    MOCK_METHOD2(hookSystemDomainStateChange,
+        void(const am_domainID_t domainID, const am_DomainState_e state));
+    MOCK_METHOD1(hookSystemReceiveEarlyData,
+        void(const std::vector<am_EarlyData_s>& data));
+    MOCK_METHOD1(hookSystemSpeedChange,
+        void(const am_speed_t speed));
+    MOCK_METHOD2(hookSystemTimingInformationChanged,
+        void(const am_mainConnectionID_t mainConnectionID, const am_timeSync_t time));
+    MOCK_METHOD2(cbAckConnect,
+        void(const am_Handle_s handle, const am_Error_e errorID));
+    MOCK_METHOD2(cbAckDisconnect,
+        void(const am_Handle_s handle, const am_Error_e errorID));
+    MOCK_METHOD3(cbAckCrossFade,
+        void(const am_Handle_s handle, const am_HotSink_e hostsink, const am_Error_e error));
+    MOCK_METHOD3(cbAckSetSinkVolumeChange,
+        void(const am_Handle_s handle, const am_volume_t volume, const am_Error_e error));
+    MOCK_METHOD3(cbAckSetSourceVolumeChange,
+        void(const am_Handle_s handle, const am_volume_t voulme, const am_Error_e error));
+    MOCK_METHOD2(cbAckSetSourceState,
+        void(const am_Handle_s handle, const am_Error_e error));
+    MOCK_METHOD2(cbAckSetSourceSoundProperties,
+        void(const am_Handle_s handle, const am_Error_e error));
+    MOCK_METHOD2(cbAckSetSourceSoundProperty,
+        void(const am_Handle_s handle, const am_Error_e error));
+    MOCK_METHOD2(cbAckSetSinkSoundProperties,
+        void(const am_Handle_s handle, const am_Error_e error));
+    MOCK_METHOD2(cbAckSetSinkSoundProperty,
+        void(const am_Handle_s handle, const am_Error_e error));
+    MOCK_METHOD4(getConnectionFormatChoice,
+        am_Error_e(const am_sourceID_t sourceID, const am_sinkID_t sinkID, const std::vector<am_ConnectionFormat_e> listPossibleConnectionFormats, std::vector<am_ConnectionFormat_e>& listPrioConnectionFormats));
+    MOCK_CONST_METHOD0(getInterfaceVersion,
+        uint16_t());
+
+};
+
+} // namespace am
+
+#endif /* MOCKROUTINGINTERFACE_H_ */
diff --git a/AudioManagerDaemon/test/routing/routingTest.cpp b/AudioManagerDaemon/test/routing/routingTest.cpp
new file mode 100644 (file)
index 0000000..2950255
--- /dev/null
@@ -0,0 +1,606 @@
+/**
+ * Copyright (C) 2011, BMW AG
+ *
+ * GeniviAudioMananger AudioManagerDaemon
+ *
+ * \file databasetest.cpp
+ *
+ * \date 20-Oct-2011 3:42:04 PM
+ * \author Christian Mueller (christian.ei.mueller@bmw.de)
+ *
+ * \section License
+ * GNU Lesser General Public License, version 2.1, with special exception (GENIVI clause)
+ * Copyright (C) 2011, BMW AG Christian Mueller  Christian.ei.mueller@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 AudioManager statically or dynamically with other modules is making a combined work based on AudioManager. 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 AudioManager give you permission to combine AudioManager 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 AudioManager and the licenses of the other code concerned.
+ * Note that people who make modified versions of AudioManager 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.
+ *
+ * THIS CODE HAS BEEN GENERATED BY ENTERPRISE ARCHITECT GENIVI MODEL. PLEASE CHANGE ONLY IN ENTERPRISE ARCHITECT AND GENERATE AGAIN
+ */
+
+#include "routingTest.h"
+#include "MockInterfaces.h"
+#include "DatabaseHandler.h"
+#include "ControlReceiver.h"
+#include "ControlSender.h"
+#include "DatabaseObserver.h"
+#include "../ControlInterfaceBackdoor.h"
+#include "../CommandInterfaceBackdoor.h"
+#include "../CommonFunctions.h"
+#include <string.h>
+
+using namespace am;
+using namespace testing;
+
+DLT_DECLARE_CONTEXT(DLT_CONTEXT)
+
+//extern int GetRandomNumber(int nLow, int nHigh);
+//extern bool equalSoundProperty (const am_SoundProperty_s a, const am_SoundProperty_s b);
+extern bool equalMainSoundProperty(const am_MainSoundProperty_s a, const am_MainSoundProperty_s b);
+extern bool equalRoutingElement(const am_RoutingElement_s a, const am_RoutingElement_s b);
+extern bool equalClassProperties(const am_ClassProperty_s a, const am_ClassProperty_s b);
+extern std::string int2string(int i);
+
+routingTest::routingTest() :
+        plistRoutingPluginDirs(), //
+        plistCommandPluginDirs(), //
+        pDatabaseHandler(std::string(":memory:")), //
+        pControlSender(std::string("")), //
+        pRouter(&pDatabaseHandler,&pControlSender), //
+        pRoutingSender(plistRoutingPluginDirs), //
+        pCommandSender(plistCommandPluginDirs), //
+        pMockInterface(), //
+        pMockControlInterface(), //
+        pRoutingInterfaceBackdoor(), //
+        pCommandInterfaceBackdoor(), //
+        pControlInterfaceBackdoor(), //
+        pControlReceiver(&pDatabaseHandler, &pRoutingSender, &pCommandSender), //
+        pObserver(&pCommandSender, &pRoutingSender)
+{
+    pDatabaseHandler.registerObserver(&pObserver);
+    pCommandInterfaceBackdoor.injectInterface(&pCommandSender, &pMockInterface);
+    pControlInterfaceBackdoor.replaceController(&pControlSender, &pMockControlInterface);
+}
+
+routingTest::~routingTest()
+{
+}
+
+void routingTest::SetUp()
+{
+    DLT_REGISTER_APP("Dtest", "AudioManagerDeamon");
+    DLT_REGISTER_CONTEXT(DLT_CONTEXT, "Main", "Main Context");
+    DLT_LOG(DLT_CONTEXT, DLT_LOG_INFO, DLT_STRING("Database Test started "));
+}
+
+void routingTest::TearDown()
+{
+    DLT_UNREGISTER_CONTEXT(DLT_CONTEXT);
+}
+
+ACTION(returnConnectionFormat)
+{
+    arg3=arg2;
+}
+
+
+
+//test that checks just 2 domains, one sink one source with only one connection format each
+TEST_F(routingTest,simpleRoute2Domains)
+{
+    EXPECT_CALL(pMockInterface,cbNumberOfSourcesChanged()).Times(2);
+    EXPECT_CALL(pMockInterface,cbNumberOfSinksChanged()).Times(2);
+    EXPECT_CALL(pMockControlInterface,getConnectionFormatChoice(_,_,_,_)).WillRepeatedly(DoAll(returnConnectionFormat(),Return(E_OK)));
+
+    //initialize 2 domains
+    am_Domain_s domain1, domain2;
+    am_domainID_t domainID1, domainID2;
+
+    domain1.domainID = 0;
+    domain1.name = "domain1";
+    domain1.busname = "domain1bus";
+    domain1.state = DS_CONTROLLED;
+    domain2.domainID = 0;
+    domain2.name = "domain2";
+    domain2.busname = "domain2bus";
+    domain2.state = DS_CONTROLLED;
+
+    ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain1,domainID1));
+    ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain2,domainID2));
+
+    am_Source_s source, gwSource;
+    am_sourceID_t sourceID, gwSourceID;
+
+    source.domainID = domainID1;
+    source.name = "source1";
+    source.sourceState = SS_ON;
+    source.sourceID = 0;
+    source.sourceClassID = 5;
+    source.listConnectionFormats.push_back(CF_ANALOG);
+
+    gwSource.domainID = domainID2;
+    gwSource.name = "gwsource1";
+    gwSource.sourceState = SS_ON;
+    gwSource.sourceID = 0;
+    gwSource.sourceClassID = 5;
+    gwSource.listConnectionFormats.push_back(CF_MONO);
+
+    ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+    ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(gwSource,gwSourceID));
+
+    am_Sink_s sink, gwSink;
+    am_sinkID_t sinkID, gwSinkID;
+
+    sink.domainID = domainID2;
+    sink.name = "sink1";
+    sink.sinkID = 0;
+    sink.sinkClassID = 5;
+    sink.muteState = MS_MUTED;
+    sink.listConnectionFormats.push_back(CF_MONO);
+
+    gwSink.domainID = domainID1;
+    gwSink.name = "gwSink";
+    gwSink.sinkID = 0;
+    gwSink.sinkClassID = 5;
+    gwSink.muteState = MS_MUTED;
+    gwSink.listConnectionFormats.push_back(CF_ANALOG);
+
+    ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+    ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(gwSink,gwSinkID));
+
+    am_Gateway_s gateway;
+    am_gatewayID_t gatewayID;
+
+    gateway.controlDomainID = domainID1;
+    gateway.gatewayID = 0;
+    gateway.sinkID = gwSinkID;
+    gateway.sourceID = gwSourceID;
+    gateway.domainSourceID = domainID2;
+    gateway.domainSinkID = domainID1;
+    gateway.listSinkFormats = gwSink.listConnectionFormats;
+    gateway.listSourceFormats = gwSource.listConnectionFormats;
+    gateway.convertionMatrix.push_back(true);
+    gateway.name = "gateway";
+
+    ASSERT_EQ(E_OK, pDatabaseHandler.enterGatewayDB(gateway,gatewayID));
+
+    std::vector<am_Route_s> listRoutes;
+    std::vector<am_RoutingElement_s> listRoutingElements;
+    am_RoutingElement_s hopp1;
+    am_RoutingElement_s hopp2;
+
+    hopp1.sinkID = gwSinkID;
+    hopp1.sourceID = sourceID;
+    hopp1.domainID = domainID1;
+    hopp1.connectionFormat = source.listConnectionFormats[0];
+
+    hopp2.sinkID = sinkID;
+    hopp2.sourceID = gwSourceID;
+    hopp2.domainID = domainID2;
+    hopp2.connectionFormat = sink.listConnectionFormats[0];
+
+    listRoutingElements.push_back(hopp1);
+    listRoutingElements.push_back(hopp2);
+
+    am_Route_s compareRoute;
+    compareRoute.route = listRoutingElements;
+    compareRoute.sinkID = sinkID;
+    compareRoute.sourceID = sourceID;
+
+    ASSERT_EQ(E_OK, pRouter.getRoute(false,sourceID,sinkID,listRoutes));
+    ASSERT_EQ(1, listRoutes.size());
+    ASSERT_TRUE(pCF.compareRoute(compareRoute,listRoutes[0]));
+
+}
+
+//test that checks just 2 domains, one sink one source but the connectionformat of source
+TEST_F(routingTest,simpleRoute2DomainsNoMatchConnectionFormats)
+{
+    EXPECT_CALL(pMockInterface,cbNumberOfSourcesChanged()).Times(2);
+    EXPECT_CALL(pMockInterface,cbNumberOfSinksChanged()).Times(2);
+    EXPECT_CALL(pMockControlInterface,getConnectionFormatChoice(_,_,_,_)).WillRepeatedly(DoAll(returnConnectionFormat(),Return(E_OK)));
+
+    //initialize 2 domains
+    am_Domain_s domain1, domain2;
+    am_domainID_t domainID1, domainID2;
+
+    domain1.domainID = 0;
+    domain1.name = "domain1";
+    domain1.busname = "domain1bus";
+    domain1.state = DS_CONTROLLED;
+    domain2.domainID = 0;
+    domain2.name = "domain2";
+    domain2.busname = "domain2bus";
+    domain2.state = DS_CONTROLLED;
+
+    ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain1,domainID1));
+    ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain2,domainID2));
+
+    am_Source_s source, gwSource;
+    am_sourceID_t sourceID, gwSourceID;
+
+    source.domainID = domainID1;
+    source.name = "source1";
+    source.sourceState = SS_ON;
+    source.sourceID = 0;
+    source.sourceClassID = 5;
+    source.listConnectionFormats.push_back(CF_STEREO);
+
+    gwSource.domainID = domainID2;
+    gwSource.name = "gwsource1";
+    gwSource.sourceState = SS_ON;
+    gwSource.sourceID = 0;
+    gwSource.sourceClassID = 5;
+    gwSource.listConnectionFormats.push_back(CF_MONO);
+
+    ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+    ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(gwSource,gwSourceID));
+
+    am_Sink_s sink, gwSink;
+    am_sinkID_t sinkID, gwSinkID;
+
+    sink.domainID = domainID2;
+    sink.name = "sink1";
+    sink.sinkID = 0;
+    sink.sinkClassID = 5;
+    sink.muteState = MS_MUTED;
+    sink.listConnectionFormats.push_back(CF_MONO);
+
+    gwSink.domainID = domainID1;
+    gwSink.name = "gwSink";
+    gwSink.sinkID = 0;
+    gwSink.sinkClassID = 5;
+    gwSink.muteState = MS_MUTED;
+    gwSink.listConnectionFormats.push_back(CF_ANALOG);
+
+    ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+    ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(gwSink,gwSinkID));
+
+    am_Gateway_s gateway;
+    am_gatewayID_t gatewayID;
+
+    gateway.controlDomainID = domainID1;
+    gateway.gatewayID = 0;
+    gateway.sinkID = gwSinkID;
+    gateway.sourceID = gwSourceID;
+    gateway.domainSourceID = domainID2;
+    gateway.domainSinkID = domainID1;
+    gateway.listSinkFormats = gwSink.listConnectionFormats;
+    gateway.listSourceFormats = gwSource.listConnectionFormats;
+    gateway.convertionMatrix.push_back(true);
+    gateway.name = "gateway";
+
+    ASSERT_EQ(E_OK, pDatabaseHandler.enterGatewayDB(gateway,gatewayID));
+
+    std::vector<am_Route_s> listRoutes;
+    std::vector<am_RoutingElement_s> listRoutingElements;
+    am_RoutingElement_s hopp1;
+    am_RoutingElement_s hopp2;
+
+    hopp1.sinkID = gwSinkID;
+    hopp1.sourceID = sourceID;
+    hopp1.domainID = domainID1;
+    hopp1.connectionFormat = source.listConnectionFormats[0];
+
+    hopp2.sinkID = sinkID;
+    hopp2.sourceID = gwSourceID;
+    hopp2.domainID = domainID2;
+    hopp2.connectionFormat = sink.listConnectionFormats[0];
+
+    listRoutingElements.push_back(hopp1);
+    listRoutingElements.push_back(hopp2);
+
+    am_Route_s compareRoute;
+    compareRoute.route = listRoutingElements;
+    compareRoute.sinkID = sinkID;
+    compareRoute.sourceID = sourceID;
+
+    ASSERT_EQ(E_OK, pRouter.getRoute(false,sourceID,sinkID,listRoutes));
+    ASSERT_EQ(0, listRoutes.size());
+}
+
+//test that checks 3 domains, one sink one source.
+TEST_F(routingTest,simpleRoute3Domains)
+{
+    EXPECT_CALL(pMockInterface,cbNumberOfSourcesChanged()).Times(3);
+    EXPECT_CALL(pMockInterface,cbNumberOfSinksChanged()).Times(3);
+    EXPECT_CALL(pMockControlInterface,getConnectionFormatChoice(_,_,_,_)).WillRepeatedly(DoAll(returnConnectionFormat(),Return(E_OK)));
+
+    //initialize 2 domains
+    am_Domain_s domain1, domain2, domain3;
+    am_domainID_t domainID1, domainID2, domainID3;
+
+    domain1.domainID = 0;
+    domain1.name = "domain1";
+    domain1.busname = "domain1bus";
+    domain1.state = DS_CONTROLLED;
+    domain2.domainID = 0;
+    domain2.name = "domain2";
+    domain2.busname = "domain2bus";
+    domain2.state = DS_CONTROLLED;
+    domain3.domainID = 0;
+    domain3.name = "domain3";
+    domain3.busname = "domain3bus";
+    domain3.state = DS_CONTROLLED;
+
+    ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain1,domainID1));
+    ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain2,domainID2));
+    ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain3,domainID3));
+
+    am_Source_s source, gwSource, gwSource1;
+    am_sourceID_t sourceID, gwSourceID, gwSourceID1;
+
+    source.domainID = domainID1;
+    source.name = "source1";
+    source.sourceState = SS_ON;
+    source.sourceID = 0;
+    source.sourceClassID = 5;
+    source.listConnectionFormats.push_back(CF_MONO);
+
+    gwSource.domainID = domainID2;
+    gwSource.name = "gwsource1";
+    gwSource.sourceState = SS_ON;
+    gwSource.sourceID = 0;
+    gwSource.sourceClassID = 5;
+    gwSource.listConnectionFormats.push_back(CF_ANALOG);
+
+    gwSource1.domainID = domainID3;
+    gwSource1.name = "gwsource2";
+    gwSource1.sourceState = SS_ON;
+    gwSource1.sourceID = 0;
+    gwSource1.sourceClassID = 5;
+    gwSource1.listConnectionFormats.push_back(CF_MONO);
+
+    ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+    ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(gwSource,gwSourceID));
+    ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(gwSource1,gwSourceID1));
+
+    am_Sink_s sink, gwSink, gwSink1;
+    am_sinkID_t sinkID, gwSinkID, gwSinkID1;
+
+    sink.domainID = domainID3;
+    sink.name = "sink1";
+    sink.sinkID = 0;
+    sink.sinkClassID = 5;
+    sink.muteState = MS_MUTED;
+    sink.listConnectionFormats.push_back(CF_MONO);
+
+    gwSink.domainID = domainID1;
+    gwSink.name = "gwSink";
+    gwSink.sinkID = 0;
+    gwSink.sinkClassID = 5;
+    gwSink.muteState = MS_MUTED;
+    gwSink.listConnectionFormats.push_back(CF_MONO);
+
+    gwSink1.domainID = domainID2;
+    gwSink1.name = "gwSink1";
+    gwSink1.sinkID = 0;
+    gwSink1.sinkClassID = 5;
+    gwSink1.muteState = MS_MUTED;
+    gwSink1.listConnectionFormats.push_back(CF_ANALOG);
+
+    ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+    ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(gwSink,gwSinkID));
+    ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(gwSink1,gwSinkID1));
+
+    am_Gateway_s gateway, gateway1;
+    am_gatewayID_t gatewayID, gatewayID1;
+
+    gateway.controlDomainID = domainID1;
+    gateway.gatewayID = 0;
+    gateway.sinkID = gwSinkID;
+    gateway.sourceID = gwSourceID;
+    gateway.domainSourceID = domainID2;
+    gateway.domainSinkID = domainID1;
+    gateway.listSinkFormats = gwSink.listConnectionFormats;
+    gateway.listSourceFormats = gwSource.listConnectionFormats;
+    gateway.convertionMatrix.push_back(true);
+    gateway.name = "gateway";
+
+    gateway1.controlDomainID = domainID2;
+    gateway1.gatewayID = 0;
+    gateway1.sinkID = gwSinkID1;
+    gateway1.sourceID = gwSourceID1;
+    gateway1.domainSourceID = domainID3;
+    gateway1.domainSinkID = domainID2;
+    gateway1.listSinkFormats = gwSink1.listConnectionFormats;
+    gateway1.listSourceFormats = gwSource1.listConnectionFormats;
+    gateway1.convertionMatrix.push_back(true);
+    gateway1.name = "gateway";
+
+    ASSERT_EQ(E_OK, pDatabaseHandler.enterGatewayDB(gateway,gatewayID));
+    ASSERT_EQ(E_OK, pDatabaseHandler.enterGatewayDB(gateway1,gatewayID1));
+
+    std::vector<am_Route_s> listRoutes;
+    std::vector<am_RoutingElement_s> listRoutingElements;
+    am_RoutingElement_s hopp1;
+    am_RoutingElement_s hopp2;
+    am_RoutingElement_s hopp3;
+
+    hopp1.sourceID = sourceID;
+    hopp1.sinkID = gwSinkID;
+    hopp1.domainID = domainID1;
+    hopp1.connectionFormat = source.listConnectionFormats[0];
+
+    hopp2.sourceID = gwSourceID;
+    hopp2.sinkID = gwSinkID1;
+    hopp2.domainID = domainID2;
+    hopp2.connectionFormat = gwSink1.listConnectionFormats[0];
+
+    hopp3.sourceID = gwSourceID1;
+    hopp3.sinkID = sinkID;
+    hopp3.domainID = domainID3;
+    hopp3.connectionFormat = sink.listConnectionFormats[0];
+
+    listRoutingElements.push_back(hopp1);
+    listRoutingElements.push_back(hopp2);
+    listRoutingElements.push_back(hopp3);
+
+    am_Route_s compareRoute;
+    compareRoute.route = listRoutingElements;
+    compareRoute.sinkID = sinkID;
+    compareRoute.sourceID = sourceID;
+
+    ASSERT_EQ(E_OK, pRouter.getRoute(false,sourceID,sinkID,listRoutes));
+    ASSERT_EQ(1, listRoutes.size());
+    ASSERT_TRUE(pCF.compareRoute(compareRoute,listRoutes[0]));
+}
+
+//test that checks 3 domains, one sink one source but the connectionformat of third domains do not fit.
+TEST_F(routingTest,simpleRoute3DomainsNoConnection)
+{
+    EXPECT_CALL(pMockInterface,cbNumberOfSourcesChanged()).Times(3);
+    EXPECT_CALL(pMockInterface,cbNumberOfSinksChanged()).Times(3);
+    EXPECT_CALL(pMockControlInterface,getConnectionFormatChoice(_,_,_,_)).WillRepeatedly(DoAll(returnConnectionFormat(),Return(E_OK)));
+
+    //initialize 2 domains
+    am_Domain_s domain1, domain2, domain3;
+    am_domainID_t domainID1, domainID2, domainID3;
+
+    domain1.domainID = 0;
+    domain1.name = "domain1";
+    domain1.busname = "domain1bus";
+    domain1.state = DS_CONTROLLED;
+    domain2.domainID = 0;
+    domain2.name = "domain2";
+    domain2.busname = "domain2bus";
+    domain2.state = DS_CONTROLLED;
+    domain3.domainID = 0;
+    domain3.name = "domain3";
+    domain3.busname = "domain3bus";
+    domain3.state = DS_CONTROLLED;
+
+    ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain1,domainID1));
+    ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain2,domainID2));
+    ASSERT_EQ(E_OK, pDatabaseHandler.enterDomainDB(domain3,domainID3));
+
+    am_Source_s source, gwSource, gwSource1;
+    am_sourceID_t sourceID, gwSourceID, gwSourceID1;
+
+    source.domainID = domainID1;
+    source.name = "source1";
+    source.sourceState = SS_ON;
+    source.sourceID = 0;
+    source.sourceClassID = 5;
+    source.listConnectionFormats.push_back(CF_MONO);
+
+    gwSource.domainID = domainID2;
+    gwSource.name = "gwsource1";
+    gwSource.sourceState = SS_ON;
+    gwSource.sourceID = 0;
+    gwSource.sourceClassID = 5;
+    gwSource.listConnectionFormats.push_back(CF_ANALOG);
+
+    gwSource1.domainID = domainID3;
+    gwSource1.name = "gwsource2";
+    gwSource1.sourceState = SS_ON;
+    gwSource1.sourceID = 0;
+    gwSource1.sourceClassID = 5;
+    gwSource1.listConnectionFormats.push_back(CF_MONO);
+
+    ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(source,sourceID));
+    ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(gwSource,gwSourceID));
+    ASSERT_EQ(E_OK, pDatabaseHandler.enterSourceDB(gwSource1,gwSourceID1));
+
+    am_Sink_s sink, gwSink, gwSink1;
+    am_sinkID_t sinkID, gwSinkID, gwSinkID1;
+
+    sink.domainID = domainID3;
+    sink.name = "sink1";
+    sink.sinkID = 0;
+    sink.sinkClassID = 5;
+    sink.muteState = MS_MUTED;
+    sink.listConnectionFormats.push_back(CF_STEREO);
+
+    gwSink.domainID = domainID1;
+    gwSink.name = "gwSink";
+    gwSink.sinkID = 0;
+    gwSink.sinkClassID = 5;
+    gwSink.muteState = MS_MUTED;
+    gwSink.listConnectionFormats.push_back(CF_MONO);
+
+    gwSink1.domainID = domainID2;
+    gwSink1.name = "gwSink1";
+    gwSink1.sinkID = 0;
+    gwSink1.sinkClassID = 5;
+    gwSink1.muteState = MS_MUTED;
+    gwSink1.listConnectionFormats.push_back(CF_ANALOG);
+
+    ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(sink,sinkID));
+    ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(gwSink,gwSinkID));
+    ASSERT_EQ(E_OK, pDatabaseHandler.enterSinkDB(gwSink1,gwSinkID1));
+
+    am_Gateway_s gateway, gateway1;
+    am_gatewayID_t gatewayID, gatewayID1;
+
+    gateway.controlDomainID = domainID1;
+    gateway.gatewayID = 0;
+    gateway.sinkID = gwSinkID;
+    gateway.sourceID = gwSourceID;
+    gateway.domainSourceID = domainID2;
+    gateway.domainSinkID = domainID1;
+    gateway.listSinkFormats = gwSink.listConnectionFormats;
+    gateway.listSourceFormats = gwSource.listConnectionFormats;
+    gateway.convertionMatrix.push_back(true);
+    gateway.name = "gateway";
+
+    gateway1.controlDomainID = domainID2;
+    gateway1.gatewayID = 0;
+    gateway1.sinkID = gwSinkID1;
+    gateway1.sourceID = gwSourceID1;
+    gateway1.domainSourceID = domainID3;
+    gateway1.domainSinkID = domainID2;
+    gateway1.listSinkFormats = gwSink1.listConnectionFormats;
+    gateway1.listSourceFormats = gwSource1.listConnectionFormats;
+    gateway1.convertionMatrix.push_back(true);
+    gateway1.name = "gateway";
+
+    ASSERT_EQ(E_OK, pDatabaseHandler.enterGatewayDB(gateway,gatewayID));
+    ASSERT_EQ(E_OK, pDatabaseHandler.enterGatewayDB(gateway1,gatewayID1));
+
+    std::vector<am_Route_s> listRoutes;
+    std::vector<am_RoutingElement_s> listRoutingElements;
+    am_RoutingElement_s hopp1;
+    am_RoutingElement_s hopp2;
+    am_RoutingElement_s hopp3;
+
+    hopp1.sourceID = sourceID;
+    hopp1.sinkID = gwSinkID;
+    hopp1.domainID = domainID1;
+    hopp1.connectionFormat = source.listConnectionFormats[0];
+
+    hopp2.sourceID = gwSourceID;
+    hopp2.sinkID = gwSinkID1;
+    hopp2.domainID = domainID2;
+    hopp2.connectionFormat = gwSink1.listConnectionFormats[0];
+
+    hopp3.sourceID = gwSourceID1;
+    hopp3.sinkID = sinkID;
+    hopp3.domainID = domainID3;
+    hopp3.connectionFormat = sink.listConnectionFormats[0];
+
+    listRoutingElements.push_back(hopp1);
+    listRoutingElements.push_back(hopp2);
+    listRoutingElements.push_back(hopp3);
+
+    am_Route_s compareRoute;
+    compareRoute.route = listRoutingElements;
+    compareRoute.sinkID = sinkID;
+    compareRoute.sourceID = sourceID;
+
+    ASSERT_EQ(E_OK, pRouter.getRoute(false,sourceID,sinkID,listRoutes));
+    ASSERT_EQ(0, listRoutes.size());
+    ASSERT_TRUE(pCF.compareRoute(compareRoute,listRoutes[0]));
+}
+
+int main(int argc, char **argv)
+{
+    ::testing::InitGoogleTest(&argc, argv);
+    return RUN_ALL_TESTS();
+}
+
diff --git a/AudioManagerDaemon/test/routing/routingTest.h b/AudioManagerDaemon/test/routing/routingTest.h
new file mode 100644 (file)
index 0000000..4b6b16b
--- /dev/null
@@ -0,0 +1,80 @@
+/**
+ * Copyright (C) 2011, BMW AG
+ *
+ * GeniviAudioMananger AudioManagerDaemon
+ *
+ * \file databasetest.h
+ *
+ * \date 20-Oct-2011 3:42:04 PM
+ * \author Christian Mueller (christian.ei.mueller@bmw.de)
+ *
+ * \section License
+ * GNU Lesser General Public License, version 2.1, with special exception (GENIVI clause)
+ * Copyright (C) 2011, BMW AG Christian Mueller  Christian.ei.mueller@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 AudioManager statically or dynamically with other modules is making a combined work based on AudioManager. 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 AudioManager give you permission to combine AudioManager 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 AudioManager and the licenses of the other code concerned.
+ * Note that people who make modified versions of AudioManager 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.
+ *
+ * THIS CODE HAS BEEN GENERATED BY ENTERPRISE ARCHITECT GENIVI MODEL. PLEASE CHANGE ONLY IN ENTERPRISE ARCHITECT AND GENERATE AGAIN
+ */
+
+#ifndef DATABASETEST_H_
+#define DATABASETEST_H_
+
+#define UNIT_TEST 1
+
+#include <gtest/gtest.h>
+#include <gmock/gmock.h>
+#include <dlt/dlt.h>
+#include <algorithm>
+#include <string>
+#include <vector>
+#include <set>
+#include "MockInterfaces.h"
+#include "DatabaseHandler.h"
+#include "ControlReceiver.h"
+#include "ControlSender.h"
+#include "DatabaseObserver.h"
+#include "RoutingSender.h"
+#include "Router.h"
+#include "../ControlInterfaceBackdoor.h"
+#include "../CommandInterfaceBackdoor.h"
+#include "../CommonFunctions.h"
+
+namespace am
+{
+
+class routingTest: public ::testing::Test
+{
+public:
+    routingTest();
+    ~routingTest();
+    std::vector<std::string> plistRoutingPluginDirs;
+    std::vector<std::string> plistCommandPluginDirs;
+    DatabaseHandler pDatabaseHandler;
+    ControlSender pControlSender;
+    Router pRouter;
+    RoutingSender pRoutingSender;
+    CommandSender pCommandSender;
+    MockCommandSendInterface pMockInterface;
+    MockControlSendInterface pMockControlInterface;
+    RoutingInterfaceBackdoor pRoutingInterfaceBackdoor;
+    CommandInterfaceBackdoor pCommandInterfaceBackdoor;
+    ControlInterfaceBackdoor pControlInterfaceBackdoor;
+    ControlReceiver pControlReceiver;
+    DatabaseObserver pObserver;
+    CommonFunctions pCF;
+    void SetUp();
+    void TearDown();
+
+    void createMainConnectionSetup();
+};
+
+}
+
+#endif /* DATABASETEST_H_ */
index c29084e..8d232f6 100644 (file)
@@ -51,6 +51,7 @@ file(GLOB ROUTING_INTERFACE_SRCS_CXX
     "../../src/CommandSender.cpp"
     "../../src/RoutingSender.cpp"
     "../../src/Router.cpp"
+    "../../src/ControlSender.cpp"
     "../CommonFunctions.cpp" 
     "*.cpp"
 )
index f741d75..754b1e9 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef _CONFIG_H
 #define _CONFIG_H
 
-#define DAEMONVERSION "ver-0.0.1-12-g80213f1"
+#define DAEMONVERSION "ver-0.0.1-14-gaf0ba5b"
 
 #define WITH_DBUS_WRAPPER
 #define WITH_SOCKETHANDLER_LOOP