summaryrefslogtreecommitdiff
path: root/AudioManagerDaemon/src
diff options
context:
space:
mode:
Diffstat (limited to 'AudioManagerDaemon/src')
-rw-r--r--AudioManagerDaemon/src/CAmControlReceiver.cpp32
-rw-r--r--AudioManagerDaemon/src/CAmControlSender.cpp18
-rw-r--r--AudioManagerDaemon/src/CAmDatabaseHandlerMap.cpp270
-rw-r--r--AudioManagerDaemon/src/CAmDatabaseHandlerSQLite.cpp1085
-rw-r--r--AudioManagerDaemon/src/CAmDatabaseObserver.cpp12
-rw-r--r--AudioManagerDaemon/src/CAmRouter.cpp1114
-rw-r--r--AudioManagerDaemon/src/CAmRoutingReceiver.cpp15
-rw-r--r--AudioManagerDaemon/src/CAmRoutingSender.cpp16
8 files changed, 1935 insertions, 627 deletions
diff --git a/AudioManagerDaemon/src/CAmControlReceiver.cpp b/AudioManagerDaemon/src/CAmControlReceiver.cpp
index ae017e2..f576f5e 100644
--- a/AudioManagerDaemon/src/CAmControlReceiver.cpp
+++ b/AudioManagerDaemon/src/CAmControlReceiver.cpp
@@ -184,6 +184,11 @@ am_Error_e CAmControlReceiver::enterGatewayDB(const am_Gateway_s & gatewayData,
return (mDatabaseHandler->enterGatewayDB(gatewayData, gatewayID));
}
+am_Error_e CAmControlReceiver::enterConverterDB(const am_Converter_s & converterData, am_converterID_t & converterID)
+{
+ return (mDatabaseHandler->enterConverterDB(converterData, converterID));
+}
+
am_Error_e CAmControlReceiver::enterSourceDB(const am_Source_s & sourceData, am_sourceID_t & sourceID)
{
return (mDatabaseHandler->enterSourceDB(sourceData, sourceID));
@@ -274,6 +279,11 @@ am_Error_e CAmControlReceiver::removeGatewayDB(const am_gatewayID_t gatewayID)
return (mDatabaseHandler->removeGatewayDB(gatewayID));
}
+am_Error_e CAmControlReceiver::removeConverterDB(const am_converterID_t converterID)
+{
+ return (mDatabaseHandler->removeConverterDB(converterID));
+}
+
am_Error_e CAmControlReceiver::removeCrossfaderDB(const am_crossfaderID_t crossfaderID)
{
return (mDatabaseHandler->removeCrossfaderDB(crossfaderID));
@@ -314,6 +324,12 @@ am_Error_e CAmControlReceiver::getGatewayInfoDB(const am_gatewayID_t gatewayID,
return (mDatabaseHandler->getGatewayInfoDB(gatewayID, gatewayData));
}
+am_Error_e CAmControlReceiver::getConverterInfoDB(const am_converterID_t converterID, am_Converter_s & converterData) const
+{
+ return (mDatabaseHandler->getConverterInfoDB(converterID, converterData));
+}
+
+
am_Error_e CAmControlReceiver::getCrossfaderInfoDB(const am_crossfaderID_t crossfaderID, am_Crossfader_s & crossfaderData) const
{
return (mDatabaseHandler->getCrossfaderInfoDB(crossfaderID, crossfaderData));
@@ -339,6 +355,11 @@ am_Error_e CAmControlReceiver::getListGatewaysOfDomain(const am_domainID_t domai
return (mDatabaseHandler->getListGatewaysOfDomain(domainID, listGatewaysID));
}
+am_Error_e CAmControlReceiver::getListConvertersOfDomain(const am_domainID_t domainID,std::vector<am_converterID_t>& listConverterID) const
+{
+ return (mDatabaseHandler->getListConvertersOfDomain(domainID,listConverterID));
+}
+
am_Error_e CAmControlReceiver::getListMainConnections(std::vector<am_MainConnection_s> & listMainConnections) const
{
return (mDatabaseHandler->getListMainConnections(listMainConnections));
@@ -384,6 +405,11 @@ am_Error_e CAmControlReceiver::getListGateways(std::vector<am_Gateway_s> & listG
return (mDatabaseHandler->getListGateways(listGateways));
}
+am_Error_e CAmControlReceiver::getListConverters(std::vector<am_Converter_s>& listConverters) const
+{
+ return (mDatabaseHandler->getListConverters(listConverters));
+}
+
am_Error_e CAmControlReceiver::getListSinkClasses(std::vector<am_SinkClass_s> & listSinkClasses) const
{
return (mDatabaseHandler->getListSinkClasses(listSinkClasses));
@@ -489,6 +515,12 @@ am_Error_e CAmControlReceiver::changeGatewayDB(const am_gatewayID_t gatewayID, c
return (mDatabaseHandler->changeGatewayDB(gatewayID,listSourceConnectionFormats,listSinkConnectionFormats,convertionMatrix));
}
+am_Error_e CAmControlReceiver::changeConverterDB(const am_converterID_t converterID, const std::vector<am_CustomConnectionFormat_t>& listSourceConnectionFormats, const std::vector<am_CustomConnectionFormat_t>& listSinkConnectionFormats, const std::vector<bool>& convertionMatrix)
+{
+ logInfo("CAmControlReceiver::changeConverterDB was called with converterID", converterID);
+ return (mDatabaseHandler->changeConverterDB(converterID,listSourceConnectionFormats,listSinkConnectionFormats,convertionMatrix));
+}
+
am_Error_e CAmControlReceiver::setVolumes(am_Handle_s& handle, const std::vector<am_Volumes_s>& listVolumes)
{
logInfo("CAmControlReceiver::setVolumes got called");
diff --git a/AudioManagerDaemon/src/CAmControlSender.cpp b/AudioManagerDaemon/src/CAmControlSender.cpp
index 229a28b..dd3558e 100644
--- a/AudioManagerDaemon/src/CAmControlSender.cpp
+++ b/AudioManagerDaemon/src/CAmControlSender.cpp
@@ -193,12 +193,24 @@ am_Error_e CAmControlSender::hookSystemRegisterGateway(const am_Gateway_s & gate
return (mController->hookSystemRegisterGateway(gatewayData, gatewayID));
}
+am_Error_e CAmControlSender::hookSystemRegisterConverter(const am_Converter_s& converterData, am_converterID_t& converterID)
+{
+ assert(mController);
+ return (mController->hookSystemRegisterConverter(converterData, converterID));
+}
+
am_Error_e CAmControlSender::hookSystemDeregisterGateway(const am_gatewayID_t gatewayID)
{
assert(mController);
return (mController->hookSystemDeregisterGateway(gatewayID));
}
+am_Error_e CAmControlSender::hookSystemDeregisterConverter(const am_converterID_t converterID)
+{
+ assert(mController);
+ return (mController->hookSystemDeregisterConverter(converterID));
+}
+
am_Error_e CAmControlSender::hookSystemRegisterCrossfader(const am_Crossfader_s & crossfaderData, am_crossfaderID_t & crossfaderID)
{
assert(mController);
@@ -414,6 +426,12 @@ am_Error_e CAmControlSender::hookSystemUpdateGateway(const am_gatewayID_t gatewa
return (mController->hookSystemUpdateGateway(gatewayID,listSourceConnectionFormats,listSinkConnectionFromats,convertionMatrix));
}
+am_Error_e CAmControlSender::hookSystemUpdateConverter(const am_converterID_t converterID, const std::vector<am_CustomConnectionFormat_t>& listSourceConnectionFormats, const std::vector<am_CustomConnectionFormat_t>& listSinkConnectionFromats, const std::vector<bool>& convertionMatrix)
+{
+ assert(mController);
+ return (mController->hookSystemUpdateConverter(converterID,listSourceConnectionFormats,listSinkConnectionFromats,convertionMatrix));
+}
+
void CAmControlSender::cbAckSetVolume(const am_Handle_s handle, const std::vector<am_Volumes_s>& listVolumes, const am_Error_e error)
{
assert(mController);
diff --git a/AudioManagerDaemon/src/CAmDatabaseHandlerMap.cpp b/AudioManagerDaemon/src/CAmDatabaseHandlerMap.cpp
index a7b765d..713eea1 100644
--- a/AudioManagerDaemon/src/CAmDatabaseHandlerMap.cpp
+++ b/AudioManagerDaemon/src/CAmDatabaseHandlerMap.cpp
@@ -26,13 +26,13 @@
#include <fstream>
#include <sstream>
#include <string>
-#include <algorithm>
#include <limits>
#include "CAmDatabaseHandlerMap.h"
#include "CAmDatabaseObserver.h"
#include "CAmRouter.h"
#include "shared/CAmDltWrapper.h"
+
namespace am
{
@@ -428,6 +428,7 @@ bool CAmDatabaseHandlerMap::CAmMappedData::increaseConnectionID(int16_t & result
CAmDatabaseHandlerMap::CAmDatabaseHandlerMap(): mFirstStaticSink(true), //
mFirstStaticSource(true), //
mFirstStaticGateway(true), //
+ mFirstStaticConverter(true), //
mFirstStaticSinkClass(true), //
mFirstStaticSourceClass(true), //
mFirstStaticCrossfader(true), //
@@ -665,7 +666,7 @@ am_Error_e CAmDatabaseHandlerMap::enterCrossfaderDB(const am_Crossfader_s & cros
if (crossfaderData.crossfaderID != 0 || mFirstStaticCrossfader)
{
//check if the ID already exists
- if (existcrossFader(crossfaderData.crossfaderID))
+ if (existCrossFader(crossfaderData.crossfaderID))
{
crossfaderID = crossfaderData.crossfaderID;
return (E_ALREADY_EXISTS);
@@ -758,6 +759,71 @@ am_Error_e CAmDatabaseHandlerMap::enterGatewayDB(const am_Gateway_s & gatewayDat
return (E_OK);
}
+bool CAmDatabaseHandlerMap::insertConverterDB(const am_Converter_s & converteData, am_converterID_t & converterID)
+{
+ int16_t nextID = 0;
+ if(mMappedData.increaseID(nextID, mMappedData.mCurrentConverterID, converteData.converterID))
+ {
+ converterID = nextID;
+ mMappedData.mConverterMap[nextID] = converteData;
+ mMappedData.mConverterMap[nextID].converterID = nextID;
+ return (true);
+ }
+ else
+ {
+ converterID = 0;
+ logInfo(__PRETTY_FUNCTION__,"Max limit reached.");
+ return (false);
+ }
+}
+
+am_Error_e CAmDatabaseHandlerMap::enterConverterDB(const am_Converter_s & converterData, am_converterID_t & converterID)
+{
+ assert(converterData.converterID<DYNAMIC_ID_BOUNDARY);
+ assert(converterData.sinkID!=0);
+ assert(converterData.sourceID!=0);
+ assert(converterData.domainID!=0);
+ assert(!converterData.name.empty());
+ assert(!converterData.convertionMatrix.empty());
+ assert(!converterData.listSinkFormats.empty());
+ assert(!converterData.listSourceFormats.empty());
+
+ //might be that the sinks and sources are not there during registration time
+ //assert(existSink(gatewayData.sinkID));
+ //assert(existSource(gatewayData.sourceID));
+
+ am_converterID_t tempID = 0;
+ am_converterID_t tempIndex = 0;
+ //if gatewayData is zero and the first Static Sink was already entered, the ID is created
+ bool result;
+ if (converterData.converterID != 0 || mFirstStaticConverter)
+ {
+ //check if the ID already exists
+ if (existGateway(converterData.converterID))
+ {
+ converterID = converterData.converterID;
+ return (E_ALREADY_EXISTS);
+ }
+ }
+ result = insertConverterDB(converterData, tempID);
+ if( false == result )
+ return (E_UNKNOWN);
+
+ tempIndex = tempID;
+ //if the ID is not created, we add it to the query
+ if (converterData.converterID == 0 && mFirstStaticConverter)
+ {
+ mFirstStaticConverter = false;
+ }
+ mMappedData.mConverterMap[tempIndex].converterID = tempID;
+ converterID = tempID;
+
+ logInfo("DatabaseHandler::enterConverterDB entered new converter with name", converterData.name, "sourceID:", converterData.sourceID, "sinkID:", converterData.sinkID, "assigned ID:", converterID);
+ if (mpDatabaseObserver)
+ mpDatabaseObserver->newConverter(mMappedData.mConverterMap[tempIndex]);
+ return (E_OK);
+}
+
void CAmDatabaseHandlerMap::dump( std::ostream & output ) const
{
output << std::endl << "****************** DUMP START ******************" << std::endl;
@@ -1274,11 +1340,28 @@ am_Error_e CAmDatabaseHandlerMap::removeGatewayDB(const am_gatewayID_t gatewayID
return (E_OK);
}
+am_Error_e CAmDatabaseHandlerMap::removeConverterDB(const am_converterID_t converterID)
+{
+ assert(converterID!=0);
+
+ if (!existConverter(converterID))
+ {
+ return (E_NON_EXISTENT);
+ }
+
+ mMappedData.mConverterMap.erase(converterID);
+
+ logInfo("DatabaseHandler::removeConverterDB removed:", converterID);
+ if (mpDatabaseObserver)
+ mpDatabaseObserver->removeConverter(converterID);
+ return (E_OK);
+}
+
am_Error_e CAmDatabaseHandlerMap::removeCrossfaderDB(const am_crossfaderID_t crossfaderID)
{
assert(crossfaderID!=0);
- if (!existcrossFader(crossfaderID))
+ if (!existCrossFader(crossfaderID))
{
return (E_NON_EXISTENT);
}
@@ -1480,10 +1563,24 @@ am_Error_e CAmDatabaseHandlerMap::getGatewayInfoDB(const am_gatewayID_t gatewayI
}
+am_Error_e CAmDatabaseHandlerMap::getConverterInfoDB(const am_converterID_t converterID, am_Converter_s& converterData) const
+{
+ assert(converterID!=0);
+ if (!existConverter(converterID))
+ {
+ return (E_NON_EXISTENT);
+ }
+
+ converterData = mMappedData.mConverterMap.at(converterID);
+
+ return (E_OK);
+
+}
+
am_Error_e CAmDatabaseHandlerMap::getCrossfaderInfoDB(const am_crossfaderID_t crossfaderID, am_Crossfader_s & crossfaderData) const
{
assert(crossfaderID!=0);
- if (!existcrossFader(crossfaderID))
+ if (!existCrossFader(crossfaderID))
{
return (E_NON_EXISTENT);
}
@@ -1574,6 +1671,24 @@ am_Error_e CAmDatabaseHandlerMap::getListGatewaysOfDomain(const am_domainID_t do
return (E_OK);
}
+am_Error_e CAmDatabaseHandlerMap::getListConvertersOfDomain(const am_domainID_t domainID, std::vector<am_converterID_t>& listConvertersID) const
+{
+ assert(domainID!=0);
+ listConvertersID.clear();
+ if (!existDomain(domainID))
+ {
+ return (E_NON_EXISTENT);
+ }
+
+ CAmMapConverter::const_iterator elementIterator = mMappedData.mConverterMap.begin();
+ for (;elementIterator != mMappedData.mConverterMap.end(); ++elementIterator)
+ {
+ if (domainID==elementIterator->second.domainID)
+ listConvertersID.push_back(elementIterator->second.converterID);
+ }
+ return (E_OK);
+}
+
am_Error_e CAmDatabaseHandlerMap::getListMainConnections(std::vector<am_MainConnection_s> & listMainConnections) const
{
listMainConnections.clear();
@@ -1673,6 +1788,17 @@ am_Error_e CAmDatabaseHandlerMap::getListGateways(std::vector<am_Gateway_s> & li
return (E_OK);
}
+am_Error_e CAmDatabaseHandlerMap::getListConverters(std::vector<am_Converter_s> & listConverters) const
+{
+ listConverters.clear();
+
+ std::for_each(mMappedData.mConverterMap.begin(), mMappedData.mConverterMap.end(), [&](const std::pair<am_converterID_t, am_Converter_s>& ref) {
+ listConverters.push_back(ref.second);
+ });
+
+ return (E_OK);
+}
+
am_Error_e CAmDatabaseHandlerMap::getListSinkClasses(std::vector<am_SinkClass_s> & listSinkClasses) const
{
listSinkClasses.clear();
@@ -1959,6 +2085,11 @@ bool CAmDatabaseHandlerMap::existGateway(const am_gatewayID_t gatewayID) const
return existsObjectWithKeyInMap(gatewayID, mMappedData.mGatewayMap);
}
+bool CAmDatabaseHandlerMap::existConverter(const am_converterID_t converterID) const
+{
+ return existsObjectWithKeyInMap(converterID, mMappedData.mConverterMap);
+}
+
am_Error_e CAmDatabaseHandlerMap::getDomainOfSource(const am_sourceID_t sourceID, am_domainID_t & domainID) const
{
assert(sourceID!=0);
@@ -2141,7 +2272,7 @@ bool CAmDatabaseHandlerMap::existConnectionID(const am_connectionID_t connection
* @param crossfaderID the ID of the crossfader to be checked
* @return true if exists
*/
-bool CAmDatabaseHandlerMap::existcrossFader(const am_crossfaderID_t crossfaderID) const
+bool CAmDatabaseHandlerMap::existCrossFader(const am_crossfaderID_t crossfaderID) const
{
return existsObjectWithKeyInMap(crossfaderID, mMappedData.mCrossfaderMap);
}
@@ -2421,7 +2552,7 @@ am_Error_e CAmDatabaseHandlerMap::changeCrossFaderHotSink(const am_crossfaderID_
assert(crossfaderID!=0);
assert(hotsink!=HS_UNKNOWN);
- if (!existcrossFader(crossfaderID))
+ if (!existCrossFader(crossfaderID))
{
return (E_NON_EXISTENT);
}
@@ -2430,54 +2561,16 @@ am_Error_e CAmDatabaseHandlerMap::changeCrossFaderHotSink(const am_crossfaderID_
return (E_OK);
}
-am_Error_e CAmDatabaseHandlerMap::getRoutingTree(bool onlyfree, CAmRoutingTree& tree, std::vector<CAmRoutingTreeItem*>& flatTree)
+bool CAmDatabaseHandlerMap::isComponentConnected(const am_Gateway_s & gateway) const
{
- am_domainID_t rootID = tree.returnRootDomainID();
- CAmRoutingTreeItem *parent = tree.returnRootItem();
- size_t i = 0;
-
- do
- {
- if (i != 0)
- {
- parent = flatTree.at(i - 1);
- rootID = parent->returnDomainID();
- }
- std::for_each(mMappedData.mGatewayMap.begin(),mMappedData.mGatewayMap.end(), [&](const std::pair<am_gatewayID_t, am_Gateway_s>& refGateway) {
- if( rootID==refGateway.second.domainSinkID )
- {
- if(!onlyfree || std::find_if(mMappedData.mConnectionMap.begin(),
- mMappedData.mConnectionMap.end(),
- [&](const std::pair<am_connectionID_t, am_Connection_Database_s>& refConnection)
- {
- return (refConnection.second.sinkID == refGateway.second.sinkID ||
- refConnection.second.sourceID ==refGateway.second.sourceID);
- })==mMappedData.mConnectionMap.end() )
- {
- // additional check to avoid cyclic routes
- const am_domainID_t domainSourceID = refGateway.second.domainSourceID;
- bool sourceDomainAlreadyHandledAsSink = false;
- for (std::vector<CAmRoutingTreeItem*>::const_iterator iFT = flatTree.begin(); iFT != flatTree.end(); ++iFT)
- {
- if (domainSourceID == (*iFT)->returnParent()->returnDomainID())
- {
- sourceDomainAlreadyHandledAsSink = true;
- break;
- }
- }
-
- if (!sourceDomainAlreadyHandledAsSink)
- {
- // logInfo("DatabaseHandler::getRoutingTree ", rootID, ", ", domainSourceID, ", ", sqlite3_column_int(query, 1));
- flatTree.push_back(tree.insertItem(domainSourceID, refGateway.second.gatewayID, parent));
- }
- }
- }
- });
- i++;
- } while (flatTree.size() > (i - 1));
+ bool ret = isConnected(gateway);
+ return ret;
+}
- return (E_OK);
+bool CAmDatabaseHandlerMap::isComponentConnected(const am_Converter_s & converter) const
+{
+ bool ret = isConnected(converter);
+ return ret;
}
am_Error_e am::CAmDatabaseHandlerMap::peekSinkClassID(const std::string & name, am_sinkClass_t & sinkClassID)
@@ -2731,6 +2824,37 @@ am_Error_e CAmDatabaseHandlerMap::changeGatewayDB(const am_gatewayID_t gatewayID
return (E_OK);
}
+am_Error_e CAmDatabaseHandlerMap::changeConverterDB(const am_converterID_t converterID, const std::vector<am_CustomConnectionFormat_t>& listSourceConnectionFormats, const std::vector<am_CustomConnectionFormat_t>& listSinkConnectionFormats, const std::vector<bool>& convertionMatrix)
+{
+ assert(converterID!=0);
+
+ if (!existConverter(converterID))
+ {
+ return (E_NON_EXISTENT);
+ }
+
+ if (!listSourceConnectionFormats.empty())
+ {
+ mMappedData.mConverterMap.at(converterID).listSourceFormats = listSourceConnectionFormats;
+ }
+
+ if (!listSinkConnectionFormats.empty())
+ {
+ mMappedData.mConverterMap.at(converterID).listSinkFormats = listSinkConnectionFormats;
+ }
+
+ if (!convertionMatrix.empty())
+ {
+ mListConnectionFormat.clear();
+ mListConnectionFormat.insert(std::make_pair(converterID, convertionMatrix));
+ }
+
+ logInfo("DatabaseHandler::changeConverterDB changed Gateway with ID", converterID);
+
+ //todo: check if observer needs to be adopted.
+ return (E_OK);
+}
+
bool changeNotificationConfiguration(std::vector<am_NotificationConfiguration_s> & listNotificationConfigurations, const am_NotificationConfiguration_s & notificationConfiguration)
{
bool changed = false;
@@ -2782,4 +2906,46 @@ am_Error_e CAmDatabaseHandlerMap::changeSourceNotificationConfigurationDB(const
return (E_NON_EXISTENT);
}
+am_Error_e CAmDatabaseHandlerMap::enumerateSources(std::function<void(const am_Source_s & element)> cb) const
+{
+ for(auto it = mMappedData.mSourceMap.begin(); it!=mMappedData.mSourceMap.end(); it++)
+ {
+ const am_Source_Database_s *pObject = &it->second;
+ if( 0==pObject->reserved )
+ cb(*pObject);
+ }
+ return E_OK;
+}
+
+am_Error_e CAmDatabaseHandlerMap::enumerateSinks(std::function<void(const am_Sink_s & element)> cb) const
+{
+ for(auto it = mMappedData.mSinkMap.begin(); it!=mMappedData.mSinkMap.end(); it++)
+ {
+ const am_Sink_Database_s *pObject = &it->second;
+ if( 0==pObject->reserved )
+ cb(*pObject);
+ }
+ return E_OK;
+}
+
+am_Error_e CAmDatabaseHandlerMap::enumerateGateways(std::function<void(const am_Gateway_s & element)> cb) const
+{
+ for(auto it = mMappedData.mGatewayMap.begin(); it!=mMappedData.mGatewayMap.end(); it++)
+ {
+ const am_Gateway_s *pObject = &it->second;
+ cb(*pObject);
+ }
+ return E_OK;
+}
+
+am_Error_e CAmDatabaseHandlerMap::enumerateConverters(std::function<void(const am_Converter_s & element)> cb) const
+{
+ for(auto it = mMappedData.mConverterMap.begin(); it!=mMappedData.mConverterMap.end(); it++)
+ {
+ const am_Converter_s *pObject = &it->second;
+ cb(*pObject);
+ }
+ return E_OK;
+}
+
}
diff --git a/AudioManagerDaemon/src/CAmDatabaseHandlerSQLite.cpp b/AudioManagerDaemon/src/CAmDatabaseHandlerSQLite.cpp
index 1390fc4..cb95ec6 100644
--- a/AudioManagerDaemon/src/CAmDatabaseHandlerSQLite.cpp
+++ b/AudioManagerDaemon/src/CAmDatabaseHandlerSQLite.cpp
@@ -104,6 +104,7 @@ namespace am
#define SOURCE_TABLE "Sources" //!< source table
#define SINK_TABLE "Sinks" //!< sink table
#define GATEWAY_TABLE "Gateways" //!< gateway table
+#define CONVERTER_TABLE "Converters" //!< converter table
#define CROSSFADER_TABLE "Crossfaders" //!< crossfader table
#define CONNECTION_TABLE "Connections" //!< connection table
#define MAINCONNECTION_TABLE "MainConnections" //!< main connection table
@@ -118,6 +119,7 @@ const std::string databaseTables[] =
" 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);", //
+ " Converters (converterID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, name VARCHAR(50), sinkID INTEGER, sourceID INTEGER, domainID INTEGER);", //
" 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);", //
@@ -140,6 +142,7 @@ CAmDatabaseHandlerSQLite::CAmDatabaseHandlerSQLite():mpDatabaseObserver(NULL), /
mFirstStaticSink(true), //
mFirstStaticSource(true), //
mFirstStaticGateway(true), //
+ mFirstStaticConverter(true),
mFirstStaticSinkClass(true), //
mFirstStaticSourceClass(true), //
mFirstStaticCrossfader(true), //
@@ -154,6 +157,7 @@ CAmDatabaseHandlerSQLite::CAmDatabaseHandlerSQLite(std::string databasePath):mpD
mFirstStaticSink(true), //
mFirstStaticSource(true), //
mFirstStaticGateway(true), //
+ mFirstStaticConverter(true),
mFirstStaticSinkClass(true), //
mFirstStaticSourceClass(true), //
mFirstStaticCrossfader(true), //
@@ -582,7 +586,7 @@ am_Error_e CAmDatabaseHandlerSQLite::enterCrossfaderDB(const am_Crossfader_s & c
else
{
//check if the ID already exists
- if (existcrossFader(crossfaderData.crossfaderID))
+ if (existCrossFader(crossfaderData.crossfaderID))
return (E_ALREADY_EXISTS);
command = "INSERT INTO " + std::string(CROSSFADER_TABLE) + "(name, sinkID_A, sinkID_B, sourceID, hotSink, crossfaderID) VALUES (?,?,?,?,?,?)";
}
@@ -760,6 +764,119 @@ am_Error_e CAmDatabaseHandlerSQLite::enterGatewayDB(const am_Gateway_s & gateway
return (E_OK);
}
+am_Error_e CAmDatabaseHandlerSQLite::enterConverterDB(const am_Converter_s & converterData, am_converterID_t & converterID)
+{
+ assert(converterData.converterID<DYNAMIC_ID_BOUNDARY);
+ assert(converterData.sinkID!=0);
+ assert(converterData.sourceID!=0);
+ assert(converterData.domainID!=0);
+ assert(!converterData.name.empty());
+ assert(!converterData.convertionMatrix.empty());
+ assert(!converterData.listSinkFormats.empty());
+ assert(!converterData.listSourceFormats.empty());
+
+ //might be that the sinks and sources are not there during registration time
+ //assert(existSink(gatewayData.sinkID));
+ //assert(existSource(gatewayData.sourceID));
+
+ sqlite3_stmt* query = NULL;
+ int eCode = 0;
+ std::string command;
+
+ //if gatewayData is zero and the first Static Sink was already entered, the ID is created
+ if (converterData.converterID == 0 && !mFirstStaticConverter)
+ {
+ command = "INSERT INTO " + std::string(CONVERTER_TABLE) + "(name, sinkID, sourceID, domainID) VALUES (?,?,?,?)";
+ }
+ else
+ {
+ //check if the ID already exists
+ if (existConverter(converterData.converterID))
+ return (E_ALREADY_EXISTS);
+ command = "INSERT INTO " + std::string(CONVERTER_TABLE) + "(name, sinkID, sourceID, domainID, converterID) VALUES (?,?,?,?,?)";
+ }
+
+ MY_SQLITE_PREPARE_V2(mpDatabase, command.c_str(), -1, &query, NULL)
+ MY_SQLITE_BIND_TEXT(query, 1, converterData.name.c_str(), converterData.name.size(), SQLITE_STATIC)
+ MY_SQLITE_BIND_INT(query, 2, converterData.sinkID)
+ MY_SQLITE_BIND_INT(query, 3, converterData.sourceID)
+ MY_SQLITE_BIND_INT(query, 4, converterData.domainID)
+
+ //if the ID is not created, we add it to the query
+ if (converterData.converterID != 0)
+ {
+ MY_SQLITE_BIND_INT(query, 5, converterData.converterID)
+ }
+
+ //if the first static sink is entered, we need to set it onto the boundary
+ else if (mFirstStaticConverter)
+ {
+ MY_SQLITE_BIND_INT(query, 5, DYNAMIC_ID_BOUNDARY)
+ mFirstStaticConverter = false;
+ }
+
+ if ((eCode = sqlite3_step(query)) != SQLITE_DONE)
+ {
+ logError("DatabaseHandler::enterConverterDB SQLITE Step error code:", eCode);
+ MY_SQLITE_FINALIZE(query)
+ return (E_DATABASE_ERROR);
+ }
+
+ MY_SQLITE_FINALIZE(query)
+
+ converterID = sqlite3_last_insert_rowid(mpDatabase);
+
+ //now the convertion matrix todo: change the map implementation sometimes to blob in sqlite
+ mListConnectionFormat.insert(std::make_pair(converterID, converterData.convertionMatrix));
+
+ command = "CREATE TABLE ConverterSourceFormat" + i2s(converterID) + std::string("(soundFormat INTEGER)");
+ if (!this->sqQuery(command))
+ return (E_DATABASE_ERROR);
+ command = "CREATE TABLE ConverterSinkFormat" + i2s(converterID) + std::string("(soundFormat INTEGER)");
+ if (!this->sqQuery(command))
+ return (E_DATABASE_ERROR);
+
+ //fill ConnectionFormats
+ command = "INSERT INTO ConverterSourceFormat" + i2s(converterID) + std::string("(soundFormat) VALUES (?)");
+ MY_SQLITE_PREPARE_V2(mpDatabase, command.c_str(), -1, &query, NULL)
+ std::vector<am_CustomConnectionFormat_t>::const_iterator connectionFormatIterator = converterData.listSourceFormats.begin();
+ for (; connectionFormatIterator < converterData.listSourceFormats.end(); ++connectionFormatIterator)
+ {
+ MY_SQLITE_BIND_INT(query, 1, *connectionFormatIterator)
+ if ((eCode = sqlite3_step(query)) != SQLITE_DONE)
+ {
+ logError("DatabaseHandler::enterConverterDB SQLITE Step error code:", eCode);
+ MY_SQLITE_FINALIZE(query)
+ return (E_DATABASE_ERROR);
+ }
+ MY_SQLITE_RESET(query)
+ }
+ MY_SQLITE_FINALIZE(query)
+
+ command = "INSERT INTO ConverterSinkFormat" + i2s(converterID) + std::string("(soundFormat) VALUES (?)");
+ MY_SQLITE_PREPARE_V2(mpDatabase, command.c_str(), -1, &query, NULL)
+ connectionFormatIterator = converterData.listSinkFormats.begin();
+ for (; connectionFormatIterator < converterData.listSinkFormats.end(); ++connectionFormatIterator)
+ {
+ MY_SQLITE_BIND_INT(query, 1, *connectionFormatIterator)
+ if ((eCode = sqlite3_step(query)) != SQLITE_DONE)
+ {
+ logError("DatabaseHandler::enterConverterDB SQLITE Step error code:", eCode);
+ MY_SQLITE_FINALIZE(query)
+ return (E_DATABASE_ERROR);
+ }
+ MY_SQLITE_RESET(query)
+ }
+ MY_SQLITE_FINALIZE(query)
+
+ logInfo("DatabaseHandler::enterConverterDB entered new gateway with name", converterData.name, "sourceID:", converterData.sourceID, "sinkID:", converterData.sinkID, "assigned ID:", converterID);
+ am_Converter_s converter = converterData;
+ converter.converterID = converterID;
+ if (mpDatabaseObserver)
+ mpDatabaseObserver->newConverter(converter);
+ return (E_OK);
+}
+
am_Error_e CAmDatabaseHandlerSQLite::enterSourceDB(const am_Source_s & sourceData, am_sourceID_t & sourceID)
{
assert(sourceData.sourceID<DYNAMIC_ID_BOUNDARY);
@@ -1438,11 +1555,28 @@ am_Error_e CAmDatabaseHandlerSQLite::removeGatewayDB(const am_gatewayID_t gatewa
return (E_OK);
}
+am_Error_e CAmDatabaseHandlerSQLite::removeConverterDB(const am_converterID_t converterID)
+{
+ assert(converterID!=0);
+
+ if (!existConverter(converterID))
+ {
+ return (E_NON_EXISTENT);
+ }
+ std::string command = "DELETE from " + std::string(CONVERTER_TABLE) + " WHERE converterID=" + i2s(converterID);
+ if (!sqQuery(command))
+ return (E_DATABASE_ERROR);
+ logInfo("DatabaseHandler::removeConverterDB removed:", converterID);
+ if (mpDatabaseObserver)
+ mpDatabaseObserver->removeConverter(converterID);
+ return (E_OK);
+}
+
am_Error_e CAmDatabaseHandlerSQLite::removeCrossfaderDB(const am_crossfaderID_t crossfaderID)
{
assert(crossfaderID!=0);
- if (!existcrossFader(crossfaderID))
+ if (!existCrossFader(crossfaderID))
{
return (E_NON_EXISTENT);
}
@@ -2061,10 +2195,79 @@ am_Error_e CAmDatabaseHandlerSQLite::getGatewayInfoDB(const am_gatewayID_t gatew
}
+am_Error_e CAmDatabaseHandlerSQLite::getConverterInfoDB(const am_converterID_t converterID, am_Converter_s& converterData) const
+{
+ assert(converterID!=0);
+ if (!existConverter(converterID))
+ {
+ return (E_NON_EXISTENT);
+ }
+ sqlite3_stmt* query = NULL, *qSinkConnectionFormat = NULL, *qSourceConnectionFormat = NULL;
+ int eCode = 0;
+ am_CustomConnectionFormat_t tempConnectionFormat;
+ std::string command = "SELECT name, sinkID, sourceID, domainID, converterID FROM " + std::string(CONVERTER_TABLE) + " WHERE converterID=" + i2s(converterID);
+ MY_SQLITE_PREPARE_V2(mpDatabase, command.c_str(), -1, &query, NULL)
+
+ while ((eCode = sqlite3_step(query)) == SQLITE_ROW)
+ {
+ converterData.name = std::string((const char*) sqlite3_column_text(query, 0));
+ converterData.sinkID = sqlite3_column_int(query, 1);
+ converterData.sourceID = sqlite3_column_int(query, 2);
+ converterData.domainID = sqlite3_column_int(query, 3);
+ converterData.converterID = sqlite3_column_int(query, 4);
+
+ //convertionMatrix:
+ ListConnectionFormat::const_iterator iter = mListConnectionFormat.begin();
+ iter = mListConnectionFormat.find(converterData.converterID);
+ if (iter == mListConnectionFormat.end())
+ {
+ logError("DatabaseHandler::getConverterInfoDB database error with convertionFormat");
+ MY_SQLITE_FINALIZE(query)
+ return (E_DATABASE_ERROR);
+ }
+ converterData.convertionMatrix = iter->second;
+
+ //read out the connectionFormats
+ std::string commandConnectionFormat = "SELECT soundFormat FROM ConverterSourceFormat" + i2s(converterData.converterID);
+ MY_SQLITE_PREPARE_V2(mpDatabase, commandConnectionFormat.c_str(), -1, &qSourceConnectionFormat, NULL)
+ while ((eCode = sqlite3_step(qSourceConnectionFormat)) == SQLITE_ROW)
+ {
+ tempConnectionFormat = (am_CustomConnectionFormat_t) sqlite3_column_int(qSourceConnectionFormat, 0);
+ converterData.listSourceFormats.push_back(tempConnectionFormat);
+ }
+
+ MY_SQLITE_FINALIZE(qSourceConnectionFormat)
+
+ //read out sound properties
+ commandConnectionFormat = "SELECT soundFormat FROM ConverterSinkFormat" + i2s(converterData.converterID);
+ MY_SQLITE_PREPARE_V2(mpDatabase, commandConnectionFormat.c_str(), -1, &qSinkConnectionFormat, NULL)
+ while ((eCode = sqlite3_step(qSinkConnectionFormat)) == SQLITE_ROW)
+ {
+ tempConnectionFormat = (am_CustomConnectionFormat_t) sqlite3_column_int(qSinkConnectionFormat, 0);
+ converterData.listSinkFormats.push_back(tempConnectionFormat);
+ }
+
+ MY_SQLITE_FINALIZE(qSinkConnectionFormat)
+
+ }
+
+ if (eCode != SQLITE_DONE)
+ {
+ logError("DatabaseHandler::getConverterInfoDB SQLITE error code:", eCode);
+ MY_SQLITE_FINALIZE(query)
+ return (E_DATABASE_ERROR);
+ }
+
+ MY_SQLITE_FINALIZE(query)
+
+ return (E_OK);
+
+}
+
am_Error_e CAmDatabaseHandlerSQLite::getCrossfaderInfoDB(const am_crossfaderID_t crossfaderID, am_Crossfader_s & crossfaderData) const
{
assert(crossfaderID!=0);
- if (!existcrossFader(crossfaderID))
+ if (!existCrossFader(crossfaderID))
{
return (E_NON_EXISTENT);
}
@@ -2226,6 +2429,39 @@ am_Error_e CAmDatabaseHandlerSQLite::getListGatewaysOfDomain(const am_domainID_t
return (E_OK);
}
+am_Error_e CAmDatabaseHandlerSQLite::getListConvertersOfDomain(const am_domainID_t domainID, std::vector<am_converterID_t>& listConvertersID) const
+{
+ assert(domainID!=0);
+ listConvertersID.clear();
+ if (!existDomain(domainID))
+ {
+ return (E_NON_EXISTENT);
+ }
+ sqlite3_stmt* query = NULL;
+ int eCode = 0;
+ am_gatewayID_t temp;
+
+ std::string command = "SELECT converterID FROM " + std::string(CONVERTER_TABLE) + " WHERE domainID=" + i2s(domainID);
+ MY_SQLITE_PREPARE_V2(mpDatabase, command.c_str(), -1, &query, NULL)
+
+ while ((eCode = sqlite3_step(query)) == SQLITE_ROW)
+ {
+ temp = sqlite3_column_int(query, 0);
+ listConvertersID.push_back(temp);
+ }
+
+ if (eCode != SQLITE_DONE)
+ {
+ logError("DatabaseHandler::getListConvertersOfDomain SQLITE error code:", eCode);
+ MY_SQLITE_FINALIZE(query)
+ return (E_DATABASE_ERROR);
+ }
+
+ MY_SQLITE_FINALIZE(query)
+
+ return (E_OK);
+}
+
am_Error_e CAmDatabaseHandlerSQLite::getListMainConnections(std::vector<am_MainConnection_s> & listMainConnections) const
{
listMainConnections.clear();
@@ -2332,217 +2568,13 @@ am_Error_e CAmDatabaseHandlerSQLite::getListConnections(std::vector<am_Connectio
am_Error_e CAmDatabaseHandlerSQLite::getListSinks(std::vector<am_Sink_s> & listSinks) const
{
listSinks.clear();
- sqlite3_stmt* query = NULL, *qConnectionFormat = NULL, *qSoundProperty = NULL, *qNotificationConfiguration= NULL, *qMAinSoundProperty = NULL, *qMainNotificationConfiguration= NULL;
- int eCode = 0;
- am_Sink_s temp;
- am_CustomConnectionFormat_t tempConnectionFormat;
- am_SoundProperty_s tempSoundProperty;
- am_MainSoundProperty_s tempMainSoundProperty;
- am_NotificationConfiguration_s tempNotificationConfiguration;
- am_NotificationConfiguration_s tempMainNotificationConfiguration;
- std::string command = "SELECT name, domainID, sinkClassID, volume, visible, availability, availabilityReason, muteState, mainVolume, sinkID FROM " + std::string(SINK_TABLE) + " WHERE reserved=0";
- MY_SQLITE_PREPARE_V2(mpDatabase, command.c_str(), -1, &query, NULL)
-
- while ((eCode = sqlite3_step(query)) == SQLITE_ROW)
- {
- temp.name = std::string((const char*) sqlite3_column_text(query, 0));
- temp.domainID = sqlite3_column_int(query, 1);
- temp.sinkClassID = sqlite3_column_int(query, 2);
- temp.volume = sqlite3_column_int(query, 3);
- temp.visible = sqlite3_column_int(query, 4);
- temp.available.availability = (am_Availability_e) sqlite3_column_int(query, 5);
- temp.available.availabilityReason = (am_CustomAvailabilityReason_t) sqlite3_column_int(query, 6);
- temp.muteState = (am_MuteState_e) sqlite3_column_int(query, 7);
- temp.mainVolume = sqlite3_column_int(query, 8);
- temp.sinkID = sqlite3_column_int(query, 9);
-
- //read out the connectionFormats
- std::string commandConnectionFormat = "SELECT soundFormat FROM SinkConnectionFormat" + i2s(temp.sinkID);
- MY_SQLITE_PREPARE_V2(mpDatabase, commandConnectionFormat.c_str(), -1, &qConnectionFormat, NULL)
- while ((eCode = sqlite3_step(qConnectionFormat)) == SQLITE_ROW)
- {
- tempConnectionFormat = (am_CustomConnectionFormat_t) sqlite3_column_int(qConnectionFormat, 0);
- temp.listConnectionFormats.push_back(tempConnectionFormat);
- }
-
- MY_SQLITE_FINALIZE(qConnectionFormat)
-
- //read out sound properties
- std::string commandSoundProperty = "SELECT soundPropertyType, value FROM SinkSoundProperty" + i2s(temp.sinkID);
- MY_SQLITE_PREPARE_V2(mpDatabase, commandSoundProperty.c_str(), -1, &qSoundProperty, NULL)
- while ((eCode = sqlite3_step(qSoundProperty)) == SQLITE_ROW)
- {
- tempSoundProperty.type = (am_CustomSoundPropertyType_t) sqlite3_column_int(qSoundProperty, 0);
- tempSoundProperty.value = sqlite3_column_int(qSoundProperty, 1);
- temp.listSoundProperties.push_back(tempSoundProperty);
- }
-
- MY_SQLITE_FINALIZE(qSoundProperty)
-
- //read out notifications
- std::string commandNotificationConfiguration = "SELECT type, status, parameter FROM SinkNotificationConfiguration" + i2s(temp.sinkID);
- MY_SQLITE_PREPARE_V2(mpDatabase, commandNotificationConfiguration.c_str(), -1, &qNotificationConfiguration, NULL)
- while ((eCode = sqlite3_step(qNotificationConfiguration)) == SQLITE_ROW)
- {
- tempNotificationConfiguration.type = static_cast<am_CustomNotificationType_t> (sqlite3_column_int(qNotificationConfiguration, 0));
- tempNotificationConfiguration.status = static_cast<am_NotificationStatus_e> (sqlite3_column_int(qNotificationConfiguration, 1));
- tempNotificationConfiguration.parameter = static_cast<int16_t> (sqlite3_column_int(qNotificationConfiguration, 2));
- temp.listNotificationConfigurations.push_back(tempNotificationConfiguration);
- }
-
- MY_SQLITE_FINALIZE(qNotificationConfiguration)
-
- //read out MainSoundProperties if sink is visible
- if(temp.visible)
- {
- std::string commandMainSoundProperty = "SELECT soundPropertyType, value FROM SinkMainSoundProperty" + i2s(temp.sinkID);
- MY_SQLITE_PREPARE_V2(mpDatabase, commandMainSoundProperty.c_str(), -1, &qMAinSoundProperty, NULL)
- while ((eCode = sqlite3_step(qMAinSoundProperty)) == SQLITE_ROW)
- {
- tempMainSoundProperty.type = (am_CustomMainSoundPropertyType_t) sqlite3_column_int(qMAinSoundProperty, 0);
- tempMainSoundProperty.value = sqlite3_column_int(qMAinSoundProperty, 1);
- temp.listMainSoundProperties.push_back(tempMainSoundProperty);
- }
-
- MY_SQLITE_FINALIZE(qMAinSoundProperty)
-
- //and mainNotificationConfigurations
- std::string commandMainNotificationConfiguration = "SELECT type, status, parameter FROM SinkMainNotificationConfiguration" + i2s(temp.sinkID);
- MY_SQLITE_PREPARE_V2(mpDatabase, commandMainNotificationConfiguration.c_str(), -1, &qMainNotificationConfiguration, NULL)
- while ((eCode = sqlite3_step(qMainNotificationConfiguration)) == SQLITE_ROW)
- {
- tempMainNotificationConfiguration.type = static_cast <am_CustomNotificationType_t> (sqlite3_column_int(qMainNotificationConfiguration, 0));
- tempMainNotificationConfiguration.status = static_cast <am_NotificationStatus_e> (sqlite3_column_int(qMainNotificationConfiguration, 1));
- tempMainNotificationConfiguration.parameter = static_cast <uint16_t>(sqlite3_column_int(qMainNotificationConfiguration, 2));
- temp.listMainNotificationConfigurations.push_back(tempMainNotificationConfiguration);
- }
-
- MY_SQLITE_FINALIZE(qMainNotificationConfiguration)
- }
-
- listSinks.push_back(temp);
- temp.listConnectionFormats.clear();
- temp.listMainSoundProperties.clear();
- temp.listSoundProperties.clear();
- }
-
- if (eCode != SQLITE_DONE)
- {
- logError("DatabaseHandler::getListSinks SQLITE error code:", eCode);
- MY_SQLITE_FINALIZE(query)
- return (E_DATABASE_ERROR);
- }
-
- MY_SQLITE_FINALIZE(query)
-
- return (E_OK);
+ return enumerateSinks([&](const am_Sink_s & sink){ listSinks.push_back(sink);});
}
am_Error_e CAmDatabaseHandlerSQLite::getListSources(std::vector<am_Source_s> & listSources) const
{
listSources.clear();
- sqlite3_stmt* query = NULL, *qConnectionFormat = NULL, *qSoundProperty = NULL, *qMAinSoundProperty = NULL, *qNotification(NULL), *qMainNotification(NULL);
- int eCode = 0;
- am_Source_s temp;
- am_CustomConnectionFormat_t tempConnectionFormat;
- am_SoundProperty_s tempSoundProperty;
- am_MainSoundProperty_s tempMainSoundProperty;
- am_NotificationConfiguration_s tempNotificationConfiguration;
- std::string command = "SELECT name, domainID, sourceClassID, sourceState, volume, visible, availability, availabilityReason, interruptState, sourceID FROM " + std::string(SOURCE_TABLE) + " WHERE reserved=0";
- MY_SQLITE_PREPARE_V2(mpDatabase, command.c_str(), -1, &query, NULL)
-
- while ((eCode = sqlite3_step(query)) == SQLITE_ROW)
- {
- temp.name = std::string((const char*) sqlite3_column_text(query, 0));
- temp.domainID = sqlite3_column_int(query, 1);
- temp.sourceClassID = sqlite3_column_int(query, 2);
- temp.sourceState = (am_SourceState_e) sqlite3_column_int(query, 3);
- temp.volume = sqlite3_column_int(query, 4);
- temp.visible = sqlite3_column_int(query, 5);
- temp.available.availability = (am_Availability_e) sqlite3_column_int(query, 6);
- temp.available.availabilityReason = (am_CustomAvailabilityReason_t) sqlite3_column_int(query, 7);
- temp.interruptState = (am_InterruptState_e) sqlite3_column_int(query, 8);
- temp.sourceID = sqlite3_column_int(query, 9);
-
- //read out the connectionFormats
- std::string commandConnectionFormat = "SELECT soundFormat FROM SourceConnectionFormat" + i2s(temp.sourceID);
- MY_SQLITE_PREPARE_V2(mpDatabase, commandConnectionFormat.c_str(), -1, &qConnectionFormat, NULL)
- while ((eCode = sqlite3_step(qConnectionFormat)) == SQLITE_ROW)
- {
- tempConnectionFormat = (am_CustomConnectionFormat_t) sqlite3_column_int(qConnectionFormat, 0);
- temp.listConnectionFormats.push_back(tempConnectionFormat);
- }
-
- MY_SQLITE_FINALIZE(qConnectionFormat)
-
- //read out sound properties
- std::string commandSoundProperty = "SELECT soundPropertyType, value FROM SourceSoundProperty" + i2s(temp.sourceID);
- MY_SQLITE_PREPARE_V2(mpDatabase, commandSoundProperty.c_str(), -1, &qSoundProperty, NULL)
- while ((eCode = sqlite3_step(qSoundProperty)) == SQLITE_ROW)
- {
- tempSoundProperty.type = (am_CustomSoundPropertyType_t) sqlite3_column_int(qSoundProperty, 0);
- tempSoundProperty.value = sqlite3_column_int(qSoundProperty, 1);
- temp.listSoundProperties.push_back(tempSoundProperty);
- }
-
- MY_SQLITE_FINALIZE(qSoundProperty)
-
- std::string notificationCommand = "SELECT type, status, parameter FROM SourceNotificationConfiguration" + i2s(temp.sourceID);
- MY_SQLITE_PREPARE_V2(mpDatabase, notificationCommand.c_str(), -1, &qNotification, NULL)
-
- while ((eCode = sqlite3_step(qNotification)) == SQLITE_ROW)
- {
- tempNotificationConfiguration.type = static_cast<am_CustomNotificationType_t>(sqlite3_column_int(qNotification, 0));
- tempNotificationConfiguration.status = static_cast<am_NotificationStatus_e>(sqlite3_column_int(qNotification, 1));
- tempNotificationConfiguration.parameter= static_cast<int16_t>(sqlite3_column_int(qNotification, 2));
- temp.listNotificationConfigurations.push_back(tempNotificationConfiguration);
- }
- MY_SQLITE_FINALIZE(qNotification)
-
- //read out MainSoundProperties if source is visible
- if(temp.visible)
- {
- std::string commandMainSoundProperty = "SELECT soundPropertyType, value FROM SourceMainSoundProperty" + i2s(temp.sourceID);
- MY_SQLITE_PREPARE_V2(mpDatabase, commandMainSoundProperty.c_str(), -1, &qMAinSoundProperty, NULL)
- while ((eCode = sqlite3_step(qMAinSoundProperty)) == SQLITE_ROW)
- {
- tempMainSoundProperty.type = (am_CustomMainSoundPropertyType_t) sqlite3_column_int(qMAinSoundProperty, 0);
- tempMainSoundProperty.value = sqlite3_column_int(qMAinSoundProperty, 1);
- temp.listMainSoundProperties.push_back(tempMainSoundProperty);
- }
-
- MY_SQLITE_FINALIZE(qMAinSoundProperty)
-
- std::string mainNotificationCommand = "SELECT type, status, parameter FROM SourceMainNotificationConfiguration" + i2s(temp.sourceID);
- MY_SQLITE_PREPARE_V2(mpDatabase, mainNotificationCommand.c_str(), -1, &qMainNotification, NULL)
-
- while ((eCode = sqlite3_step(qMainNotification)) == SQLITE_ROW)
- {
- tempNotificationConfiguration.type = static_cast<am_CustomNotificationType_t>(sqlite3_column_int(qMainNotification, 0));
- tempNotificationConfiguration.status = static_cast<am_NotificationStatus_e>(sqlite3_column_int(qMainNotification, 1));
- tempNotificationConfiguration.parameter= static_cast<int16_t>(sqlite3_column_int(qMainNotification, 2));
- temp.listMainNotificationConfigurations.push_back(tempNotificationConfiguration);
- }
- MY_SQLITE_FINALIZE(qMainNotification)
- }
-
-
- listSources.push_back(temp);
- temp.listConnectionFormats.clear();
- temp.listMainSoundProperties.clear();
- temp.listSoundProperties.clear();
- }
-
- if (eCode != SQLITE_DONE)
- {
- logError("DatabaseHandler::getListSources SQLITE error code:", eCode);
- MY_SQLITE_FINALIZE(query)
- return (E_DATABASE_ERROR);
- }
-
- MY_SQLITE_FINALIZE(query)
-
- return (E_OK);
+ return enumerateSources([&](const am_Source_s & source){ listSources.push_back(source);});
}
am_Error_e CAmDatabaseHandlerSQLite::getListSourceClasses(std::vector<am_SourceClass_s> & listSourceClasses) const
@@ -2634,72 +2666,13 @@ am_Error_e CAmDatabaseHandlerSQLite::getListCrossfaders(std::vector<am_Crossfade
am_Error_e CAmDatabaseHandlerSQLite::getListGateways(std::vector<am_Gateway_s> & listGateways) const
{
listGateways.clear();
- sqlite3_stmt* query = NULL, *qSinkConnectionFormat = NULL, *qSourceConnectionFormat = NULL;
- int eCode = 0;
- am_Gateway_s temp;
- am_CustomConnectionFormat_t tempConnectionFormat;
-
- std::string command = "SELECT name, sinkID, sourceID, domainSinkID, domainSourceID, controlDomainID, gatewayID FROM " + std::string(GATEWAY_TABLE);
- MY_SQLITE_PREPARE_V2(mpDatabase, command.c_str(), -1, &query, NULL)
-
- while ((eCode = sqlite3_step(query)) == SQLITE_ROW)
- {
- temp.name = std::string((const char*) sqlite3_column_text(query, 0));
- temp.sinkID = sqlite3_column_int(query, 1);
- temp.sourceID = sqlite3_column_int(query, 2);
- temp.domainSinkID = sqlite3_column_int(query, 3);
- temp.domainSourceID = sqlite3_column_int(query, 4);
- temp.controlDomainID = sqlite3_column_int(query, 5);
- temp.gatewayID = sqlite3_column_int(query, 6);
-
- //convertionMatrix:
- ListConnectionFormat::const_iterator iter = mListConnectionFormat.begin();
- iter = mListConnectionFormat.find(temp.gatewayID);
- if (iter == mListConnectionFormat.end())
- {
- logError("DatabaseHandler::getListGateways database error with convertionFormat");
-
- return (E_DATABASE_ERROR);
- }
- temp.convertionMatrix = iter->second;
-
- //read out the connectionFormats
- std::string commandConnectionFormat = "SELECT soundFormat FROM GatewaySourceFormat" + i2s(temp.gatewayID);
- MY_SQLITE_PREPARE_V2(mpDatabase, commandConnectionFormat.c_str(), -1, &qSourceConnectionFormat, NULL)
- while ((eCode = sqlite3_step(qSourceConnectionFormat)) == SQLITE_ROW)
- {
- tempConnectionFormat = (am_CustomConnectionFormat_t) sqlite3_column_int(qSourceConnectionFormat, 0);
- temp.listSourceFormats.push_back(tempConnectionFormat);
- }
-
- MY_SQLITE_FINALIZE(qSourceConnectionFormat)
-
- //read out sound properties
- commandConnectionFormat = "SELECT soundFormat FROM GatewaySinkFormat" + i2s(temp.gatewayID);
- MY_SQLITE_PREPARE_V2(mpDatabase, commandConnectionFormat.c_str(), -1, &qSinkConnectionFormat, NULL)
- while ((eCode = sqlite3_step(qSinkConnectionFormat)) == SQLITE_ROW)
- {
- tempConnectionFormat = (am_CustomConnectionFormat_t) sqlite3_column_int(qSinkConnectionFormat, 0);
- temp.listSinkFormats.push_back(tempConnectionFormat);
- }
-
- MY_SQLITE_FINALIZE(qSinkConnectionFormat)
-
- listGateways.push_back(temp);
- temp.listSinkFormats.clear();
- temp.listSourceFormats.clear();
- }
-
- if (eCode != SQLITE_DONE)
- {
- logError("DatabaseHandler::getListGateways SQLITE error code:", eCode);
- MY_SQLITE_FINALIZE(query)
- return (E_DATABASE_ERROR);
- }
-
- MY_SQLITE_FINALIZE(query)
+ return enumerateGateways([&](const am_Gateway_s & gateway){ listGateways.push_back(gateway);});
+}
- return (E_OK);
+am_Error_e CAmDatabaseHandlerSQLite::getListConverters(std::vector<am_Converter_s> & listConverters) const
+{
+ listConverters.clear();
+ return enumerateConverters([&](const am_Converter_s & converter){ listConverters.push_back(converter);});
}
am_Error_e CAmDatabaseHandlerSQLite::getListSinkClasses(std::vector<am_SinkClass_s> & listSinkClasses) const
@@ -3001,6 +2974,21 @@ am_Error_e am::CAmDatabaseHandlerSQLite::getListGatewayConnectionFormats(const a
return (E_OK);
}
+am_Error_e am::CAmDatabaseHandlerSQLite::getListConverterConnectionFormats(const am_converterID_t converterID, std::vector<bool> & listConnectionFormat) const
+{
+ ListConnectionFormat::const_iterator iter = mListConnectionFormat.begin();
+ iter = mListConnectionFormat.find(converterID);
+ if (iter == mListConnectionFormat.end())
+ {
+ logError("DatabaseHandler::getListConverterConnectionFormats database error with convertionFormat");
+
+ return (E_DATABASE_ERROR);
+ }
+ listConnectionFormat = iter->second;
+
+ return (E_OK);
+}
+
am_Error_e CAmDatabaseHandlerSQLite::getTimingInformation(const am_mainConnectionID_t mainConnectionID, am_timeSync_t & delay) const
{
assert(mainConnectionID!=0);
@@ -3573,6 +3561,26 @@ bool CAmDatabaseHandlerSQLite::existGateway(const am_gatewayID_t gatewayID) cons
return (returnVal);
}
+bool CAmDatabaseHandlerSQLite::existConverter(const am_converterID_t converterID) const
+{
+ sqlite3_stmt* query = NULL;
+ std::string command = "SELECT converterID FROM " + std::string(CONVERTER_TABLE) + " WHERE converterID=" + i2s(converterID);
+ int eCode = 0;
+ bool returnVal = true;
+ MY_SQLITE_PREPARE_V2_BOOL(mpDatabase, command.c_str(), -1, &query, NULL)
+
+ if ((eCode = sqlite3_step(query)) == SQLITE_DONE)
+ returnVal = false;
+ else if (eCode != SQLITE_ROW)
+ {
+ returnVal = false;
+ logError("DatabaseHandler::existConverter database error!:", eCode);
+ }
+
+ MY_SQLITE_FINALIZE_BOOL(query)
+ return (returnVal);
+}
+
am_Error_e CAmDatabaseHandlerSQLite::getDomainOfSource(const am_sourceID_t sourceID, am_domainID_t & domainID) const
{
assert(sourceID!=0);
@@ -3928,7 +3936,7 @@ bool CAmDatabaseHandlerSQLite::existConnectionID(const am_connectionID_t connect
* @param crossfaderID the ID of the crossfader to be checked
* @return true if exists
*/
-bool CAmDatabaseHandlerSQLite::existcrossFader(const am_crossfaderID_t crossfaderID) const
+bool CAmDatabaseHandlerSQLite::existCrossFader(const am_crossfaderID_t crossfaderID) const
{
sqlite3_stmt* query = NULL;
std::string command = "SELECT crossfaderID FROM " + std::string(CROSSFADER_TABLE) + " WHERE crossfaderID=?";
@@ -4367,7 +4375,7 @@ am_Error_e CAmDatabaseHandlerSQLite::changeCrossFaderHotSink(const am_crossfader
int eCode = 0;
std::string command;
- if (!existcrossFader(crossfaderID))
+ if (!existCrossFader(crossfaderID))
{
return (E_NON_EXISTENT);
}
@@ -4385,63 +4393,53 @@ am_Error_e CAmDatabaseHandlerSQLite::changeCrossFaderHotSink(const am_crossfader
return (E_OK);
}
-am_Error_e CAmDatabaseHandlerSQLite::getRoutingTree(bool onlyfree, CAmRoutingTree& tree, std::vector<CAmRoutingTreeItem*>& flatTree)
+bool CAmDatabaseHandlerSQLite::isComponentConnected(const am_Gateway_s & gateway) const
{
- sqlite3_stmt* query = NULL;
- int eCode = 0;
- size_t i = 0;
- std::string command;
- am_domainID_t rootID = tree.returnRootDomainID();
- CAmRoutingTreeItem *parent = tree.returnRootItem();
-
- if (onlyfree)
- {
- command = "SELECT g.domainSourceID,g.gatewayID FROM " + std::string(GATEWAY_TABLE) + " g WHERE domainSinkID=? AND NOT EXISTS (SELECT NULL FROM " + std::string(CONNECTION_TABLE) + " c WHERE c.sinkID = g.sinkID OR c.sourceID = g.sourceID )";
- }
- else
- {
- command = "SELECT domainSourceID,gatewayID FROM " + std::string(GATEWAY_TABLE) + " WHERE domainSinkID=?";
- }
-
- do
- {
- if (i != 0)
- {
- parent = flatTree.at(i - 1);
- rootID = parent->returnDomainID();
- }
- MY_SQLITE_PREPARE_V2(mpDatabase, command.c_str(), -1, &query, NULL)
- MY_SQLITE_BIND_INT(query, 1, rootID)
-
- while ((eCode = sqlite3_step(query)) == SQLITE_ROW)
- {
- // additional check to avoid cyclic routes
- const am_domainID_t domainSourceID = sqlite3_column_int(query, 0);
- bool sourceDomainAlreadyHandledAsSink = false;
- for (std::vector<CAmRoutingTreeItem*>::const_iterator iFT = flatTree.begin(); iFT != flatTree.end(); ++iFT)
- {
- if (domainSourceID == (*iFT)->returnParent()->returnDomainID()) sourceDomainAlreadyHandledAsSink = true;
- }
-
- if (!sourceDomainAlreadyHandledAsSink)
- {
- // logInfo("DatabaseHandler::getRoutingTree ", rootID, ", ", domainSourceID, ", ", sqlite3_column_int(query, 1));
- flatTree.push_back(tree.insertItem(domainSourceID, sqlite3_column_int(query, 1), parent));
- }
- }
-
- if (eCode != SQLITE_DONE)
- {
- logError("DatabaseHandler::getRoutingTree SQLITE error code:", eCode);
- MY_SQLITE_FINALIZE(query)
- return (E_DATABASE_ERROR);
- }
-
- MY_SQLITE_FINALIZE(query)
- i++;
- } while (flatTree.size() > (i - 1));
+ sqlite3_stmt* query = NULL;
+ int eCode = 0;
+ std::string command;
+ bool returnVal = true;
+ command = "SELECT 1 FROM " + std::string(CONNECTION_TABLE) + " c WHERE c.sinkID = ? OR c.sourceID = ?";
+
+ MY_SQLITE_PREPARE_V2_BOOL(mpDatabase, command.c_str(), -1, &query, NULL)
+ MY_SQLITE_BIND_INT(query, 1, gateway.sinkID)
+ MY_SQLITE_BIND_INT(query, 2, gateway.sourceID)
+ if ((eCode = sqlite3_step(query)) == SQLITE_DONE)
+ {
+ returnVal = false;
+ }
+ else if (eCode != SQLITE_ROW)
+ {
+ returnVal = false;
+ logError("DatabaseHandler::isComponentConnected database error!:", eCode);
+ }
+ MY_SQLITE_FINALIZE(query)
+ return returnVal;
+}
- return (E_OK);
+bool CAmDatabaseHandlerSQLite::isComponentConnected(const am_Converter_s & converter) const
+{
+ sqlite3_stmt* query = NULL;
+ int eCode = 0;
+ std::string command;
+ bool returnVal = true;
+ command = "SELECT 1 FROM " + std::string(CONNECTION_TABLE) + " c WHERE c.sinkID = ? OR c.sourceID = ?";
+
+ MY_SQLITE_PREPARE_V2_BOOL(mpDatabase, command.c_str(), -1, &query, NULL)
+ MY_SQLITE_BIND_INT(query, 1, converter.sinkID)
+ MY_SQLITE_BIND_INT(query, 2, converter.sourceID)
+ if ((eCode = sqlite3_step(query)) == SQLITE_DONE)
+ {
+ returnVal = false;
+ }
+ else if (eCode != SQLITE_ROW)
+ {
+ returnVal = false;
+ logError("DatabaseHandler::isComponentConnected database error!:", eCode);
+ }
+ MY_SQLITE_FINALIZE(query)
+
+ return returnVal;
}
am_Error_e am::CAmDatabaseHandlerSQLite::peekSinkClassID(const std::string & name, am_sinkClass_t & sinkClassID)
@@ -4979,6 +4977,80 @@ am_Error_e CAmDatabaseHandlerSQLite::changeGatewayDB(const am_gatewayID_t gatewa
return (E_OK);
}
+am_Error_e CAmDatabaseHandlerSQLite::changeConverterDB(const am_converterID_t converterID, const std::vector<am_CustomConnectionFormat_t>& listSourceConnectionFormats, const std::vector<am_CustomConnectionFormat_t>& listSinkConnectionFormats, const std::vector<bool>& convertionMatrix)
+{
+ assert(converterID!=0);
+
+ sqlite3_stmt* query = NULL;
+ int eCode = 0;
+ std::string command;
+
+ if (!existConverter(converterID))
+ {
+ return (E_NON_EXISTENT);
+ }
+
+ if (!listSourceConnectionFormats.empty())
+ {
+ //clear Database
+ command = "DELETE from ConverterSourceFormat" + i2s(converterID);
+ if (!sqQuery(command))
+ return (E_DATABASE_ERROR);
+
+ //fill ConnectionFormats
+ command = "INSERT INTO ConverterSourceFormat" + i2s(converterID) + std::string("(soundFormat) VALUES (?)");
+ MY_SQLITE_PREPARE_V2(mpDatabase, command.c_str(), -1, &query, NULL)
+ std::vector<am_CustomConnectionFormat_t>::const_iterator connectionFormatIterator = listSourceConnectionFormats.begin();
+ for (; connectionFormatIterator < listSourceConnectionFormats.end(); ++connectionFormatIterator)
+ {
+ MY_SQLITE_BIND_INT(query, 1, *connectionFormatIterator)
+ if ((eCode = sqlite3_step(query)) != SQLITE_DONE)
+ {
+ logError("DatabaseHandler::enterConverterDB SQLITE Step error code:", eCode);
+ MY_SQLITE_FINALIZE(query)
+ return (E_DATABASE_ERROR);
+ }
+ MY_SQLITE_RESET(query)
+ }
+ MY_SQLITE_FINALIZE(query)
+ }
+
+ if (!listSinkConnectionFormats.empty())
+ {
+ //clear Database
+ command = "DELETE from ConverterSinkFormat" + i2s(converterID);
+ if (!sqQuery(command))
+ return (E_DATABASE_ERROR);
+
+ command = "INSERT INTO ConverterSinkFormat" + i2s(converterID) + std::string("(soundFormat) VALUES (?)");
+ MY_SQLITE_PREPARE_V2(mpDatabase, command.c_str(), -1, &query, NULL)
+ std::vector<am_CustomConnectionFormat_t>::const_iterator connectionFormatIterator = listSinkConnectionFormats.begin();
+ for (; connectionFormatIterator < listSinkConnectionFormats.end(); ++connectionFormatIterator)
+ {
+ MY_SQLITE_BIND_INT(query, 1, *connectionFormatIterator)
+ if ((eCode = sqlite3_step(query)) != SQLITE_DONE)
+ {
+ logError("DatabaseHandler::enterConverterDB SQLITE Step error code:", eCode);
+ MY_SQLITE_FINALIZE(query)
+ return (E_DATABASE_ERROR);
+ }
+ MY_SQLITE_RESET(query)
+ }
+ MY_SQLITE_FINALIZE(query)
+ }
+
+ if (!convertionMatrix.empty())
+ {
+ mListConnectionFormat.clear();
+ mListConnectionFormat.insert(std::make_pair(converterID, convertionMatrix));
+ }
+
+ logInfo("DatabaseHandler::changeConverterDB changed Gateway with ID", converterID);
+
+ //todo: check if observer needs to be adopted.
+ return (E_OK);
+}
+
am_Error_e CAmDatabaseHandlerSQLite::changeSinkNotificationConfigurationDB(const am_sinkID_t sinkID, const am_NotificationConfiguration_s notificationConfiguration)
{
assert(sinkID!=0);
@@ -5048,4 +5120,355 @@ void CAmDatabaseHandlerSQLite::createTables()
}
}
+am_Error_e CAmDatabaseHandlerSQLite::enumerateSources(std::function<void(const am_Source_s & element)> cb) const
+{
+ sqlite3_stmt* query = NULL, *qConnectionFormat = NULL, *qSoundProperty = NULL, *qMAinSoundProperty = NULL, *qNotification(NULL), *qMainNotification(NULL);
+ int eCode = 0;
+ am_Source_s temp;
+ am_CustomConnectionFormat_t tempConnectionFormat;
+ am_SoundProperty_s tempSoundProperty;
+ am_MainSoundProperty_s tempMainSoundProperty;
+ am_NotificationConfiguration_s tempNotificationConfiguration;
+ std::string command = "SELECT name, domainID, sourceClassID, sourceState, volume, visible, availability, availabilityReason, interruptState, sourceID FROM " + std::string(SOURCE_TABLE) + " WHERE reserved=0";
+ MY_SQLITE_PREPARE_V2(mpDatabase, command.c_str(), -1, &query, NULL)
+
+ while ((eCode = sqlite3_step(query)) == SQLITE_ROW)
+ {
+ temp.name = std::string((const char*) sqlite3_column_text(query, 0));
+ temp.domainID = sqlite3_column_int(query, 1);
+ temp.sourceClassID = sqlite3_column_int(query, 2);
+ temp.sourceState = (am_SourceState_e) sqlite3_column_int(query, 3);
+ temp.volume = sqlite3_column_int(query, 4);
+ temp.visible = sqlite3_column_int(query, 5);
+ temp.available.availability = (am_Availability_e) sqlite3_column_int(query, 6);
+ temp.available.availabilityReason = (am_CustomAvailabilityReason_t) sqlite3_column_int(query, 7);
+ temp.interruptState = (am_InterruptState_e) sqlite3_column_int(query, 8);
+ temp.sourceID = sqlite3_column_int(query, 9);
+
+ //read out the connectionFormats
+ std::string commandConnectionFormat = "SELECT soundFormat FROM SourceConnectionFormat" + i2s(temp.sourceID);
+ MY_SQLITE_PREPARE_V2(mpDatabase, commandConnectionFormat.c_str(), -1, &qConnectionFormat, NULL)
+ while ((eCode = sqlite3_step(qConnectionFormat)) == SQLITE_ROW)
+ {
+ tempConnectionFormat = (am_CustomConnectionFormat_t) sqlite3_column_int(qConnectionFormat, 0);
+ temp.listConnectionFormats.push_back(tempConnectionFormat);
+ }
+
+ MY_SQLITE_FINALIZE(qConnectionFormat)
+
+ //read out sound properties
+ std::string commandSoundProperty = "SELECT soundPropertyType, value FROM SourceSoundProperty" + i2s(temp.sourceID);
+ MY_SQLITE_PREPARE_V2(mpDatabase, commandSoundProperty.c_str(), -1, &qSoundProperty, NULL)
+ while ((eCode = sqlite3_step(qSoundProperty)) == SQLITE_ROW)
+ {
+ tempSoundProperty.type = (am_CustomSoundPropertyType_t) sqlite3_column_int(qSoundProperty, 0);
+ tempSoundProperty.value = sqlite3_column_int(qSoundProperty, 1);
+ temp.listSoundProperties.push_back(tempSoundProperty);
+ }
+
+ MY_SQLITE_FINALIZE(qSoundProperty)
+
+ std::string notificationCommand = "SELECT type, status, parameter FROM SourceNotificationConfiguration" + i2s(temp.sourceID);
+ MY_SQLITE_PREPARE_V2(mpDatabase, notificationCommand.c_str(), -1, &qNotification, NULL)
+
+ while ((eCode = sqlite3_step(qNotification)) == SQLITE_ROW)
+ {
+ tempNotificationConfiguration.type = static_cast<am_CustomNotificationType_t>(sqlite3_column_int(qNotification, 0));
+ tempNotificationConfiguration.status = static_cast<am_NotificationStatus_e>(sqlite3_column_int(qNotification, 1));
+ tempNotificationConfiguration.parameter= static_cast<int16_t>(sqlite3_column_int(qNotification, 2));
+ temp.listNotificationConfigurations.push_back(tempNotificationConfiguration);
+ }
+ MY_SQLITE_FINALIZE(qNotification)
+
+ //read out MainSoundProperties if source is visible
+ if(temp.visible)
+ {
+ std::string commandMainSoundProperty = "SELECT soundPropertyType, value FROM SourceMainSoundProperty" + i2s(temp.sourceID);
+ MY_SQLITE_PREPARE_V2(mpDatabase, commandMainSoundProperty.c_str(), -1, &qMAinSoundProperty, NULL)
+ while ((eCode = sqlite3_step(qMAinSoundProperty)) == SQLITE_ROW)
+ {
+ tempMainSoundProperty.type = (am_CustomMainSoundPropertyType_t) sqlite3_column_int(qMAinSoundProperty, 0);
+ tempMainSoundProperty.value = sqlite3_column_int(qMAinSoundProperty, 1);
+ temp.listMainSoundProperties.push_back(tempMainSoundProperty);
+ }
+
+ MY_SQLITE_FINALIZE(qMAinSoundProperty)
+
+ std::string mainNotificationCommand = "SELECT type, status, parameter FROM SourceMainNotificationConfiguration" + i2s(temp.sourceID);
+ MY_SQLITE_PREPARE_V2(mpDatabase, mainNotificationCommand.c_str(), -1, &qMainNotification, NULL)
+
+ while ((eCode = sqlite3_step(qMainNotification)) == SQLITE_ROW)
+ {
+ tempNotificationConfiguration.type = static_cast<am_CustomNotificationType_t>(sqlite3_column_int(qMainNotification, 0));
+ tempNotificationConfiguration.status = static_cast<am_NotificationStatus_e>(sqlite3_column_int(qMainNotification, 1));
+ tempNotificationConfiguration.parameter= static_cast<int16_t>(sqlite3_column_int(qMainNotification, 2));
+ temp.listMainNotificationConfigurations.push_back(tempNotificationConfiguration);
+ }
+ MY_SQLITE_FINALIZE(qMainNotification)
+ }
+
+
+ cb(temp);
+ temp.listConnectionFormats.clear();
+ temp.listMainSoundProperties.clear();
+ temp.listSoundProperties.clear();
+ }
+
+ if (eCode != SQLITE_DONE)
+ {
+ logError("DatabaseHandler::getListSources SQLITE error code:", eCode);
+ MY_SQLITE_FINALIZE(query)
+ return (E_DATABASE_ERROR);
+ }
+
+ MY_SQLITE_FINALIZE(query)
+
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerSQLite::enumerateSinks(std::function<void(const am_Sink_s & element)> cb) const
+{
+ sqlite3_stmt* query = NULL, *qConnectionFormat = NULL, *qSoundProperty = NULL, *qNotificationConfiguration= NULL, *qMAinSoundProperty = NULL, *qMainNotificationConfiguration= NULL;
+ int eCode = 0;
+ am_Sink_s temp;
+ am_CustomConnectionFormat_t tempConnectionFormat;
+ am_SoundProperty_s tempSoundProperty;
+ am_MainSoundProperty_s tempMainSoundProperty;
+ am_NotificationConfiguration_s tempNotificationConfiguration;
+ am_NotificationConfiguration_s tempMainNotificationConfiguration;
+ std::string command = "SELECT name, domainID, sinkClassID, volume, visible, availability, availabilityReason, muteState, mainVolume, sinkID FROM " + std::string(SINK_TABLE) + " WHERE reserved=0";
+ MY_SQLITE_PREPARE_V2(mpDatabase, command.c_str(), -1, &query, NULL)
+
+ while ((eCode = sqlite3_step(query)) == SQLITE_ROW)
+ {
+ temp.name = std::string((const char*) sqlite3_column_text(query, 0));
+ temp.domainID = sqlite3_column_int(query, 1);
+ temp.sinkClassID = sqlite3_column_int(query, 2);
+ temp.volume = sqlite3_column_int(query, 3);
+ temp.visible = sqlite3_column_int(query, 4);
+ temp.available.availability = (am_Availability_e) sqlite3_column_int(query, 5);
+ temp.available.availabilityReason = (am_CustomAvailabilityReason_t) sqlite3_column_int(query, 6);
+ temp.muteState = (am_MuteState_e) sqlite3_column_int(query, 7);
+ temp.mainVolume = sqlite3_column_int(query, 8);
+ temp.sinkID = sqlite3_column_int(query, 9);
+
+ //read out the connectionFormats
+ std::string commandConnectionFormat = "SELECT soundFormat FROM SinkConnectionFormat" + i2s(temp.sinkID);
+ MY_SQLITE_PREPARE_V2(mpDatabase, commandConnectionFormat.c_str(), -1, &qConnectionFormat, NULL)
+ while ((eCode = sqlite3_step(qConnectionFormat)) == SQLITE_ROW)
+ {
+ tempConnectionFormat = (am_CustomConnectionFormat_t) sqlite3_column_int(qConnectionFormat, 0);
+ temp.listConnectionFormats.push_back(tempConnectionFormat);
+ }
+
+ MY_SQLITE_FINALIZE(qConnectionFormat)
+
+ //read out sound properties
+ std::string commandSoundProperty = "SELECT soundPropertyType, value FROM SinkSoundProperty" + i2s(temp.sinkID);
+ MY_SQLITE_PREPARE_V2(mpDatabase, commandSoundProperty.c_str(), -1, &qSoundProperty, NULL)
+ while ((eCode = sqlite3_step(qSoundProperty)) == SQLITE_ROW)
+ {
+ tempSoundProperty.type = (am_CustomSoundPropertyType_t) sqlite3_column_int(qSoundProperty, 0);
+ tempSoundProperty.value = sqlite3_column_int(qSoundProperty, 1);
+ temp.listSoundProperties.push_back(tempSoundProperty);
+ }
+
+ MY_SQLITE_FINALIZE(qSoundProperty)
+
+ //read out notifications
+ std::string commandNotificationConfiguration = "SELECT type, status, parameter FROM SinkNotificationConfiguration" + i2s(temp.sinkID);
+ MY_SQLITE_PREPARE_V2(mpDatabase, commandNotificationConfiguration.c_str(), -1, &qNotificationConfiguration, NULL)
+ while ((eCode = sqlite3_step(qNotificationConfiguration)) == SQLITE_ROW)
+ {
+ tempNotificationConfiguration.type = static_cast<am_CustomNotificationType_t> (sqlite3_column_int(qNotificationConfiguration, 0));
+ tempNotificationConfiguration.status = static_cast<am_NotificationStatus_e> (sqlite3_column_int(qNotificationConfiguration, 1));
+ tempNotificationConfiguration.parameter = static_cast<int16_t> (sqlite3_column_int(qNotificationConfiguration, 2));
+ temp.listNotificationConfigurations.push_back(tempNotificationConfiguration);
+ }
+
+ MY_SQLITE_FINALIZE(qNotificationConfiguration)
+
+ //read out MainSoundProperties if sink is visible
+ if(temp.visible)
+ {
+ std::string commandMainSoundProperty = "SELECT soundPropertyType, value FROM SinkMainSoundProperty" + i2s(temp.sinkID);
+ MY_SQLITE_PREPARE_V2(mpDatabase, commandMainSoundProperty.c_str(), -1, &qMAinSoundProperty, NULL)
+ while ((eCode = sqlite3_step(qMAinSoundProperty)) == SQLITE_ROW)
+ {
+ tempMainSoundProperty.type = (am_CustomMainSoundPropertyType_t) sqlite3_column_int(qMAinSoundProperty, 0);
+ tempMainSoundProperty.value = sqlite3_column_int(qMAinSoundProperty, 1);
+ temp.listMainSoundProperties.push_back(tempMainSoundProperty);
+ }
+
+ MY_SQLITE_FINALIZE(qMAinSoundProperty)
+
+ //and mainNotificationConfigurations
+ std::string commandMainNotificationConfiguration = "SELECT type, status, parameter FROM SinkMainNotificationConfiguration" + i2s(temp.sinkID);
+ MY_SQLITE_PREPARE_V2(mpDatabase, commandMainNotificationConfiguration.c_str(), -1, &qMainNotificationConfiguration, NULL)
+ while ((eCode = sqlite3_step(qMainNotificationConfiguration)) == SQLITE_ROW)
+ {
+ tempMainNotificationConfiguration.type = static_cast <am_CustomNotificationType_t> (sqlite3_column_int(qMainNotificationConfiguration, 0));
+ tempMainNotificationConfiguration.status = static_cast <am_NotificationStatus_e> (sqlite3_column_int(qMainNotificationConfiguration, 1));
+ tempMainNotificationConfiguration.parameter = static_cast <uint16_t>(sqlite3_column_int(qMainNotificationConfiguration, 2));
+ temp.listMainNotificationConfigurations.push_back(tempMainNotificationConfiguration);
+ }
+
+ MY_SQLITE_FINALIZE(qMainNotificationConfiguration)
+ }
+
+ cb(temp);
+ temp.listConnectionFormats.clear();
+ temp.listMainSoundProperties.clear();
+ temp.listSoundProperties.clear();
+ }
+
+ if (eCode != SQLITE_DONE)
+ {
+ logError("DatabaseHandler::getListSinks SQLITE error code:", eCode);
+ MY_SQLITE_FINALIZE(query)
+ return (E_DATABASE_ERROR);
+ }
+
+ MY_SQLITE_FINALIZE(query)
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerSQLite::enumerateGateways(std::function<void(const am_Gateway_s & element)> cb) const
+{
+ sqlite3_stmt* query = NULL, *qSinkConnectionFormat = NULL, *qSourceConnectionFormat = NULL;
+ int eCode = 0;
+ am_Gateway_s temp;
+ am_CustomConnectionFormat_t tempConnectionFormat;
+
+ std::string command = "SELECT name, sinkID, sourceID, domainSinkID, domainSourceID, controlDomainID, gatewayID FROM " + std::string(GATEWAY_TABLE);
+ MY_SQLITE_PREPARE_V2(mpDatabase, command.c_str(), -1, &query, NULL)
+
+ while ((eCode = sqlite3_step(query)) == SQLITE_ROW)
+ {
+ temp.name = std::string((const char*) sqlite3_column_text(query, 0));
+ temp.sinkID = sqlite3_column_int(query, 1);
+ temp.sourceID = sqlite3_column_int(query, 2);
+ temp.domainSinkID = sqlite3_column_int(query, 3);
+ temp.domainSourceID = sqlite3_column_int(query, 4);
+ temp.controlDomainID = sqlite3_column_int(query, 5);
+ temp.gatewayID = sqlite3_column_int(query, 6);
+
+ //convertionMatrix:
+ ListConnectionFormat::const_iterator iter = mListConnectionFormat.begin();
+ iter = mListConnectionFormat.find(temp.gatewayID);
+ if (iter == mListConnectionFormat.end())
+ {
+ logError("DatabaseHandler::getListGateways database error with convertionFormat");
+
+ return (E_DATABASE_ERROR);
+ }
+ temp.convertionMatrix = iter->second;
+
+ //read out the connectionFormats
+ std::string commandConnectionFormat = "SELECT soundFormat FROM GatewaySourceFormat" + i2s(temp.gatewayID);
+ MY_SQLITE_PREPARE_V2(mpDatabase, commandConnectionFormat.c_str(), -1, &qSourceConnectionFormat, NULL)
+ while ((eCode = sqlite3_step(qSourceConnectionFormat)) == SQLITE_ROW)
+ {
+ tempConnectionFormat = (am_CustomConnectionFormat_t) sqlite3_column_int(qSourceConnectionFormat, 0);
+ temp.listSourceFormats.push_back(tempConnectionFormat);
+ }
+
+ MY_SQLITE_FINALIZE(qSourceConnectionFormat)
+
+ //read out sound properties
+ commandConnectionFormat = "SELECT soundFormat FROM GatewaySinkFormat" + i2s(temp.gatewayID);
+ MY_SQLITE_PREPARE_V2(mpDatabase, commandConnectionFormat.c_str(), -1, &qSinkConnectionFormat, NULL)
+ while ((eCode = sqlite3_step(qSinkConnectionFormat)) == SQLITE_ROW)
+ {
+ tempConnectionFormat = (am_CustomConnectionFormat_t) sqlite3_column_int(qSinkConnectionFormat, 0);
+ temp.listSinkFormats.push_back(tempConnectionFormat);
+ }
+
+ MY_SQLITE_FINALIZE(qSinkConnectionFormat)
+
+ cb(temp);
+ temp.listSinkFormats.clear();
+ temp.listSourceFormats.clear();
+ }
+
+ if (eCode != SQLITE_DONE)
+ {
+ logError("DatabaseHandler::getListGateways SQLITE error code:", eCode);
+ MY_SQLITE_FINALIZE(query)
+ return (E_DATABASE_ERROR);
+ }
+
+ MY_SQLITE_FINALIZE(query)
+
+ return (E_OK);
+}
+
+am_Error_e CAmDatabaseHandlerSQLite::enumerateConverters(std::function<void(const am_Converter_s & element)> cb) const
+{
+ sqlite3_stmt* query = NULL, *qSinkConnectionFormat = NULL, *qSourceConnectionFormat = NULL;
+ int eCode = 0;
+ am_Converter_s temp;
+ am_CustomConnectionFormat_t tempConnectionFormat;
+
+ std::string command = "SELECT name, sinkID, sourceID, domainID, converterID FROM " + std::string(CONVERTER_TABLE);
+ MY_SQLITE_PREPARE_V2(mpDatabase, command.c_str(), -1, &query, NULL)
+
+ while ((eCode = sqlite3_step(query)) == SQLITE_ROW)
+ {
+ temp.name = std::string((const char*) sqlite3_column_text(query, 0));
+ temp.sinkID = sqlite3_column_int(query, 1);
+ temp.sourceID = sqlite3_column_int(query, 2);
+ temp.domainID = sqlite3_column_int(query, 3);
+ temp.converterID = sqlite3_column_int(query, 4);
+
+ //convertionMatrix:
+ ListConnectionFormat::const_iterator iter = mListConnectionFormat.begin();
+ iter = mListConnectionFormat.find(temp.converterID);
+ if (iter == mListConnectionFormat.end())
+ {
+ logError("DatabaseHandler::getListConverters database error with convertionFormat");
+
+ return (E_DATABASE_ERROR);
+ }
+ temp.convertionMatrix = iter->second;
+
+ //read out the connectionFormats
+ std::string commandConnectionFormat = "SELECT soundFormat FROM ConverterSourceFormat" + i2s(temp.converterID);
+ MY_SQLITE_PREPARE_V2(mpDatabase, commandConnectionFormat.c_str(), -1, &qSourceConnectionFormat, NULL)
+ while ((eCode = sqlite3_step(qSourceConnectionFormat)) == SQLITE_ROW)
+ {
+ tempConnectionFormat = (am_CustomConnectionFormat_t) sqlite3_column_int(qSourceConnectionFormat, 0);
+ temp.listSourceFormats.push_back(tempConnectionFormat);
+ }
+
+ MY_SQLITE_FINALIZE(qSourceConnectionFormat)
+
+ //read out sound properties
+ commandConnectionFormat = "SELECT soundFormat FROM ConverterSinkFormat" + i2s(temp.converterID);
+ MY_SQLITE_PREPARE_V2(mpDatabase, commandConnectionFormat.c_str(), -1, &qSinkConnectionFormat, NULL)
+ while ((eCode = sqlite3_step(qSinkConnectionFormat)) == SQLITE_ROW)
+ {
+ tempConnectionFormat = (am_CustomConnectionFormat_t) sqlite3_column_int(qSinkConnectionFormat, 0);
+ temp.listSinkFormats.push_back(tempConnectionFormat);
+ }
+
+ MY_SQLITE_FINALIZE(qSinkConnectionFormat)
+
+ cb(temp);
+ temp.listSinkFormats.clear();
+ temp.listSourceFormats.clear();
+ }
+
+ if (eCode != SQLITE_DONE)
+ {
+ logError("DatabaseHandler::getListConverters SQLITE error code:", eCode);
+ MY_SQLITE_FINALIZE(query)
+ return (E_DATABASE_ERROR);
+ }
+
+ MY_SQLITE_FINALIZE(query)
+
+ return (E_OK);
+}
+
}
diff --git a/AudioManagerDaemon/src/CAmDatabaseObserver.cpp b/AudioManagerDaemon/src/CAmDatabaseObserver.cpp
index 506ec01..57a76cc 100644
--- a/AudioManagerDaemon/src/CAmDatabaseObserver.cpp
+++ b/AudioManagerDaemon/src/CAmDatabaseObserver.cpp
@@ -111,6 +111,12 @@ void CAmDatabaseObserver::newGateway(const am_Gateway_s& gateway)
//todo: implement something
}
+void CAmDatabaseObserver::newConverter(const am_Converter_s& coverter)
+{
+ (void) coverter;
+ //todo: implement something
+}
+
void CAmDatabaseObserver::newCrossfader(const am_Crossfader_s& crossfader)
{
mRoutingSender->addCrossfaderLookup(crossfader);
@@ -143,6 +149,12 @@ void CAmDatabaseObserver::removeGateway(const am_gatewayID_t gatewayID)
//todo: implement something?
}
+void CAmDatabaseObserver::removeConverter(const am_converterID_t converterID)
+{
+ (void) converterID;
+ //todo: implement something?
+}
+
void CAmDatabaseObserver::removeCrossfader(const am_crossfaderID_t crossfaderID)
{
mRoutingSender->removeCrossfaderLookup(crossfaderID);
diff --git a/AudioManagerDaemon/src/CAmRouter.cpp b/AudioManagerDaemon/src/CAmRouter.cpp
index d574e45..6ab0a07 100644
--- a/AudioManagerDaemon/src/CAmRouter.cpp
+++ b/AudioManagerDaemon/src/CAmRouter.cpp
@@ -13,30 +13,83 @@
*
*
* \author Christian Mueller, christian.ei.mueller@bmw.de BMW 2011,2012
+ * \author Aleksandar Donchev, Aleksander.Donchev@partner.bmw.de BMW 2013,2014
*
* \file CAmRouter.cpp
* For further information see http://www.genivi.org/.
*
*/
-#include "CAmRouter.h"
#include <cassert>
#include <algorithm>
#include <vector>
#include <iterator>
+#include "CAmRouter.h"
#include "IAmDatabaseHandler.h"
#include "CAmControlSender.h"
+#include "shared/CAmDltWrapper.h"
+
+
namespace am {
+
+void getSourceSinkPossibleConnectionFormats(std::vector<CAmNode<am_RoutingNodeData_s>*>::iterator iteratorSource,
+ std::vector<CAmNode<am_RoutingNodeData_s>*>::iterator iteratorSink,
+ std::vector<am_CustomConnectionFormat_t> & outConnectionFormats)
+{
+ CAmNode<am_RoutingNodeData_s> * nodeSink = *iteratorSink;
+ assert(nodeSink->getData().type==am_RoutingNodeData_s::am_NodeDataType_e::SINK);
+
+ CAmNode<am_RoutingNodeData_s> * nodeSource = *iteratorSource;
+ assert(nodeSource->getData().type==am_RoutingNodeData_s::am_NodeDataType_e::SOURCE);
+
+ am_Source_s *source = nodeSource->getData().data.source;
+ am_Sink_s *sink = nodeSink->getData().data.sink;
+ CAmRouter::listPossibleConnectionFormats(source->listConnectionFormats, sink->listConnectionFormats, outConnectionFormats);
+}
+
+template <class X> void getMergeConnectionFormats(const X * element,
+ const am_CustomConnectionFormat_t connectionFormat,
+ const std::vector<am_CustomConnectionFormat_t> & listConnectionFormats,
+ std::vector<am_CustomConnectionFormat_t> & outListMergeConnectionFormats)
+{
+ std::vector<am_CustomConnectionFormat_t> listRestrictedConnectionFormats;
+ CAmRouter::getRestrictedOutputFormats(element->convertionMatrix,
+ element->listSourceFormats,
+ element->listSinkFormats,
+ connectionFormat,
+ listRestrictedConnectionFormats);
+ std::sort(listRestrictedConnectionFormats.begin(), listRestrictedConnectionFormats.end()); //todo: this might be not needed if we use strictly sorted input
+ std::insert_iterator<std::vector<am_CustomConnectionFormat_t> > inserter(outListMergeConnectionFormats, outListMergeConnectionFormats.begin());
+ set_intersection(listConnectionFormats.begin(), listConnectionFormats.end(), listRestrictedConnectionFormats.begin(), listRestrictedConnectionFormats.end(), inserter);
+}
+
+
CAmRouter::CAmRouter(IAmDatabaseHandler* iDatabaseHandler, CAmControlSender* iSender) :
mpDatabaseHandler(iDatabaseHandler), //
- mpControlSender(iSender)
+ mpControlSender(iSender),
+ mOnlyFreeConversionNodes(false),
+ mRoutingGraph(),
+ mNodeListSources(),
+ mNodeListSinks(),
+ mNodeListGateways(),
+ mNodeListConverters(),
+ mNodeListSourceStatus(),
+ mNodeListSinkStatus(),
+ mNodeListConverterStatus(),
+ mNodeListGatewayStatus(),
+ mpRootSource(0),
+ mpRootSink(0)
{
assert(mpDatabaseHandler);
assert(mpControlSender);
}
+CAmRouter::~CAmRouter()
+{
+}
+
/**
* returns the best route between a source and a sink
* @param onlyfree if true only free gateways are used
@@ -48,213 +101,67 @@ CAmRouter::CAmRouter(IAmDatabaseHandler* iDatabaseHandler, CAmControlSender* iSe
am_Error_e CAmRouter::getRoute(const bool onlyfree, const am_sourceID_t sourceID, const am_sinkID_t sinkID, std::vector<am_Route_s> & returnList)
{
returnList.clear();
- //first find out in which domains the source and sink are
- am_domainID_t sourceDomainID;
- am_domainID_t sinkDomainID;
- if (mpDatabaseHandler->getDomainOfSource(sourceID, sourceDomainID) != E_OK)
- return (E_NON_EXISTENT);
- if (mpDatabaseHandler->getDomainOfSink(sinkID, sinkDomainID) != E_OK)
- return (E_NON_EXISTENT);
-
- if (sourceDomainID == sinkDomainID) //shortcut if the domains are the same...
- {
- //first get the list of possible connection formats
- std::vector<am_CustomConnectionFormat_t> listFormats, listPriorityConnectionFormats;
- listPossibleConnectionFormats(sourceID, sinkID, listFormats);
-
- //dummy route
- am_Route_s route;
- route.sinkID = sinkID;
- route.sourceID = sourceID;
- route.route.clear();
-
- //get the prio of the Controller:
- mpControlSender->getConnectionFormatChoice(sourceID, sinkID, route, listFormats, listPriorityConnectionFormats);
-
- //no possible connection, so no route ! But we report OK since there is no fault ...
- if (listPriorityConnectionFormats.empty())
- return (E_OK);
-
- //return the first item as route:
- am_RoutingElement_s routingElement;
- routingElement.sourceID = sourceID;
- routingElement.sinkID = sinkID;
- routingElement.connectionFormat = listPriorityConnectionFormats[0];
- routingElement.domainID = sourceDomainID;
-
- //Now get a route:
- am_Route_s actualRoute;
- actualRoute.route.push_back(routingElement);
- actualRoute.sourceID = sourceID;
- actualRoute.sinkID = sinkID;
-
- //push it to the return list - we are done here ...
- returnList.push_back(actualRoute);
- return (E_OK);
-
- }
- CAmRoutingTree routingtree(sourceDomainID); //Build up a Tree from the Source_Domain to every other domain.
- std::vector<CAmRoutingTreeItem*> flattree; //This list is the flat tree
- std::vector<CAmRoutingTreeItem*> matchtree;
- std::vector<am_gatewayID_t> listGatewayID; //holds all gateway ids of the route
- am_RoutingElement_s routingElement;
- am_Route_s actualRoute; //holds the actual Route
- am_sourceID_t lastSource = 0;
-
- mpDatabaseHandler->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<CAmRoutingTreeItem*>::iterator iterator = flattree.begin();
- for (; iterator != flattree.end(); ++iterator)
- {
- if ((*iterator)->returnDomainID() == sinkDomainID)
- {
- matchtree.push_back(*iterator);
- }
- }
-
- //No we need to trace back the routes for each entry in matchtree
- iterator = matchtree.begin();
- for (; iterator != matchtree.end(); ++iterator)
- {
- std::vector<am_RoutingElement_s> actualRoutingElement; //intermediate list of current routing pairs
- //getting the route for the actual item
- 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();
- for (; gatewayIterator != listGatewayID.end(); ++gatewayIterator)
- {
- am_Gateway_s gatewayData;
- if (mpDatabaseHandler->getGatewayInfoDB(*gatewayIterator, 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(sinkID, sourceID, actualRoutingElement, routingInterator, gatewayIterator) != 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);
+ am_Source_s source;
+ am_Sink_s sink;
+ mpDatabaseHandler->getSourceInfoDB(sourceID, source);
+ mpDatabaseHandler->getSinkInfoDB(sinkID, sink);
+ return getRoute(onlyfree, source, sink, returnList);
}
-void CAmRouter::listPossibleConnectionFormats(const am_sourceID_t sourceID, const am_sinkID_t sinkID, std::vector<am_CustomConnectionFormat_t>& listFormats) const
+bool CAmRouter::getAllowedFormatsFromConvMatrix( const std::vector<bool> & convertionMatrix,
+ const std::vector<am_CustomConnectionFormat_t> & listSourceFormats,
+ const std::vector<am_CustomConnectionFormat_t> & listSinkFormats,
+ std::vector<am_CustomConnectionFormat_t> & sourceFormats,
+ std::vector<am_CustomConnectionFormat_t> & sinkFormats)
{
- std::vector<am_CustomConnectionFormat_t> listSourceFormats;
- std::vector<am_CustomConnectionFormat_t> listSinkFormats;
- mpDatabaseHandler->getListSinkConnectionFormats(sinkID, listSinkFormats);
- mpDatabaseHandler->getListSourceConnectionFormats(sourceID, listSourceFormats);
- std::sort(listSinkFormats.begin(), listSinkFormats.end()); //todo: this might be not needed if we use strictly sorted input
- std::sort(listSourceFormats.begin(), listSourceFormats.end()); //todo: this might be not needed if we use strictly sorted input
- std::insert_iterator<std::vector<am_CustomConnectionFormat_t> > inserter(listFormats, listFormats.begin());
- set_intersection(listSourceFormats.begin(), listSourceFormats.end(), listSinkFormats.begin(), listSinkFormats.end(), inserter);
+ const size_t sizeSourceFormats = listSourceFormats.size();
+ const size_t sizeSinkFormats = listSinkFormats.size();
+ const size_t sizeConvertionMatrix = convertionMatrix.size();
+
+ if(sizeSourceFormats==0||sizeSinkFormats==0||sizeConvertionMatrix==0||sizeConvertionMatrix!=sizeSinkFormats*sizeSourceFormats)
+ {
+ return false;
+ }
+
+ std::vector<bool>::const_iterator iterator = convertionMatrix.begin();
+ for (; iterator != convertionMatrix.end(); ++iterator)
+ {
+ if( true == *iterator )
+ {
+ const size_t index = iterator-convertionMatrix.begin();
+ size_t idx = index%sizeSourceFormats;
+ sourceFormats.push_back(listSourceFormats.at(idx));
+ idx = index/sizeSourceFormats;
+ sinkFormats.push_back(listSinkFormats.at(idx));
+ }
+ }
+ return sourceFormats.size()>0;
}
-am_Error_e CAmRouter::findBestWay(am_sinkID_t sinkID, am_sourceID_t sourceID, std::vector<am_RoutingElement_s> & listRoute, std::vector<am_RoutingElement_s>::iterator routeIterator, std::vector<am_gatewayID_t>::iterator gatewayIterator)
+void CAmRouter::listPossibleConnectionFormats(std::vector<am_CustomConnectionFormat_t> & inListSourceFormats,
+ std::vector<am_CustomConnectionFormat_t> & inListSinkFormats,
+ std::vector<am_CustomConnectionFormat_t> & outListFormats)
{
- am_Error_e returnError = E_NOT_POSSIBLE;
- std::vector<am_CustomConnectionFormat_t> listConnectionFormats;
- std::vector<am_CustomConnectionFormat_t> listMergeConnectionFormats;
- std::vector<am_CustomConnectionFormat_t> listPriorityConnectionFormats;
- std::vector<am_RoutingElement_s>::iterator nextIterator = routeIterator + 1;
- //get best connection format
- listPossibleConnectionFormats(routeIterator->sourceID, routeIterator->sinkID, listConnectionFormats);
-
- //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_CustomConnectionFormat_t> listRestrictedConnectionFormats;
- std::insert_iterator<std::vector<am_CustomConnectionFormat_t> > inserter(listMergeConnectionFormats, listMergeConnectionFormats.begin());
- std::vector<am_RoutingElement_s>::iterator tempIterator(routeIterator);
- tempIterator--;
- listRestrictedOutputFormatsGateways(*gatewayIterator, (tempIterator)->connectionFormat, listRestrictedConnectionFormats);
- std::sort(listRestrictedConnectionFormats.begin(), listRestrictedConnectionFormats.end()); //todo: this might be not needed if we use strictly sorted input
- set_intersection(listConnectionFormats.begin(), listConnectionFormats.end(), listRestrictedConnectionFormats.begin(), listRestrictedConnectionFormats.end(), inserter);
- gatewayIterator++;
- }
- else
- {
- listMergeConnectionFormats = listConnectionFormats;
- }
-
- am_Route_s route;
- route.sinkID = sinkID;
- route.sourceID = sourceID;
- route.route = listRoute;
-
- //let the controller decide:
- mpControlSender->getConnectionFormatChoice(routeIterator->sourceID, routeIterator->sinkID, route, listMergeConnectionFormats, listPriorityConnectionFormats);
-
- //we have the list sorted after prios - now we try one after the other with the next part of the route
- std::vector<am_CustomConnectionFormat_t>::iterator connectionFormatIterator = listPriorityConnectionFormats.begin();
-
- //here we need to check if we are at the end and stop
- if (nextIterator == listRoute.end())
- {
- if (!listPriorityConnectionFormats.empty())
- {
- routeIterator->connectionFormat = listPriorityConnectionFormats.front();
- return (E_OK);
- }
- else
- return (E_NOT_POSSIBLE);
- }
-
- for (; connectionFormatIterator != listPriorityConnectionFormats.end(); ++connectionFormatIterator)
- {
- routeIterator->connectionFormat = *connectionFormatIterator;
- if ((returnError = findBestWay(sinkID, sourceID, listRoute, nextIterator, gatewayIterator)) == E_OK)
- {
- break;
- }
- }
-
- return (returnError);
+ std::sort(inListSourceFormats.begin(), inListSourceFormats.end());
+ std::sort(inListSinkFormats.begin(), inListSinkFormats.end());
+ std::insert_iterator<std::vector<am_CustomConnectionFormat_t> > inserter(outListFormats, outListFormats.begin());
+ set_intersection(inListSourceFormats.begin(), inListSourceFormats.end(), inListSinkFormats.begin(), inListSinkFormats.end(), inserter);
}
-void CAmRouter::listRestrictedOutputFormatsGateways(const am_gatewayID_t gatewayID, const am_CustomConnectionFormat_t sinkConnectionFormat, std::vector<am_CustomConnectionFormat_t> & listFormats) const
+
+bool CAmRouter::getRestrictedOutputFormats(const std::vector<bool> & convertionMatrix,
+ const std::vector<am_CustomConnectionFormat_t> & listSourceFormats,
+ const std::vector<am_CustomConnectionFormat_t> & listSinkFormats,
+ const am_CustomConnectionFormat_t connectionFormat,
+ std::vector<am_CustomConnectionFormat_t> & listFormats)
{
listFormats.clear();
- am_Gateway_s gatewayData;
- mpDatabaseHandler->getGatewayInfoDB(gatewayID, gatewayData);
- std::vector<am_CustomConnectionFormat_t>::const_iterator rowSinkIterator = gatewayData.listSinkFormats.begin();
- std::vector<bool>::const_iterator matrixIterator = gatewayData.convertionMatrix.begin();
+ std::vector<am_CustomConnectionFormat_t>::const_iterator rowSinkIterator = listSinkFormats.begin();
+ std::vector<bool>::const_iterator matrixIterator = convertionMatrix.begin();
//find the row number of the sink
- rowSinkIterator = find(gatewayData.listSinkFormats.begin(), gatewayData.listSinkFormats.end(), sinkConnectionFormat);
- int rowNumberSink = rowSinkIterator - gatewayData.listSinkFormats.begin();
+ rowSinkIterator = find(listSinkFormats.begin(), listSinkFormats.end(), connectionFormat);
+ int rowNumberSink = rowSinkIterator - listSinkFormats.begin();
//go through the convertionMatrix and find out if the conversion is possible, if yes, add connectionFormat ...
std::advance(matrixIterator, rowNumberSink);
@@ -264,96 +171,817 @@ void CAmRouter::listRestrictedOutputFormatsGateways(const am_gatewayID_t gateway
{
if (*matrixIterator)
{
- listFormats.push_back(gatewayData.listSourceFormats.at((matrixIterator - gatewayData.convertionMatrix.begin()) / gatewayData.listSinkFormats.size()));
+ listFormats.push_back(listSourceFormats.at((matrixIterator - convertionMatrix.begin()) / listSinkFormats.size()));
}
- std::advance(matrixIterator, gatewayData.listSinkFormats.size());
- } while (gatewayData.convertionMatrix.end() - matrixIterator > 0);
+ std::advance(matrixIterator, listSinkFormats.size());
+ } while (convertionMatrix.end() - matrixIterator > 0);
+
+ return listFormats.size();
}
-CAmRouter::~CAmRouter()
+#ifdef EXTENDED_ROUTING_GRAPH
+void appendNodes(CAmGraph<am_RoutingNodeData_s, uint16_t> & routingGraph,
+ const std::vector<am_CustomConnectionFormat_t> & listConnectionFormats,
+ am_RoutingNodeData_s & nodeData,
+ std::vector<CAmNode<am_RoutingNodeData_s>*> & nodeList)
{
+ std::for_each(listConnectionFormats.begin(), listConnectionFormats.end(), [&](const am_CustomConnectionFormat_t cf){
+ nodeData.inConnectionFormat = cf;
+ nodeList.push_back(&routingGraph.addNode(nodeData));
+ });
}
-CAmRoutingTreeItem::CAmRoutingTreeItem(const am_domainID_t domainID, const am_gatewayID_t gatewayID, CAmRoutingTreeItem *parent) :
- mDomainID(domainID), //
- mGatewayID(gatewayID), //
- mpParentItem(parent)
+void appendNodes(CAmGraph<am_RoutingNodeData_s, uint16_t> & routingGraph,
+ const std::vector<am_CustomConnectionFormat_t> & sourceConnectionFormats,
+ const std::vector<am_CustomConnectionFormat_t> & sinkConnectionFormats,
+ const std::vector<bool> & convertionMatrix,
+ am_RoutingNodeData_s & nodeData,
+ std::vector<CAmNode<am_RoutingNodeData_s>*> & nodeList)
{
- assert(mDomainID!=0);
+
+ std::vector<am_CustomConnectionFormat_t> sourceFormats, sinkFormats;
+ if(CAmRouter::getAllowedFormatsFromConvMatrix(convertionMatrix, sourceConnectionFormats, sinkConnectionFormats, sourceFormats, sinkFormats))
+ {
+ for(size_t i = 0; i < sourceFormats.size(); i++)
+ {
+ nodeData.inConnectionFormat = sinkFormats[i];
+ nodeData.outConnectionFormat = sourceFormats[i];
+ nodeList.push_back(&routingGraph.addNode(nodeData));
+ }
+ }
}
+#endif
-void CAmRoutingTreeItem::appendChild(CAmRoutingTreeItem *newChild)
+am_Error_e CAmRouter::getRoute(const bool onlyfree, const am_Source_s & aSource, const am_Sink_s & aSink, std::vector<am_Route_s> & listRoutes)
{
- assert(newChild);
- mListChildItems.push_back(newChild);
+ clear();
+ mOnlyFreeConversionNodes = onlyfree;
+
+ // We need to copy the sinks, sources, converters, gateways, because we don't know what store is being used (SQLite or Map).
+ //todo: Don't make copy for map storage.
+ std::deque<am_Source_s> listSources;
+ std::deque<am_Sink_s> listSinks;
+ std::deque<am_Gateway_s> listGateways;
+ std::deque<am_Converter_s> listConverters;
+
+ am_Error_e error = E_OK;
+
+ am_RoutingNodeData_s nodeDataSrc;
+ nodeDataSrc.type = NodeDataType::SOURCE;
+ mpDatabaseHandler->enumerateSources([&](const am_Source_s & obj){
+ listSources.push_back(obj);
+ nodeDataSrc.data.source = &listSources.back();
+ mNodeListSourceStatus[obj.sourceID]=false;
+#ifdef EXTENDED_ROUTING_GRAPH
+ appendNodes(mRoutingGraph, obj.listConnectionFormats, nodeDataSrc, mNodeListSources);
+#else
+ mNodeListSources.push_back(&mRoutingGraph.addNode(nodeDataSrc));
+#endif
+ });
+ am_RoutingNodeData_s nodeDataSink;
+ nodeDataSink.type = NodeDataType::SINK;
+ mpDatabaseHandler->enumerateSinks([&](const am_Sink_s & obj){
+ listSinks.push_back(obj);
+ nodeDataSink.data.sink = &listSinks.back();
+ mNodeListSinkStatus[obj.sinkID]=false;
+#ifdef EXTENDED_ROUTING_GRAPH
+ appendNodes(mRoutingGraph, obj.listConnectionFormats, nodeDataSink, mNodeListSinks);
+#else
+ mNodeListSinks.push_back(&mRoutingGraph.addNode(nodeDataSink));
+#endif
+ });
+ am_RoutingNodeData_s nodeDataGateway;
+ nodeDataGateway.type = NodeDataType::GATEWAY;
+ mpDatabaseHandler->enumerateGateways([&](const am_Gateway_s & obj){
+ listGateways.push_back(obj);
+ nodeDataGateway.data.gateway = &listGateways.back();
+ mNodeListGatewayStatus[obj.gatewayID]=false;
+#ifdef EXTENDED_ROUTING_GRAPH
+ appendNodes(mRoutingGraph, obj.listSourceFormats, obj.listSinkFormats, obj.convertionMatrix, nodeDataGateway, mNodeListGateways);
+#else
+ mNodeListGateways.push_back(&mRoutingGraph.addNode(nodeDataGateway));
+#endif
+ });
+ am_RoutingNodeData_s nodeDataConverter;
+ nodeDataConverter.type = NodeDataType::CONVERTER;
+ mpDatabaseHandler->enumerateConverters([&](const am_Converter_s & obj){
+ listConverters.push_back(obj);
+ nodeDataConverter.data.converter = &listConverters.back();
+ mNodeListConverterStatus[obj.converterID]=false;
+#ifdef EXTENDED_ROUTING_GRAPH
+ appendNodes(mRoutingGraph, obj.listSourceFormats, obj.listSinkFormats, obj.convertionMatrix, nodeDataConverter, mNodeListConverters);
+#else
+ mNodeListConverters.push_back(&mRoutingGraph.addNode(nodeDataConverter));
+#endif
+ });
+
+ buildGraph(aSource, aSink);
+
+#ifdef EXTENDED_ROUTING_GRAPH
+ std::vector<std::vector<CAmNode<am_RoutingNodeData_s>*>> pathNodes;
+ getShortestPath(listRoutes, pathNodes);
+#else
+ std::vector<std::vector<CAmNode<am_RoutingNodeData_s>*>> pathNodes;
+ error = getAllPaths(listRoutes, pathNodes);
+#endif
+ return error;
}
-void CAmRoutingTreeItem::returnChildItems(std::vector<CAmRoutingTreeItem*> listChildItems)
+void CAmRouter::buildGraph( const am_Source_s & aSource, const am_Sink_s & aSink)
{
- listChildItems = mListChildItems;
+ //build up a topological sorted graph
+#ifdef EXTENDED_ROUTING_GRAPH
+ mpRootSource = (am_Source_s*)&aSource;
+ mpRootSink = (am_Sink_s*)&aSink;
+ for(auto it1=aSource.listConnectionFormats.begin(); it1!=aSource.listConnectionFormats.end(); it1++)
+ {
+ am::CAmNode<am::am_RoutingNodeData_s>* pRootNodeSource = sourceNodeWithID(aSource.sourceID, *it1);
+ for(auto it2=aSink.listConnectionFormats.begin(); it2!=aSink.listConnectionFormats.end(); it2++)
+ {
+ am::CAmNode<am::am_RoutingNodeData_s>* pRootNodeSink = sinkNodeWithID(aSink.sinkID, *it2);
+ if(pRootNodeSource && pRootNodeSink)
+ {
+ if(aSource.domainID==aSink.domainID)
+ routeInSameDomain(*pRootNodeSource, *pRootNodeSink);
+ else
+ routeInAnotherDomain(*pRootNodeSource, *pRootNodeSink);
+ }
+ }
+ }
+#else
+ mpRootSource = sourceNodeWithID(aSource.sourceID);
+ mpRootSink = sinkNodeWithID(aSink.sinkID);
+
+ assert(mpRootSource);
+ assert(mpRootSink);
+
+ if(aSource.domainID==aSink.domainID)
+ {
+ routeInSameDomain(*mpRootSource, *mpRootSink);
+ }
+ else
+ {
+ routeInAnotherDomain(*mpRootSource, *mpRootSink);
+ }
+#endif
+#ifdef TRACE_GRAPH
+ mRoutingGraph.trace([&](const CAmNode<am_RoutingNodeData_s> & node, const std::vector<CAmVertex<am_RoutingNodeData_s,uint16_t>*> & list) {
+ std::cout << "Node " << node.getIndex() << " :";
+ ((CAmNode<am_RoutingNodeData_s> &)node).getData().trace();
+ std::cout << "-->";
+ std::for_each(list.begin(), list.end(), [&](const CAmVertex<am_RoutingNodeData_s,uint16_t>* refVertex){
+ am::CAmNode<am::am_RoutingNodeData_s>* data = refVertex->getNode();
+ std::cout << "Node " << data->getIndex() << " :";
+ data->getData().trace();
+ });
+ std::cout << std::endl;
+ });
+#endif
}
+#ifdef EXTENDED_ROUTING_GRAPH
-am_domainID_t CAmRoutingTreeItem::returnDomainID() const
+CAmNode<am_RoutingNodeData_s>* CAmRouter::sinkNodeWithID(const am_sinkID_t sinkID, const am_CustomConnectionFormat_t connectionFormat)
{
- return (mDomainID);
+ auto iter = std::find_if(mNodeListSinks.begin(), mNodeListSinks.end(), [sinkID, connectionFormat](CAmNode<am_RoutingNodeData_s>* node){
+ return node->getData().data.sink->sinkID==sinkID && node->getData().inConnectionFormat==connectionFormat;
+ });
+ if(iter!=mNodeListSinks.end())
+ return *iter;
+ return NULL;
}
-am_gatewayID_t CAmRoutingTreeItem::returnGatewayID() const
+CAmNode<am_RoutingNodeData_s>* CAmRouter::sourceNodeWithID(const am_sourceID_t sourceID, const am_CustomConnectionFormat_t connectionFormat)
+{
+ auto iter = std::find_if(mNodeListSources.begin(), mNodeListSources.end(), [sourceID, connectionFormat](CAmNode<am_RoutingNodeData_s>* node){
+ return node->getData().data.source->sourceID==sourceID && node->getData().inConnectionFormat==connectionFormat;
+ });
+ if(iter!=mNodeListSources.end())
+ return *iter;
+ return NULL;
+}
+#else
+CAmNode<am_RoutingNodeData_s>* CAmRouter::sinkNodeWithID(const am_sinkID_t sinkID)
{
- return (mGatewayID);
+ auto iter = std::find_if(mNodeListSinks.begin(), mNodeListSinks.end(), [sinkID](CAmNode<am_RoutingNodeData_s>* node){
+ return node->getData().data.sink->sinkID==sinkID;
+ });
+ if(iter!=mNodeListSinks.end())
+ return *iter;
+ return NULL;
}
-CAmRoutingTreeItem* CAmRoutingTreeItem::returnParent() const
+CAmNode<am_RoutingNodeData_s>* CAmRouter::sourceNodeWithID(const am_sourceID_t sourceID)
{
- return (mpParentItem);
+ auto iter = std::find_if(mNodeListSources.begin(), mNodeListSources.end(), [sourceID](CAmNode<am_RoutingNodeData_s>* node){
+ return node->getData().data.source->sourceID==sourceID;
+ });
+ if(iter!=mNodeListSources.end())
+ return *iter;
+ return NULL;
}
+#endif
-CAmRoutingTreeItem::~CAmRoutingTreeItem()
+void CAmRouter::connectNodes(const CAmNode<am_RoutingNodeData_s> & node1,
+ const CAmNode<am_RoutingNodeData_s> & node2,
+ const am_CustomConnectionFormat_t vertexData,
+ const int16_t weight)
{
+ if( !mRoutingGraph.isAnyVertex(node1, node2) )
+ mRoutingGraph.connectNodes(node1, node2, vertexData, weight);
}
-CAmRoutingTree::CAmRoutingTree(const am_domainID_t rootDomainID) :
- mRootItem(CAmRoutingTreeItem(rootDomainID))
+bool CAmRouter::routeInSameDomain(CAmNode<am_RoutingNodeData_s> & aSource, CAmNode<am_RoutingNodeData_s> & aSink)
{
- assert(rootDomainID!=0);
+ am_RoutingNodeData_s & sourceData = aSource.getData();
+ am_RoutingNodeData_s & sinkData = aSink.getData();
+ am_Source_s * source = sourceData.data.source;
+ //If exists connection return
+ if( mRoutingGraph.isAnyVertex(aSource, aSink))
+ return true;
+ if( mNodeListSourceStatus[source->sourceID] )
+ return false;
+ bool result = false;
+ mNodeListSourceStatus[source->sourceID]=true;
+#ifdef EXTENDED_ROUTING_GRAPH
+ if(sourceData.inConnectionFormat!=sinkData.inConnectionFormat) // it is not possible to connect them directly
+ {
+#else
+ am_Sink_s * sink = sinkData.data.sink;
+ std::vector<am_CustomConnectionFormat_t> listFormats;
+ CAmRouter::listPossibleConnectionFormats(source->listConnectionFormats, sink->listConnectionFormats, listFormats);
+ if(listFormats.size()==0) // it is not possible to connect them directly
+ {
+#endif
+ bool availableConverter = false;
+ for(auto iter = mNodeListConverters.begin(); iter!=mNodeListConverters.end(); iter++)
+ {
+ CAmNode<am_RoutingNodeData_s>* converterNode = *iter;
+ am_RoutingNodeData_s & converterNodeData = converterNode->getData();
+ am_Converter_s * converter = converterNodeData.data.converter;
+ //Get only converters with end point in current source domain
+ if( !mNodeListConverterStatus[converter->converterID] && converter->domainID==source->domainID && (!mOnlyFreeConversionNodes || !isComponentConnected(*converter)))
+ {
+ //Get the sink connected to the converter...
+ mNodeListConverterStatus[converter->converterID]=true;
+#ifdef EXTENDED_ROUTING_GRAPH
+ CAmNode<am_RoutingNodeData_s> *converterSinkNode = this->sinkNodeWithID(converter->sinkID, converterNodeData.inConnectionFormat);
+#else
+ CAmNode<am_RoutingNodeData_s> *converterSinkNode = this->sinkNodeWithID(converter->sinkID);
+#endif
+ if(converterSinkNode)
+ {
+ am_RoutingNodeData_s & converterSinkData = converterSinkNode->getData();
+ //Check whether the hidden sink formats match the source formats...
+#ifdef EXTENDED_ROUTING_GRAPH
+ if(sourceData.inConnectionFormat==converterSinkData.inConnectionFormat)
+ {
+ CAmNode<am_RoutingNodeData_s> *converterSourceNode = this->sourceNodeWithID(converter->sourceID, converterNodeData.outConnectionFormat);
+ if(converterSourceNode)
+ {
+ am_RoutingNodeData_s & converterSourceData = converterSourceNode->getData();
+ if(converterSourceData.inConnectionFormat==converterSinkData.outConnectionFormat)
+ {
+ availableConverter=true;
+ // Connection source->conv_sink->converter->conv_source
+ this->connectNodes(aSource, *converterSinkNode, converterNodeData.inConnectionFormat, 1);
+ this->connectNodes(*converterSinkNode, *converterNode, converterNodeData.inConnectionFormat, 1);
+ this->connectNodes(*converterNode, *converterSourceNode, converterNodeData.outConnectionFormat, 1);
+ result|=this->routeInSameDomain(*converterSourceNode, aSink);
+ }
+ }
+ }
+ else
+ {
+ //the converter is not suitable, lets try to find paths through another domains
+ bool alternResult = this->routeInAnotherDomain(aSource, *converterSinkNode);
+ if(alternResult)
+ {
+ CAmNode<am_RoutingNodeData_s> *converterSourceNode = this->sourceNodeWithID(converter->sourceID, converterNodeData.outConnectionFormat);
+ if(converterSourceNode)
+ {
+ am_RoutingNodeData_s & converterSourceData = converterSourceNode->getData();
+ if(converterSourceData.inConnectionFormat==converterSinkData.outConnectionFormat)
+ {
+ // Connection source->conv_sink->converter->conv_source
+ this->connectNodes(*converterSinkNode, *converterNode, converterNodeData.inConnectionFormat, 1);
+ this->connectNodes(*converterNode, *converterSourceNode, converterNodeData.outConnectionFormat, 1);
+ result|=this->routeInSameDomain(*converterSourceNode, aSink);
+ }
+ }
+ }
+ }
+#else
+ am_Sink_s * nextSink = converterSinkData.data.sink;
+ std::vector<am_CustomConnectionFormat_t> sourceFormats, sinkFormats, intersection;
+ //Check whether the hidden sink formats match the source formats...
+ CAmRouter::listPossibleConnectionFormats(source->listConnectionFormats, nextSink->listConnectionFormats, intersection);
+ if(intersection.size()>0)//OK match source -> conv_sink
+ {
+ //Are there convertible formats or not
+ if(CAmRouter::getAllowedFormatsFromConvMatrix(converter->convertionMatrix, converter->listSourceFormats, converter->listSinkFormats, sourceFormats, sinkFormats))
+ {
+ availableConverter=true;
+ CAmNode<am_RoutingNodeData_s> *nextSourceNode = this->sourceNodeWithID(converter->sourceID);
+ assert(nextSourceNode);
+ //Connections source->hidden_sink->converter->hidden_source
+ this->connectNodes(aSource, *converterSinkNode, CF_UNKNOWN, 1);
+ this->connectNodes(*converterSinkNode, *converterNode, CF_UNKNOWN, 1);
+ this->connectNodes(*converterNode, *nextSourceNode, CF_UNKNOWN, 1);
+ //Go ahead with hidden_source and sink
+ result|=this->routeInSameDomain(*nextSourceNode, aSink);
+ }
+ }
+ else
+ {
+ //the converter is not suitable, lets try to find paths through another domains
+ bool alternResult = this->routeInAnotherDomain(aSource, *converterSinkNode);
+ if(alternResult)
+ {
+ if(CAmRouter::getAllowedFormatsFromConvMatrix(converter->convertionMatrix, converter->listSourceFormats, converter->listSinkFormats, sourceFormats, sinkFormats))
+ {
+ CAmNode<am_RoutingNodeData_s> *nextSourceNode = this->sourceNodeWithID(converter->sourceID);
+ assert(nextSourceNode);
+ //Connections source->hidden_sink->converter->hidden_source
+ this->connectNodes(*converterSinkNode, *converterNode, CF_UNKNOWN, 1);
+ this->connectNodes(*converterNode, *nextSourceNode, CF_UNKNOWN, 1);
+ //Go ahead with hidden_source and sink
+ result|=this->routeInSameDomain(*nextSourceNode, aSink);
+ }
+ }
+ }
+#endif
+ }
+ mNodeListConverterStatus[converter->converterID]=false;
+ }
+ }
+ if(!availableConverter)
+ {
+ mNodeListSourceStatus[source->sourceID]=false;
+ result|=this->routeInAnotherDomain(aSource, aSink);
+ }
+ }
+ else
+ {
+ //success only if the source can be connected with the sink
+#ifdef EXTENDED_ROUTING_GRAPH
+ this->connectNodes(aSource, aSink, sourceData.inConnectionFormat, 1);
+#else
+ this->connectNodes(aSource, aSink, CF_UNKNOWN, 1);
+#endif
+ result=true;
+ }
+ mNodeListSourceStatus[source->sourceID]=false;
+ return result;
}
-CAmRoutingTreeItem *CAmRoutingTree::insertItem(const am_domainID_t domainID, const am_gatewayID_t gatewayID, CAmRoutingTreeItem *parent)
+bool CAmRouter::routeInAnotherDomain(CAmNode<am_RoutingNodeData_s> & aSource, CAmNode<am_RoutingNodeData_s> & aSink)
{
- CAmRoutingTreeItem *newTree = new CAmRoutingTreeItem(domainID, gatewayID, parent);
- parent->appendChild(newTree);
- mListChild.push_back(newTree);
- return (newTree);
+ am_RoutingNodeData_s & sourceData = aSource.getData();
+ am_RoutingNodeData_s & sinkData = aSink.getData();
+ am_Source_s * source = sourceData.data.source;
+ am_Sink_s * sink = sinkData.data.sink;
+
+ if(mRoutingGraph.isAnyVertex(aSource, aSink))
+ return true;
+ if( mNodeListSourceStatus[source->sourceID] )
+ return false;
+ mNodeListSourceStatus[source->sourceID]=true;
+#ifndef EXTENDED_ROUTING_GRAPH
+ std::vector<am_CustomConnectionFormat_t> sourceFormats, sinkFormats, intersection;
+#endif
+ bool result = false;
+ for(auto iter = mNodeListGateways.begin(); iter!=mNodeListGateways.end(); iter++)
+ {
+ CAmNode<am_RoutingNodeData_s>* gatewayNode = *iter;
+ am_RoutingNodeData_s & gatewayNodeData = gatewayNode->getData();
+ am_Gateway_s * gateway = gatewayNodeData.data.gateway;
+ //Get only gateways with end point in current source domain
+ if(
+ !mNodeListGatewayStatus[gateway->gatewayID] &&
+ gateway->domainSinkID==source->domainID &&
+ (!mOnlyFreeConversionNodes || !isComponentConnected(*gateway)) )
+ {
+ //Get the sink connected to the gateway...
+ mNodeListGatewayStatus[gateway->gatewayID]=true;
+#ifdef EXTENDED_ROUTING_GRAPH
+ CAmNode<am_RoutingNodeData_s> *gatewaySinkNode = this->sinkNodeWithID(gateway->sinkID, gatewayNodeData.inConnectionFormat);
+#else
+ CAmNode<am_RoutingNodeData_s> *gatewaySinkNode = this->sinkNodeWithID(gateway->sinkID);
+#endif
+
+ if(gatewaySinkNode)
+ {
+ am_RoutingNodeData_s & gatewaySinkData = gatewaySinkNode->getData();
+ //Check whether the hidden sink formats match the source formats...
+
+#ifdef EXTENDED_ROUTING_GRAPH
+ if(sourceData.inConnectionFormat==gatewaySinkData.inConnectionFormat)
+ {
+ //Check if the gateway is able to convert any formats...
+ CAmNode<am_RoutingNodeData_s> *gatewaySourceNode = this->sourceNodeWithID(gateway->sourceID, gatewayNodeData.outConnectionFormat);
+ if(gatewaySourceNode)
+ {
+ am_RoutingNodeData_s & gatewaySourceData = gatewaySourceNode->getData();
+ if(gatewaySourceData.inConnectionFormat==gatewayNodeData.outConnectionFormat)
+ {
+ am_Source_s * gatewaySource = gatewaySourceData.data.source;
+ //Connections source->hidden_sink->gateway->hidden_source
+ this->connectNodes(aSource, *gatewaySinkNode, gatewayNodeData.inConnectionFormat, 1);
+ this->connectNodes(*gatewaySinkNode, *gatewayNode, gatewayNodeData.inConnectionFormat, 1);
+ this->connectNodes(*gatewayNode, *gatewaySourceNode, gatewayNodeData.outConnectionFormat, 1);
+ //Go ahead with hidden_source and sink
+ if(gatewaySource->domainID==sink->domainID)
+ result|=this->routeInSameDomain(*gatewaySourceNode, aSink);
+ else
+ result|=this->routeInAnotherDomain(*gatewaySourceNode, aSink);
+ }
+ }
+ }
+ else
+ {
+ //the gateway is not suitable, lets try to find paths within this domains
+ bool alternResult = this->routeInSameDomain(aSource, *gatewaySinkNode);
+ if(alternResult)
+ {
+ CAmNode<am_RoutingNodeData_s> *gatewaySourceNode = this->sourceNodeWithID(gateway->sourceID, gatewayNodeData.outConnectionFormat);
+ if(gatewaySourceNode)
+ {
+ am_RoutingNodeData_s & gatewaySourceData = gatewaySourceNode->getData();
+ if(gatewaySourceData.inConnectionFormat==gatewayNodeData.outConnectionFormat)
+ {
+ am_Source_s * gatewaySource = gatewaySourceData.data.source;
+ //Connections source->hidden_sink->gateway->hidden_source
+ this->connectNodes(aSource, *gatewaySinkNode, gatewayNodeData.inConnectionFormat, 1);
+ this->connectNodes(*gatewaySinkNode, *gatewayNode, gatewayNodeData.inConnectionFormat, 1);
+ this->connectNodes(*gatewayNode, *gatewaySourceNode, gatewayNodeData.outConnectionFormat, 1);
+ //Go ahead with hidden_source and sink
+ if(gatewaySource->domainID==sink->domainID)
+ result|=this->routeInSameDomain(*gatewaySourceNode, aSink);
+ else
+ result|=this->routeInAnotherDomain(*gatewaySourceNode, aSink);
+ }
+ }
+ }
+ }
+#else
+ am_Sink_s * nextSink = gatewaySinkData.data.sink;
+ std::vector<am_CustomConnectionFormat_t> sourceFormats, sinkFormats, intersection;
+ CAmRouter::listPossibleConnectionFormats(source->listConnectionFormats, nextSink->listConnectionFormats, intersection);
+ if(intersection.size()>0)//OK match source -> conv_sink
+ {
+ //Check if the gateway is able to convert any formats...
+ if(CAmRouter::getAllowedFormatsFromConvMatrix(gateway->convertionMatrix, gateway->listSourceFormats, gateway->listSinkFormats, sourceFormats, sinkFormats))
+ {
+ CAmNode<am_RoutingNodeData_s> *nextSourceNode = this->sourceNodeWithID(gateway->sourceID);
+ assert(nextSourceNode);
+ am_Source_s * nextSource = nextSourceNode->getData().data.source;
+ //Connections source->hidden_sink->gateway->hidden_source
+ this->connectNodes(aSource, *gatewaySinkNode, CF_UNKNOWN, 1);
+ this->connectNodes(*gatewaySinkNode, *gatewayNode, CF_UNKNOWN, 1);
+ this->connectNodes(*gatewayNode, *nextSourceNode, CF_UNKNOWN, 1);
+ //Go ahead with hidden_source and sink
+ if(nextSource->domainID==sink->domainID)
+ result|=this->routeInSameDomain(*nextSourceNode, aSink);
+ else
+ result|=this->routeInAnotherDomain(*nextSourceNode, aSink);
+ }
+ }
+ else
+ {
+ //the gateway is not suitable, lets try to find paths within this domains
+ mNodeListSourceStatus[source->sourceID]=false;
+ bool alternResult = this->routeInSameDomain(aSource, *gatewaySinkNode);
+ if(alternResult)
+ {
+ if(CAmRouter::getAllowedFormatsFromConvMatrix(gateway->convertionMatrix, gateway->listSourceFormats, gateway->listSinkFormats, sourceFormats, sinkFormats))
+ {
+ CAmNode<am_RoutingNodeData_s> *nextSourceNode = this->sourceNodeWithID(gateway->sourceID);
+ assert(nextSourceNode);
+ am_Source_s * nextSource = nextSourceNode->getData().data.source;
+ //Connections source->hidden_sink->gateway->hidden_source
+ this->connectNodes(*gatewaySinkNode, *gatewayNode, CF_UNKNOWN, 1);
+ this->connectNodes(*gatewayNode, *nextSourceNode, CF_UNKNOWN, 1);
+ //Go ahead with hidden_source and sink
+ if(nextSource->domainID==sink->domainID)
+ result|=this->routeInSameDomain(*nextSourceNode, aSink);
+ else
+ result|=this->routeInAnotherDomain(*nextSourceNode, aSink);
+ }
+ }
+ }
+#endif
+ }
+ mNodeListGatewayStatus[gateway->gatewayID]=false;
+ }
+ }
+ mNodeListSourceStatus[source->sourceID]=false;
+ return result;
}
-void CAmRoutingTree::getRoute(CAmRoutingTreeItem *targetItem, std::vector<am_gatewayID_t>& listGateways)
+#ifdef EXTENDED_ROUTING_GRAPH
+void CAmRouter::getShortestPath(const am_Source_s & aSource,
+ const am_Sink_s & aSink,
+ std::vector<am_Route_s> & resultPath,
+ std::vector<std::vector<CAmNode<am_RoutingNodeData_s>*>> & resultNodesPath)
{
- listGateways.clear();
- CAmRoutingTreeItem *parentItem = targetItem;
- while (parentItem != &mRootItem)
- {
- listGateways.push_back(parentItem->returnGatewayID());
- parentItem = parentItem->returnParent();
- }
- std::reverse(listGateways.begin(), listGateways.end());
+ std::vector<CAmNode<am_RoutingNodeData_s>*> listTargets;
+ std::vector<CAmNode<am_RoutingNodeData_s>*> * pathNodes;
+ am_Route_s *path;
+ am_RoutingElement_s * element;
+ std::function<void(const am_GraphPathPosition_e, CAmNode<am_RoutingNodeData_s> &)> cb = [&](const am_GraphPathPosition_e pos, CAmNode<am_RoutingNodeData_s> & object)
+ {
+ if(pos==GRAPH_PATH_START)
+ {
+ resultNodesPath.emplace_back();
+ pathNodes=&resultNodesPath.back();
+ resultPath.emplace_back();
+ path= &resultPath.back();
+ path->sinkID = aSink.sinkID;
+ path->sourceID = aSource.sourceID;
+ }
+ pathNodes->insert(pathNodes->begin(), (CAmNode<am_RoutingNodeData_s>*)&object);
+
+ am_RoutingNodeData_s & routingData = object.getData();
+
+ if(routingData.type==am_RoutingNodeData_s::am_NodeDataType_e::SINK)
+ {
+ auto iter = path->route.emplace(path->route.begin());
+ element = &(*iter);
+
+ element->domainID = routingData.data.sink->domainID;
+ element->sinkID = routingData.data.sink->sinkID;
+ element->connectionFormat = routingData.inConnectionFormat;
+
+ }
+ else if(routingData.type==am_RoutingNodeData_s::am_NodeDataType_e::SOURCE)
+ {
+ element->domainID = routingData.data.source->domainID;
+ element->sourceID = routingData.data.source->sourceID;
+ element->connectionFormat = routingData.inConnectionFormat;
+ }
+ };
+
+
+ for(auto it2=aSink.listConnectionFormats.begin(); it2!=aSink.listConnectionFormats.end(); it2++)
+ {
+ am::CAmNode<am::am_RoutingNodeData_s>* pRootNodeSink = sinkNodeWithID(aSink.sinkID, *it2);
+ if(pRootNodeSink)
+ listTargets.push_back(pRootNodeSink);
+ }
+ if(listTargets.size())
+ {
+ for(auto it1=aSource.listConnectionFormats.begin(); it1!=aSource.listConnectionFormats.end(); it1++)
+ {
+ am::CAmNode<am::am_RoutingNodeData_s>* pRootNodeSource = sourceNodeWithID(aSource.sourceID, *it1);
+ if(pRootNodeSource)
+ {
+ mRoutingGraph.getShortestPath(*pRootNodeSource, listTargets, cb);
+ }
+ }
+ }
+}
+
+void CAmRouter::getShortestPath(std::vector<am_Route_s> & routes, std::vector<std::vector<CAmNode<am_RoutingNodeData_s>*>> & nodes)
+{
+ getShortestPath(*mpRootSource, *mpRootSink, routes, nodes);
}
-am_domainID_t CAmRoutingTree::returnRootDomainID() const
+void CAmRouter::getShortestPath(const am_Source_s & aSource, const am_Sink_s & aSink,
+ std::vector<std::vector<CAmNode<am_RoutingNodeData_s>*>> & resultPath)
{
- return (mRootItem.returnDomainID());
+ std::vector<CAmNode<am_RoutingNodeData_s>*> listTargets;
+ for(auto it2=aSink.listConnectionFormats.begin(); it2!=aSink.listConnectionFormats.end(); it2++)
+ {
+ am::CAmNode<am::am_RoutingNodeData_s>* pRootNodeSink = sinkNodeWithID(aSink.sinkID, *it2);
+ if(pRootNodeSink)
+ listTargets.push_back(pRootNodeSink);
+ }
+ if(listTargets.size())
+ {
+ for(auto it1=aSource.listConnectionFormats.begin(); it1!=aSource.listConnectionFormats.end(); it1++)
+ {
+ am::CAmNode<am::am_RoutingNodeData_s>* pRootNodeSource = sourceNodeWithID(aSource.sourceID, *it1);
+ if(pRootNodeSource)
+ {
+ mRoutingGraph.getShortestPath(*pRootNodeSource, listTargets, resultPath);
+ }
+ }
+ }
}
+#else
-CAmRoutingTreeItem *CAmRoutingTree::returnRootItem()
+am_Error_e CAmRouter::determineConnectionFormatsForPath(am_Route_s & routeObjects, std::vector<CAmNode<am_RoutingNodeData_s>*> & nodes)
{
- return (&mRootItem);
+ std::vector<am_RoutingElement_s>::iterator routingElementIterator = routeObjects.route.begin();
+ std::vector<CAmNode<am_RoutingNodeData_s>*>::iterator nodeIterator = nodes.begin();
+ if( routingElementIterator!= routeObjects.route.end() && nodeIterator!=nodes.end() )
+ return doConnectionFormatsForPath(routeObjects, nodes, routingElementIterator, nodeIterator);
+ return E_OK;
}
-CAmRoutingTree::~CAmRoutingTree()
+am_Error_e CAmRouter::doConnectionFormatsForPath(am_Route_s & routeObjects,
+ std::vector<CAmNode<am_RoutingNodeData_s>*> & nodes,
+ std::vector<am_RoutingElement_s>::iterator routingElementIterator,
+ std::vector<CAmNode<am_RoutingNodeData_s>*>::iterator nodeIterator)
{
- std::vector<CAmRoutingTreeItem*>::iterator it = mListChild.begin();
- for (; it != mListChild.end(); ++it)
+ am_Error_e returnError = E_NOT_POSSIBLE;
+ std::vector<am_CustomConnectionFormat_t> listConnectionFormats;
+ std::vector<am_CustomConnectionFormat_t> listMergeConnectionFormats;
+
+ std::vector<CAmNode<am_RoutingNodeData_s>*>::iterator currentNodeIterator = nodeIterator;
+ std::vector<am_RoutingElement_s>::iterator currentRoutingElementIterator = routingElementIterator;
+
+ if (currentRoutingElementIterator!=routeObjects.route.begin())
{
- delete *it;
+ std::vector<am_CustomConnectionFormat_t> listConnectionFormats;
+ std::vector<am_RoutingElement_s>::iterator tempIterator = (currentRoutingElementIterator-1);
+ CAmNode<am_RoutingNodeData_s> * currentNode = *currentNodeIterator;
+ getSourceSinkPossibleConnectionFormats(currentNodeIterator+1, currentNodeIterator+2, listConnectionFormats);
+
+ if(currentNode->getData().type==am_RoutingNodeData_s::am_NodeDataType_e::GATEWAY)
+ {
+ am_Gateway_s *gateway = currentNode->getData().data.gateway;
+ getMergeConnectionFormats(gateway, tempIterator->connectionFormat, listConnectionFormats, listMergeConnectionFormats);
+ }
+ else if(currentNode->getData().type==am_RoutingNodeData_s::am_NodeDataType_e::CONVERTER)
+ {
+ am_Converter_s *converter = currentNode->getData().data.converter;
+ getMergeConnectionFormats(converter, tempIterator->connectionFormat, listConnectionFormats, listMergeConnectionFormats);
+ }
+ currentNodeIterator+=3;
}
+ else
+ {
+ CAmNode<am_RoutingNodeData_s> * currentNode = *currentNodeIterator;
+ assert(currentNode->getData().type==am_RoutingNodeData_s::am_NodeDataType_e::SOURCE);
+
+ currentNodeIterator++;
+ assert(currentNodeIterator!=nodes.end());
+
+ CAmNode<am_RoutingNodeData_s> * nodeSink = *currentNodeIterator;
+ assert(nodeSink->getData().type==am_RoutingNodeData_s::am_NodeDataType_e::SINK);
+
+ am_Source_s *source = currentNode->getData().data.source;
+ am_Sink_s *sink = nodeSink->getData().data.sink;
+ CAmRouter::listPossibleConnectionFormats(source->listConnectionFormats, sink->listConnectionFormats, listMergeConnectionFormats);
+ currentNodeIterator+=1; //now we are on the next converter/gateway
+ }
+
+ //let the controller decide:
+ std::vector<am_CustomConnectionFormat_t> listPriorityConnectionFormats;
+ mpControlSender->getConnectionFormatChoice(currentRoutingElementIterator->sourceID, currentRoutingElementIterator->sinkID, routeObjects,
+ listMergeConnectionFormats, listPriorityConnectionFormats);
+
+ //we have the list sorted after priors - now we try one after the other with the next part of the route
+ std::vector<am_CustomConnectionFormat_t>::iterator connectionFormatIterator = listPriorityConnectionFormats.begin();
+ //here we need to check if we are at the end and stop
+ std::vector<am_RoutingElement_s>::iterator nextIterator = currentRoutingElementIterator + 1;//next pair source and sink
+ if (nextIterator == routeObjects.route.end())
+ {
+ if (!listPriorityConnectionFormats.empty())
+ {
+ currentRoutingElementIterator->connectionFormat = listPriorityConnectionFormats.front();
+ return (E_OK);
+ }
+ else
+ return (E_NOT_POSSIBLE);
+ }
+
+ for (; connectionFormatIterator != listPriorityConnectionFormats.end(); ++connectionFormatIterator)
+ {
+ currentRoutingElementIterator->connectionFormat = *connectionFormatIterator;
+ if ((returnError = doConnectionFormatsForPath(routeObjects, nodes, nextIterator, currentNodeIterator)) == E_OK)
+ {
+ break;
+ }
+ }
+ return (returnError);
+}
+
+void CAmRouter::getShortestPath(const CAmNode<am_RoutingNodeData_s> & source,
+ const CAmNode<am_RoutingNodeData_s> & destination,
+ std::vector<CAmNode<am_RoutingNodeData_s>*> & resultPath)
+{
+ mRoutingGraph.getShortestPath(source, destination, resultPath);
+}
+
+void CAmRouter::getShortestPath(std::vector<CAmNode<am_RoutingNodeData_s>*> & resultPath)
+{
+ getShortestPath(*mpRootSource, *mpRootSink, resultPath);
}
+
+void CAmRouter::getShortestPath(CAmNode<am_RoutingNodeData_s> & aSource, CAmNode<am_RoutingNodeData_s> & aSink,
+ am_Route_s & resultPath, std::vector<CAmNode<am_RoutingNodeData_s>*> & resultNodesPath)
+{
+ am_RoutingElement_s * element;
+ am_RoutingNodeData_s & sinkNodeData = aSink.getData();
+ am_RoutingNodeData_s & sourceNodeData = aSource.getData();
+ resultPath.sinkID = sinkNodeData.data.sink->sinkID;
+ resultPath.sourceID = sourceNodeData.data.source->sourceID;
+
+ std::function<void(const am_GraphPathPosition_e, CAmNode<am_RoutingNodeData_s> &)> cb = [&](const am_GraphPathPosition_e, CAmNode<am_RoutingNodeData_s> & object)
+ {
+ resultNodesPath.insert(resultNodesPath.begin(), (CAmNode<am_RoutingNodeData_s>*)&object);
+ am_RoutingNodeData_s & routingData = object.getData();
+ if(routingData.type==am_RoutingNodeData_s::am_NodeDataType_e::SINK)
+ {
+ auto iter = resultPath.route.emplace(resultPath.route.begin());
+ element = &(*iter);
+ element->domainID = routingData.data.sink->domainID;
+ element->sinkID = routingData.data.sink->sinkID;
+ element->connectionFormat = CF_UNKNOWN;
+ }
+ else if(routingData.type==am_RoutingNodeData_s::am_NodeDataType_e::SOURCE)
+ {
+ element->domainID = routingData.data.source->domainID;
+ element->sourceID = routingData.data.source->sourceID;
+ element->connectionFormat = CF_UNKNOWN;
+ }
+ };
+ mRoutingGraph.getShortestPath(aSource, aSink, cb);
+}
+
+void CAmRouter::getShortestPath(am_Route_s & resultPath, std::vector<CAmNode<am_RoutingNodeData_s>*> & resultNodesPath)
+{
+ getShortestPath(*mpRootSource, *mpRootSink, resultPath, resultNodesPath);
+}
+
+am_Error_e CAmRouter::getAllPaths(CAmNode<am_RoutingNodeData_s> & aSource, CAmNode<am_RoutingNodeData_s> & aSink,
+ std::vector<am_Route_s> & resultPath, std::vector<std::vector<CAmNode<am_RoutingNodeData_s>*>> & resultNodesPath)
+{
+ uint8_t errorsCount = 0, successCount = 0;
+ mRoutingGraph.getAllPaths(aSource, aSink, [&](const std::vector<CAmNode<am_RoutingNodeData_s>*> & path) {
+ resultNodesPath.push_back(path);
+ resultPath.emplace_back();
+ am_Route_s & nextRoute = resultPath.back();
+ nextRoute.sinkID = aSink.getData().data.sink->sinkID;
+ nextRoute.sourceID = aSource.getData().data.source->sourceID;
+ am_RoutingElement_s * element;
+ for(auto it = path.begin(); it!=path.end(); it++)
+ {
+ am_RoutingNodeData_s & routingData = (*it)->getData();
+ if(routingData.type==am_RoutingNodeData_s::am_NodeDataType_e::SOURCE)
+ {
+ auto iter = nextRoute.route.emplace(nextRoute.route.end());
+ element = &(*iter);
+ element->domainID = routingData.data.source->domainID;
+ element->sourceID = routingData.data.source->sourceID;
+ element->connectionFormat = CF_UNKNOWN;
+ }
+ else if(routingData.type==am_RoutingNodeData_s::am_NodeDataType_e::SINK)
+ {
+ element->domainID = routingData.data.sink->domainID;
+ element->sinkID = routingData.data.sink->sinkID;
+ element->connectionFormat = CF_UNKNOWN;
+ }
+ }
+ am_Error_e err = determineConnectionFormatsForPath(nextRoute, (std::vector<CAmNode<am_RoutingNodeData_s>*> &)path);
+ if(err!=E_OK)
+ {
+ errorsCount++;
+ auto last = resultPath.end()-1;
+ resultPath.erase(last);
+#ifdef TRACE_GRAPH
+ std::cout<<"Error by determining connection formats for path from source:"<<nextRoute.sourceID<<" to sink:"<<nextRoute.sinkID<<"\n";
+#endif
+ }
+ else
+ {
+#ifdef TRACE_GRAPH
+ std::cout<<"Successfully determined connection formats for path from source:"<<nextRoute.sourceID<<" to sink:"<<nextRoute.sinkID<<"\n";
+#endif
+ successCount++;
+ }
+ });
+ if(successCount)
+ return E_OK;
+ if(errorsCount)
+ return E_NOT_POSSIBLE;
+ return E_OK;
+}
+
+am_Error_e CAmRouter::getAllPaths(std::vector<am_Route_s> & resultPath, std::vector<std::vector<CAmNode<am_RoutingNodeData_s>*>> & resultNodesPath)
+{
+ return getAllPaths(*mpRootSource, *mpRootSink, resultPath, resultNodesPath);
+}
+
+#endif
+
+void CAmRouter::clear()
+{
+ mNodeListSourceStatus.clear();
+ mNodeListSinkStatus.clear();
+ mNodeListConverterStatus.clear();
+ mNodeListGatewayStatus.clear();
+
+ mRoutingGraph.clear();
+ mNodeListSources.clear();
+ mNodeListSinks.clear();
+ mNodeListGateways.clear();
+ mNodeListConverters.clear();
+ mpRootSource=NULL;
+ mpRootSink=NULL;
+}
+
+
}
diff --git a/AudioManagerDaemon/src/CAmRoutingReceiver.cpp b/AudioManagerDaemon/src/CAmRoutingReceiver.cpp
index eaa38e1..67bc911 100644
--- a/AudioManagerDaemon/src/CAmRoutingReceiver.cpp
+++ b/AudioManagerDaemon/src/CAmRoutingReceiver.cpp
@@ -238,11 +238,21 @@ am_Error_e CAmRoutingReceiver::registerGateway(const am_Gateway_s & gatewayData,
return (mpControlSender->hookSystemRegisterGateway(gatewayData, gatewayID));
}
+am_Error_e CAmRoutingReceiver::registerConverter(const am_Converter_s& converterData, am_converterID_t& converterID)
+{
+ return (mpControlSender->hookSystemRegisterConverter(converterData, converterID));
+}
+
am_Error_e CAmRoutingReceiver::deregisterGateway(const am_gatewayID_t gatewayID)
{
return (mpControlSender->hookSystemDeregisterGateway(gatewayID));
}
+am_Error_e CAmRoutingReceiver::deregisterConverter(const am_converterID_t converterID)
+{
+ return (mpControlSender->hookSystemDeregisterConverter(converterID));
+}
+
am_Error_e CAmRoutingReceiver::peekSink(const std::string& name, am_sinkID_t & sinkID)
{
return (mpDatabaseHandler->peekSink(name, sinkID));
@@ -418,6 +428,11 @@ am_Error_e CAmRoutingReceiver::updateGateway(const am_gatewayID_t gatewayID, con
return (mpControlSender->hookSystemUpdateGateway(gatewayID,listSourceFormats,listSinkFormats,convertionMatrix));
}
+am_Error_e CAmRoutingReceiver::updateConverter(const am_converterID_t converterID, const std::vector<am_CustomConnectionFormat_t>& listSourceFormats, const std::vector<am_CustomConnectionFormat_t>& listSinkFormats, const std::vector<bool>& convertionMatrix)
+{
+ return (mpControlSender->hookSystemUpdateConverter(converterID,listSourceFormats,listSinkFormats,convertionMatrix));
+}
+
am_Error_e CAmRoutingReceiver::updateSink(const am_sinkID_t sinkID, const am_sinkClass_t sinkClassID, const std::vector<am_SoundProperty_s>& listSoundProperties, const std::vector<am_CustomConnectionFormat_t>& listConnectionFormats, const std::vector<am_MainSoundProperty_s>& listMainSoundProperties)
{
return (mpControlSender->hookSystemUpdateSink(sinkID,sinkClassID,listSoundProperties,listConnectionFormats,listMainSoundProperties));
diff --git a/AudioManagerDaemon/src/CAmRoutingSender.cpp b/AudioManagerDaemon/src/CAmRoutingSender.cpp
index 1606761..cd9c3d7 100644
--- a/AudioManagerDaemon/src/CAmRoutingSender.cpp
+++ b/AudioManagerDaemon/src/CAmRoutingSender.cpp
@@ -525,7 +525,11 @@ am_Error_e CAmRoutingSender::removeCrossfaderLookup(const am_crossfaderID_t cros
am_Error_e CAmRoutingSender::removeHandle(const am_Handle_s& handle)
{
if (mlistActiveHandles.erase(handle))
+ {
+ logInfo(__PRETTY_FUNCTION__,handle.handle,handle.handleType);
return (E_OK);
+ }
+ logError(__PRETTY_FUNCTION__,"Could not remove handle",handle.handle);
return (E_UNKNOWN);
}
@@ -556,6 +560,7 @@ am_Handle_s CAmRoutingSender::createHandle(const am_handleData_c& handleData, co
mlistActiveHandles.insert(std::make_pair(handle, handleData));
if ((mlistActiveHandles.size()%100) == 0)
logInfo("CAmRoutingSender::createHandle warning: too many open handles, number of handles: ", mlistActiveHandles.size());
+ logInfo(__PRETTY_FUNCTION__,handle.handle, handle.handleType);
return (handle);
}
@@ -570,9 +575,18 @@ CAmRoutingSender::am_handleData_c CAmRoutingSender::returnHandleData(const am_Ha
HandlesMap::const_iterator it = mlistActiveHandles.begin();
it = mlistActiveHandles.find(handle);
if (it!=mlistActiveHandles.end())
- return (it->second);
+ {
+ const am_handleData_c & result = it->second;
+ logInfo(__PRETTY_FUNCTION__, handle.handle, handle.handleType,
+ "connectionID", result.connectionID,
+ "sinkID", result.sinkID,
+ "sourceID",result.sourceID,
+ "sourceState", result.sourceState);
+ return result;
+ }
am_handleData_c handleData;
handleData.sinkID=0;
+ logError(__PRETTY_FUNCTION__,"could not find handle data for handle",handle.handle,handle.handleType);
return (handleData);
}