summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AudioManagerDaemon/CMakeLists.txt1
-rw-r--r--AudioManagerDaemon/include/DatabaseHandler.h8
-rw-r--r--AudioManagerDaemon/include/Router.h79
-rw-r--r--AudioManagerDaemon/src/DatabaseHandler.cpp130
-rw-r--r--AudioManagerDaemon/src/Router.cpp290
-rw-r--r--AudioManagerDaemon/src/main.cpp7
-rw-r--r--AudioManagerDaemon/test/controlInterface/CMakeLists.txt1
-rw-r--r--AudioManagerDaemon/test/database/CMakeLists.txt1
-rw-r--r--AudioManagerDaemon/test/routingInterface/CMakeLists.txt1
9 files changed, 515 insertions, 3 deletions
diff --git a/AudioManagerDaemon/CMakeLists.txt b/AudioManagerDaemon/CMakeLists.txt
index 7e8946d..c6cbb62 100644
--- a/AudioManagerDaemon/CMakeLists.txt
+++ b/AudioManagerDaemon/CMakeLists.txt
@@ -37,6 +37,7 @@ SET(AUDIOMAN_SRCS_CXX
src/RoutingSender.cpp
src/SocketHandler.cpp
src/TelnetServer.cpp
+ src/Router.cpp
)
IF(WITH_DBUS_WRAPPER)
diff --git a/AudioManagerDaemon/include/DatabaseHandler.h b/AudioManagerDaemon/include/DatabaseHandler.h
index 05fd237..65f4a64 100644
--- a/AudioManagerDaemon/include/DatabaseHandler.h
+++ b/AudioManagerDaemon/include/DatabaseHandler.h
@@ -32,6 +32,8 @@
namespace am {
class DatabaseObserver;
+class RoutingTree;
+class RoutingTreeItem;
#define DYNAMIC_ID_BOUNDARY 100 //!< the value below is reserved for staticIDs, the value above will be assigned to dynamically registered items
@@ -43,6 +45,7 @@ class DatabaseObserver;
//todo: exchange last_insert_row id to be more safe
//todo: create test to ensure uniqueness of names throughout the database
//todo: enforce the uniqueness of names
+//todo: set isUsed flag for gateways!
/**
* This class handles and abstracts the database
@@ -118,10 +121,15 @@ public:
am_Error_e getListMainSinkSoundProperties(const am_sinkID_t sinkID, std::vector<am_MainSoundProperty_s>& listSoundProperties) const ;
am_Error_e getListMainSourceSoundProperties(const am_sourceID_t sourceID, std::vector<am_MainSoundProperty_s>& listSourceProperties) const ;
am_Error_e getListSystemProperties(std::vector<am_SystemProperty_s>& listSystemProperties) const ;
+ am_Error_e getListSinkConnectionFormats(const am_sinkID_t sinkID, std::vector<am_ConnectionFormat_e> & listConnectionFormats) const ;
+ am_Error_e getListSourceConnectionFormats(const am_sourceID_t sourceID, std::vector<am_ConnectionFormat_e> & listConnectionFormats) const ;
+ am_Error_e getListGatewayConnectionFormats(const am_gatewayID_t gatewayID, std::vector<bool> & listConnectionFormat) const;
am_Error_e getTimingInformation(const am_mainConnectionID_t mainConnectionID, am_timeSync_t& delay) const ;
am_Error_e getDomainOfSource(const am_sourceID_t sourceID, am_domainID_t& domainID) const;
+ 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 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);
diff --git a/AudioManagerDaemon/include/Router.h b/AudioManagerDaemon/include/Router.h
new file mode 100644
index 0000000..7635522
--- /dev/null
+++ b/AudioManagerDaemon/include/Router.h
@@ -0,0 +1,79 @@
+/**
+ * Copyright (C) 2011, BMW AG
+ *
+ * GeniviAudioMananger AudioManagerDaemon
+ *
+ * \file Router.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.
+ *
+ */
+
+#ifndef ROUTER_H_
+#define ROUTER_H_
+
+#include <audiomanagertypes.h>
+
+namespace am {
+
+class DatabaseHandler;
+
+class Router {
+public:
+ Router(DatabaseHandler* iDatabaseHandler);
+ 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();
+
+private:
+ am_Error_e findBestWay(std::vector<am_RoutingElement_s>& listRoute,std::vector<am_RoutingElement_s>::iterator routeIterator,std::vector<am_gatewayID_t>::iterator gatewayIterator,int choiceNumber);
+ 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;
+};
+
+class RoutingTreeItem {
+public:
+ RoutingTreeItem(const am_domainID_t domainID, const am_gatewayID_t gatewayID = 0, RoutingTreeItem *parent = 0);
+ void appendChild(RoutingTreeItem *newChild);
+ void returnChildItems(std::vector<RoutingTreeItem*> listChildItems);
+ am_domainID_t returnDomainID() const;
+ am_gatewayID_t returnGatewayID() const;
+ virtual ~RoutingTreeItem();
+ RoutingTreeItem* returnParent() const;
+private:
+ std::vector<RoutingTreeItem*> mListChildItems; //!< List of all child items
+ am_domainID_t mDomainID; //!< the domain ID of the item
+ am_gatewayID_t mGatewayID; //!< the gateway Id
+ RoutingTreeItem *mParentItem; //!< pointer to the parent item
+};
+
+
+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);
+ am_domainID_t returnRootDomainID() const;
+ RoutingTreeItem* returnRootItem();
+ virtual ~RoutingTree();
+private:
+ RoutingTreeItem mRootItem; //!< pointer to root item
+ std::vector<RoutingTreeItem*> mListChild; //!< list of all childs
+};
+
+} /* namespace am */
+#endif /* ROUTER_H_ */
+
diff --git a/AudioManagerDaemon/src/DatabaseHandler.cpp b/AudioManagerDaemon/src/DatabaseHandler.cpp
index 76aadf8..c712fbd 100644
--- a/AudioManagerDaemon/src/DatabaseHandler.cpp
+++ b/AudioManagerDaemon/src/DatabaseHandler.cpp
@@ -30,6 +30,7 @@
#include <sstream>
#include <string>
#include <dlt/dlt.h>
+#include "Router.h"
#define DOMAIN_TABLE "Domains"
#define SOURCE_CLASS_TABLE "SourceClasses"
@@ -54,7 +55,7 @@ const std::string databaseTables[]={
" SinkClasses (sinkClassID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, name VARCHAR(50));",
" Sources (sourceID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, domainID INTEGER, name VARCHAR(50), sourceClassID INTEGER, sourceState INTEGER, volume INTEGER, visible BOOL, availability INTEGER, availabilityReason INTEGER, interruptState INTEGER, reserved BOOL);",
" Sinks (sinkID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, name VARCHAR(50), domainID INTEGER, sinkClassID INTEGER, volume INTEGER, visible BOOL, availability INTEGER, availabilityReason INTEGER, muteState INTEGER, mainVolume INTEGER, reserved BOOL);",
- " Gateways (gatewayID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, name VARCHAR(50), sinkID INTEGER, sourceID INTEGER, domainSinkID INTEGER, domainSourceID INTEGER, controlDomainID INTEGER);",
+ " Gateways (gatewayID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, name VARCHAR(50), sinkID INTEGER, sourceID INTEGER, domainSinkID INTEGER, domainSourceID INTEGER, controlDomainID INTEGER, inUse BOOL);",
" Crossfaders (crossfaderID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, name VARCHAR(50), sinkID_A INTEGER, sinkID_B INTEGER, sourceID INTEGER, hotSink INTEGER);",
" Connections (connectionID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, sourceID INTEGER, sinkID INTEGER, delay INTEGER, connectionFormat INTEGER, reserved BOOL);",
" MainConnections (mainConnectionID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, sourceID INTEGER, sinkID INTEGER, connectionState INTEGER, delay INTEGER);",
@@ -2531,6 +2532,70 @@ am_Error_e DatabaseHandler::getListSystemProperties(std::vector<am_SystemPropert
return E_OK;
}
+am_Error_e am::DatabaseHandler::getListSinkConnectionFormats(const am_sinkID_t sinkID, std::vector<am_ConnectionFormat_e> & listConnectionFormats) const
+{
+ listConnectionFormats.clear();
+ sqlite3_stmt *qConnectionFormat=NULL;
+ int eCode=0;
+ am_ConnectionFormat_e tempConnectionFormat;
+ std::string commandConnectionFormat= "SELECT soundFormat FROM SinkConnectionFormat"+ i2s(sinkID);
+ sqlite3_prepare_v2(mDatabase,commandConnectionFormat.c_str(),-1,&qConnectionFormat,NULL);
+ while((eCode=sqlite3_step(qConnectionFormat))==SQLITE_ROW)
+ {
+ tempConnectionFormat=(am_ConnectionFormat_e)sqlite3_column_int(qConnectionFormat,0);
+ listConnectionFormats.push_back(tempConnectionFormat);
+ }
+
+ if((eCode=sqlite3_finalize(qConnectionFormat))!=SQLITE_OK)
+ {
+ DLT_LOG(AudioManager, DLT_LOG_ERROR, DLT_STRING("DatabaseHandler::getListSinkConnectionFormats SQLITE Finalize error code:"),DLT_INT(eCode));
+ return E_DATABASE_ERROR;
+ }
+
+ return E_OK;
+}
+
+
+
+am_Error_e am::DatabaseHandler::getListSourceConnectionFormats(const am_sourceID_t sourceID, std::vector<am_ConnectionFormat_e> & listConnectionFormats) const
+{
+ listConnectionFormats.clear();
+ sqlite3_stmt* query=NULL, *qConnectionFormat=NULL, *qSoundProperty=NULL, *qMAinSoundProperty=NULL;
+ int eCode=0;
+ am_ConnectionFormat_e tempConnectionFormat;
+
+ //read out the connectionFormats
+ std::string commandConnectionFormat= "SELECT soundFormat FROM SourceConnectionFormat"+ i2s(sourceID);
+ sqlite3_prepare_v2(mDatabase,commandConnectionFormat.c_str(),-1,&qConnectionFormat,NULL);
+ while((eCode=sqlite3_step(qConnectionFormat))==SQLITE_ROW)
+ {
+ tempConnectionFormat=(am_ConnectionFormat_e)sqlite3_column_int(qConnectionFormat,0);
+ listConnectionFormats.push_back(tempConnectionFormat);
+ }
+
+ if((eCode=sqlite3_finalize(qConnectionFormat))!=SQLITE_OK)
+ {
+ DLT_LOG(AudioManager, DLT_LOG_ERROR, DLT_STRING("DatabaseHandler::getListSources SQLITE Finalize error code:"),DLT_INT(eCode));
+ return E_DATABASE_ERROR;
+ }
+
+ return E_OK;
+}
+
+am_Error_e am::DatabaseHandler::getListGatewayConnectionFormats(const am_gatewayID_t gatewayID, std::vector<bool> & listConnectionFormat) const
+{
+ ListConnectionFormat::const_iterator iter=mListConnectionFormat.begin();
+ iter=mListConnectionFormat.find(gatewayID);
+ if (iter == mListConnectionFormat.end())
+ {
+ DLT_LOG(AudioManager, DLT_LOG_ERROR, DLT_STRING("DatabaseHandler::getListGatewayConnectionFormats database error with convertionFormat"));
+ return (E_DATABASE_ERROR);
+ }
+ listConnectionFormat=iter->second;
+
+ return (E_OK);
+}
+
am_Error_e DatabaseHandler::getTimingInformation(const am_mainConnectionID_t mainConnectionID, am_timeSync_t & delay) const
@@ -3046,7 +3111,29 @@ am_Error_e DatabaseHandler::getDomainOfSource(const am_sourceID_t sourceID, am_d
DLT_LOG(AudioManager, DLT_LOG_ERROR, DLT_STRING("DatabaseHandler::getDomainOfSource database error!:"), DLT_INT(eCode))
}
sqlite3_finalize(query);
- return returnVal;
+ return (returnVal);
+}
+
+am_Error_e am::DatabaseHandler::getDomainOfSink(const am_sinkID_t sinkID, am_domainID_t & domainID) const
+{
+ assert(sinkID!=0);
+
+ sqlite3_stmt* query=NULL;
+ std::string command = "SELECT domainID FROM " + std::string(SINK_TABLE) + " WHERE sinkID=" + i2s(sinkID);
+ int eCode=0;
+ am_Error_e returnVal=E_DATABASE_ERROR;
+ sqlite3_prepare_v2(mDatabase,command.c_str(),-1,&query,NULL);
+ if ((eCode=sqlite3_step(query))==SQLITE_ROW)
+ {
+ domainID=sqlite3_column_int(query,0);
+ returnVal=E_OK;
+ }
+ else
+ {
+ DLT_LOG(AudioManager, DLT_LOG_ERROR, DLT_STRING("DatabaseHandler::getDomainOfSink database error!:"), DLT_INT(eCode))
+ }
+ sqlite3_finalize(query);
+ return (returnVal);
}
@@ -3771,6 +3858,45 @@ 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)
+{
+ sqlite3_stmt* query=NULL;
+ int eCode=0;
+ size_t i=0;
+ std::string command;
+ am_domainID_t rootID = tree->returnRootDomainID();
+ RoutingTreeItem *parent = tree->returnRootItem();
+
+ command="SELECT domainSourceID,gatewayID FROM " + std::string(GATEWAY_TABLE)+ " WHERE domainSinkID=? AND IsBlocked=?";
+
+ sqlite3_prepare_v2(mDatabase,command.c_str(),-1,&query,NULL);
+ do {
+ 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));
+ }
+
+ if(eCode!=SQLITE_DONE)
+ {
+ 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);
+ }
+
+ return (E_OK);
+}
+
void DatabaseHandler::createTables()
{
for(uint16_t i=0;i<sizeof(databaseTables)/sizeof(databaseTables[0]);i++)
diff --git a/AudioManagerDaemon/src/Router.cpp b/AudioManagerDaemon/src/Router.cpp
new file mode 100644
index 0000000..9e1b5f6
--- /dev/null
+++ b/AudioManagerDaemon/src/Router.cpp
@@ -0,0 +1,290 @@
+/**
+ * Copyright (C) 2011, BMW AG
+ *
+ * GeniviAudioMananger AudioManagerDaemon
+ *
+ * \file Router.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.
+ *
+ */
+
+#include "Router.h"
+#include "DatabaseHandler.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)
+{
+ assert(mDatabaseHandler);
+}
+
+am_Error_e am::Router::getRoute(const bool onlyfree, const am_sourceID_t sourceID, const am_sinkID_t sinkID, std::vector<am_Route_s> & returnList)
+{
+ //first find out in which domains the source and sink are
+ am_domainID_t sourceDomainID;
+ am_domainID_t sinkDomainID;
+ if (mDatabaseHandler->getDomainOfSource(sourceID,sourceDomainID) != E_OK) return (E_NON_EXISTENT);
+ if (mDatabaseHandler->getDomainOfSink(sinkID,sinkDomainID) != E_OK) return (E_NON_EXISTENT);
+
+ 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<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
+ am_Route_s actualRoute; //holds the actual Route
+ 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
+
+ //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)
+ {
+ if((*flatIterator)->returnDomainID()!=sinkDomainID)
+ {
+ flatIterator=flattree.erase(flatIterator);
+ }
+ }
+
+ //No we need to trace back the routes for each entry in matchtree
+ flatIterator=flattree.begin();
+ for(;flatIterator!=flattree.end();++flatIterator)
+ {
+ //getting the route for the actual item
+ routingtree.getRoute(*flatIterator, &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();
+ for(;gatewayIterator!=listGatewayID.end();++gatewayIterator)
+ {
+ am_Gateway_s gatewayData;
+ if (mDatabaseHandler->getGatewayInfoDB(2,gatewayData) != E_OK) return (E_UNKNOWN);
+
+ //at the beginning of the route, we connect first the source to the first gateway
+ if (gatewayIterator ==listGatewayID.begin())
+ {
+ routingElement.sourceID = sourceID;
+ routingElement.domainID = sourceDomainID;
+ }
+ else
+ {
+ routingElement.sourceID = lastSource;
+ routingElement.domainID = gatewayData.domainSinkID;
+ }
+ routingElement.sinkID = gatewayData.sinkID;
+ actualRoutingElement.push_back(routingElement);
+ lastSource = gatewayData.sourceID;
+ }
+ //at the end of the route, connect to the sink !
+ routingElement.sourceID = lastSource;
+ routingElement.sinkID = sinkID;
+ routingElement.domainID = sinkDomainID;
+ actualRoutingElement.push_back(routingElement);
+
+ //So now we got the route, what is missing are the connectionFormats...
+
+ //Step through the routes and try to use always the best connectionFormat
+ std::vector<am_RoutingElement_s>::iterator routingInterator=actualRoutingElement.begin();
+ gatewayIterator =listGatewayID.begin();
+ if(findBestWay(actualRoutingElement,routingInterator,gatewayIterator,0)!=E_OK) continue;
+
+ //add the route to the list of routes...
+ actualRoute.sourceID = sourceID;
+ actualRoute.sinkID = sinkID;
+ actualRoute.route = actualRoutingElement;
+ returnList.push_back(actualRoute);
+ }
+ return (E_OK);
+}
+
+void Router::listPossibleConnectionFormats(const am_sourceID_t sourceID,const am_sinkID_t sinkID,std::vector<am_ConnectionFormat_e>& listFormats) const
+{
+ std::vector<am_ConnectionFormat_e> listSourceFormats;
+ std::vector<am_ConnectionFormat_e> listSinkFormats;
+ mDatabaseHandler->getListSinkConnectionFormats(sinkID,listSinkFormats);
+ mDatabaseHandler->getListSourceConnectionFormats(sourceID,listSourceFormats);
+ set_union(listSourceFormats.begin(), listSourceFormats.end(), listSinkFormats.begin(), listSinkFormats.end(), listFormats.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)
+{
+ std::vector<am_ConnectionFormat_e> listConnectionFormats;
+ std::vector<am_ConnectionFormat_e> listPriorityConnectionFormats;
+ //get best connection format for the first connection, now
+ listPossibleConnectionFormats(routeIterator->sinkID,routeIterator->sourceID,listConnectionFormats);
+
+ //if we get to the point that no choice makes sense, return ...
+ if (choiceNumber>=(int)listConnectionFormats.size()) return (E_NOT_POSSIBLE);
+
+ //if we have not just started, we need to take care about the gateways...
+ if(routeIterator!=listRoute.begin())
+ {
+ //since we have to deal with Gateways, there are restrictions what connectionFormat we can take. So we need to take the subset of connections that are restricted:
+ std::vector<am_ConnectionFormat_e> listRestrictedConnectionFormats;
+ listRestrictedOutputFormatsGateways(*gatewayIterator,(routeIterator--)->connectionFormat,listRestrictedConnectionFormats);
+ set_union(listConnectionFormats.begin(), listConnectionFormats.end(), listRestrictedConnectionFormats.begin(), listRestrictedConnectionFormats.end(), listConnectionFormats.begin());
+ }
+
+ //let the controller decide:
+ getConnectionFormatChoice(routeIterator->sinkID,routeIterator->sourceID,listConnectionFormats,listPriorityConnectionFormats);
+
+ //go back one step, if we cannot find a format!
+ if(listPriorityConnectionFormats.empty())
+ {
+ findBestWay(listRoute,routeIterator--,gatewayIterator--,choiceNumber++);
+ }
+ routeIterator->connectionFormat=listPriorityConnectionFormats.at(choiceNumber);
+
+ if (routeIterator<listRoute.end())
+ {
+ findBestWay(listRoute,routeIterator++,gatewayIterator++,0);
+ }
+ return (E_OK);
+}
+
+void Router::listRestrictedOutputFormatsGateways(const am_gatewayID_t gatewayID, const am_ConnectionFormat_e sinkConnectionFormat, std::vector<am_ConnectionFormat_e> & listFormats) const
+{
+ listFormats.clear();
+ am_Gateway_s gatewayData;
+ std::vector<am_ConnectionFormat_e>::const_iterator rowSinkIterator=gatewayData.listSinkFormats.begin();
+ std::vector<bool>::const_iterator matrixIterator=gatewayData.convertionMatrix.begin();
+ mDatabaseHandler->getGatewayInfoDB(gatewayID,gatewayData);
+
+ //find the row number of the sink
+ rowSinkIterator = find (gatewayData.listSinkFormats.begin(), gatewayData.listSinkFormats.end(), sinkConnectionFormat);
+ int rowNumberSink=rowSinkIterator - gatewayData.listSinkFormats.begin();
+
+ //go through the convertionMatrix and find out if the conversion is possible, if yes, add connectionFormat ...
+ matrixIterator+rowNumberSink;
+
+ //iterate line-wise through the matrix and add more formats
+ do
+ {
+ if(*matrixIterator)
+ {
+ listFormats.push_back(gatewayData.listSourceFormats.at(matrixIterator-gatewayData.convertionMatrix.begin()));
+ }
+ matrixIterator+gatewayData.listSinkFormats.size();
+ }
+ while (matrixIterator-gatewayData.convertionMatrix.begin()<(int)gatewayData.listSourceFormats.size());
+}
+
+
+Router::~Router()
+{
+}
+
+RoutingTreeItem::RoutingTreeItem(const am_domainID_t domainID, const am_gatewayID_t gatewayID, RoutingTreeItem *parent)
+ :mDomainID(domainID),
+ mGatewayID(gatewayID),
+ mParentItem(parent)
+{
+ assert(mDomainID==0);
+ assert(mGatewayID==0);
+ assert(mParentItem);
+}
+
+void RoutingTreeItem::appendChild(RoutingTreeItem *newChild)
+{
+ assert(newChild);
+ mListChildItems.push_back(newChild);
+}
+
+void RoutingTreeItem::returnChildItems(std::vector<RoutingTreeItem*> listChildItems)
+{
+ listChildItems=mListChildItems;
+}
+
+am_domainID_t RoutingTreeItem::returnDomainID() const
+{
+ return (mDomainID);
+}
+
+am_gatewayID_t RoutingTreeItem::returnGatewayID() const
+{
+ return (mGatewayID);
+}
+
+RoutingTreeItem* RoutingTreeItem::returnParent() const
+{
+ return (mParentItem);
+}
+
+RoutingTreeItem::~RoutingTreeItem()
+{
+}
+
+
+RoutingTree::RoutingTree(const am_domainID_t rootDomainID)
+ :mRootItem(RoutingTreeItem(rootDomainID))
+{
+ assert(rootDomainID!=0);
+}
+
+RoutingTreeItem *RoutingTree::insertItem(const am_domainID_t domainID, const am_gatewayID_t gatewayID, RoutingTreeItem *parent)
+{
+ RoutingTreeItem *newTree = new RoutingTreeItem(domainID, gatewayID,parent);
+ parent->appendChild(newTree);
+ mListChild.push_back(newTree);
+ return newTree;
+}
+
+void RoutingTree::getRoute(RoutingTreeItem *targetItem, std::vector<am_gatewayID_t> *listGateways)
+{
+ RoutingTreeItem *parentItem = targetItem;
+ while (parentItem != &mRootItem) {
+ listGateways->push_back(parentItem->returnGatewayID());
+ parentItem = parentItem->returnParent();
+ }
+}
+
+am_domainID_t RoutingTree::returnRootDomainID() const
+{
+ return (mRootItem.returnDomainID());
+}
+
+RoutingTreeItem *RoutingTree::returnRootItem()
+{
+ return (&mRootItem);
+}
+
+RoutingTree::~RoutingTree()
+{
+ std::vector<RoutingTreeItem*>::iterator it=mListChild.begin();
+ for(;it!=mListChild.end();++it)
+ {
+ delete *it;
+ }
+}
+
+
+
+
+
+
diff --git a/AudioManagerDaemon/src/main.cpp b/AudioManagerDaemon/src/main.cpp
index d2ed51d..3d940f6 100644
--- a/AudioManagerDaemon/src/main.cpp
+++ b/AudioManagerDaemon/src/main.cpp
@@ -205,8 +205,13 @@ void parseCommandLine(int argc, char **argv)
static void signalHandler (int sig, siginfo_t *siginfo, void *context)
{
+ (void)sig;
+ (void)siginfo;
+ (void)context;
DLT_LOG(AudioManager, DLT_LOG_ERROR, DLT_STRING("signal handler was called, exit now..."));
gDispatchDone=1;
+ //todo: maually fire the mainloop
+ //todo: ifdef no sockethandler
exit(1);
}
@@ -235,7 +240,7 @@ int main(int argc, char *argv[])
sigaction(SIGQUIT, &signalAction, NULL);
struct sigaction signalChildAction;
- memset (&signalAction, '\0', sizeof(signalChildAction));
+ memset (&signalChildAction, '\0', sizeof(signalChildAction));
signalChildAction.sa_flags = SA_NOCLDWAIT;
sigaction (SIGCHLD, &signalChildAction, NULL);
diff --git a/AudioManagerDaemon/test/controlInterface/CMakeLists.txt b/AudioManagerDaemon/test/controlInterface/CMakeLists.txt
index 024e6b2..0e4f1ee 100644
--- a/AudioManagerDaemon/test/controlInterface/CMakeLists.txt
+++ b/AudioManagerDaemon/test/controlInterface/CMakeLists.txt
@@ -52,6 +52,7 @@ file(GLOB CONTROL_INTERFACE_SRCS_CXX
"../../src/CommandSender.cpp"
"../../src/ControlReceiver.cpp"
"../../src/ControlSender.cpp"
+ "../../src/Router.cpp"
"../CommonFunctions.cpp"
"*.cpp"
)
diff --git a/AudioManagerDaemon/test/database/CMakeLists.txt b/AudioManagerDaemon/test/database/CMakeLists.txt
index 6a8b742..9e870d7 100644
--- a/AudioManagerDaemon/test/database/CMakeLists.txt
+++ b/AudioManagerDaemon/test/database/CMakeLists.txt
@@ -49,6 +49,7 @@ file(GLOB DATABASE_SRCS_CXX
"../../src/CommandSender.cpp"
"../../src/RoutingSender.cpp"
"../../src/ControlReceiver.cpp"
+ "../../src/Router.cpp"
"../CommonFunctions.cpp"
"*.cpp"
)
diff --git a/AudioManagerDaemon/test/routingInterface/CMakeLists.txt b/AudioManagerDaemon/test/routingInterface/CMakeLists.txt
index dc12a93..c29084e 100644
--- a/AudioManagerDaemon/test/routingInterface/CMakeLists.txt
+++ b/AudioManagerDaemon/test/routingInterface/CMakeLists.txt
@@ -50,6 +50,7 @@ file(GLOB ROUTING_INTERFACE_SRCS_CXX
"../../src/DatabaseObserver.cpp"
"../../src/CommandSender.cpp"
"../../src/RoutingSender.cpp"
+ "../../src/Router.cpp"
"../CommonFunctions.cpp"
"*.cpp"
)