From af0ba5b505b361679c07899187b7043d867742c3 Mon Sep 17 00:00:00 2001 From: christian mueller Date: Tue, 24 Jan 2012 17:07:25 +0100 Subject: * finalized Router implementation * added new generated ControlSendInterface with router support --- AudioManagerDaemon/src/Router.cpp | 370 +++++++++++++++++++------------------- 1 file changed, 187 insertions(+), 183 deletions(-) (limited to 'AudioManagerDaemon/src') diff --git a/AudioManagerDaemon/src/Router.cpp b/AudioManagerDaemon/src/Router.cpp index 9e1b5f6..e7c9096 100644 --- a/AudioManagerDaemon/src/Router.cpp +++ b/AudioManagerDaemon/src/Router.cpp @@ -27,264 +27,268 @@ #include #include #include +#include using namespace am; am_Error_e getConnectionFormatChoice(const am_sinkID_t, const am_sourceID_t, const std::vector& listPossibleConnectionFormats, std::vector& listPriorityConnectionFormats) { - listPriorityConnectionFormats=listPossibleConnectionFormats; - return (E_OK); + listPriorityConnectionFormats = listPossibleConnectionFormats; + return (E_OK); } -Router::Router(DatabaseHandler *iDatabaseHandler) - :mDatabaseHandler(iDatabaseHandler) +Router::Router(DatabaseHandler *iDatabaseHandler) : + mDatabaseHandler(iDatabaseHandler) { - assert(mDatabaseHandler); + assert(mDatabaseHandler); } -am_Error_e am::Router::getRoute(const bool onlyfree, const am_sourceID_t sourceID, const am_sinkID_t sinkID, std::vector & returnList) +am_Error_e Router::getRoute(const bool onlyfree, const am_sourceID_t sourceID, const am_sinkID_t sinkID, std::vector & returnList) { - //first find out in which domains the source and sink are - am_domainID_t sourceDomainID; - am_domainID_t sinkDomainID; - if (mDatabaseHandler->getDomainOfSource(sourceID,sourceDomainID) != E_OK) return (E_NON_EXISTENT); - if (mDatabaseHandler->getDomainOfSink(sinkID,sinkDomainID) != E_OK) return (E_NON_EXISTENT); - - RoutingTree routingtree(sourceDomainID); //Build up a Tree from the Source_Domain to every other domain. - std::vector flattree; //This list is the flat tree - std::vector matchtree; //This List holds all TreeItems which have the right Domain Sink IDs - std::vector listGatewayID; //holds all gateway ids of the route - am_RoutingElement_s routingElement; - std::vector actualRoutingElement;//intermediate list of current routing pairs - am_Route_s actualRoute; //holds the actual Route - am_sourceID_t lastSource = 0; - - //TODO: kind of unclean. The separation between database and router could be better. - mDatabaseHandler->getRoutingTree(onlyfree, &routingtree, &flattree); //Build up the tree out of the database as - - //we go through the returned flattree and look for our sink, after that flattree holds only treeItems that match - std::vector::iterator flatIterator=flattree.begin(); - for(;flatIterator!=flattree.end();++flatIterator) - { - if((*flatIterator)->returnDomainID()!=sinkDomainID) - { - flatIterator=flattree.erase(flatIterator); - } - } - - //No we need to trace back the routes for each entry in matchtree - flatIterator=flattree.begin(); - for(;flatIterator!=flattree.end();++flatIterator) - { - //getting the route for the actual item - routingtree.getRoute(*flatIterator, &listGatewayID); //This gives only the Gateway IDs we need more - - //go throught the gatewayids and get more information - std::vector::iterator gatewayIterator =listGatewayID.begin(); - for(;gatewayIterator!=listGatewayID.end();++gatewayIterator) - { - am_Gateway_s gatewayData; - if (mDatabaseHandler->getGatewayInfoDB(2,gatewayData) != E_OK) return (E_UNKNOWN); - - //at the beginning of the route, we connect first the source to the first gateway - if (gatewayIterator ==listGatewayID.begin()) - { - routingElement.sourceID = sourceID; - routingElement.domainID = sourceDomainID; - } - else - { - routingElement.sourceID = lastSource; - routingElement.domainID = gatewayData.domainSinkID; - } - routingElement.sinkID = gatewayData.sinkID; - actualRoutingElement.push_back(routingElement); - lastSource = gatewayData.sourceID; - } - //at the end of the route, connect to the sink ! - routingElement.sourceID = lastSource; - routingElement.sinkID = sinkID; - routingElement.domainID = sinkDomainID; - actualRoutingElement.push_back(routingElement); - - //So now we got the route, what is missing are the connectionFormats... - - //Step through the routes and try to use always the best connectionFormat - std::vector::iterator routingInterator=actualRoutingElement.begin(); - gatewayIterator =listGatewayID.begin(); - if(findBestWay(actualRoutingElement,routingInterator,gatewayIterator,0)!=E_OK) continue; - - //add the route to the list of routes... - actualRoute.sourceID = sourceID; - actualRoute.sinkID = sinkID; - actualRoute.route = actualRoutingElement; - returnList.push_back(actualRoute); - } - return (E_OK); + //first find out in which domains the source and sink are + am_domainID_t sourceDomainID; + am_domainID_t sinkDomainID; + if (mDatabaseHandler->getDomainOfSource(sourceID, sourceDomainID) != E_OK) + return (E_NON_EXISTENT); + if (mDatabaseHandler->getDomainOfSink(sinkID, sinkDomainID) != E_OK) + return (E_NON_EXISTENT); + + RoutingTree routingtree(sourceDomainID); //Build up a Tree from the Source_Domain to every other domain. + std::vector flattree; //This list is the flat tree + std::vector matchtree; //This List holds all TreeItems which have the right Domain Sink IDs + std::vector listGatewayID; //holds all gateway ids of the route + am_RoutingElement_s routingElement; + std::vector actualRoutingElement; //intermediate list of current routing pairs + am_Route_s actualRoute; //holds the actual Route + am_sourceID_t lastSource = 0; + + //TODO: kind of unclean. The separation between database and router could be better. + mDatabaseHandler->getRoutingTree(onlyfree, &routingtree, &flattree); //Build up the tree out of the database as + + //we go through the returned flattree and look for our sink, after that flattree holds only treeItems that match + std::vector::iterator flatIterator = flattree.begin(); + for (; flatIterator != flattree.end(); ++flatIterator) + { + if ((*flatIterator)->returnDomainID() != sinkDomainID) + { + flatIterator = flattree.erase(flatIterator); + } + } + + //No we need to trace back the routes for each entry in matchtree + flatIterator = flattree.begin(); + for (; flatIterator != flattree.end(); ++flatIterator) + { + //getting the route for the actual item + routingtree.getRoute(*flatIterator, &listGatewayID); //This gives only the Gateway IDs we need more + + //go throught the gatewayids and get more information + std::vector::iterator gatewayIterator = listGatewayID.begin(); + for (; gatewayIterator != listGatewayID.end(); ++gatewayIterator) + { + am_Gateway_s gatewayData; + if (mDatabaseHandler->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::iterator routingInterator = actualRoutingElement.begin(); + gatewayIterator = listGatewayID.begin(); + if (findBestWay(actualRoutingElement, routingInterator, gatewayIterator, 0) != E_OK) + continue; + + //add the route to the list of routes... + actualRoute.sourceID = sourceID; + actualRoute.sinkID = sinkID; + actualRoute.route = actualRoutingElement; + returnList.push_back(actualRoute); + } + return (E_OK); } -void Router::listPossibleConnectionFormats(const am_sourceID_t sourceID,const am_sinkID_t sinkID,std::vector& listFormats) const +void Router::listPossibleConnectionFormats(const am_sourceID_t sourceID, const am_sinkID_t sinkID, std::vector& listFormats) const { - std::vector listSourceFormats; - std::vector listSinkFormats; - mDatabaseHandler->getListSinkConnectionFormats(sinkID,listSinkFormats); - mDatabaseHandler->getListSourceConnectionFormats(sourceID,listSourceFormats); - set_union(listSourceFormats.begin(), listSourceFormats.end(), listSinkFormats.begin(), listSinkFormats.end(), listFormats.begin()); + std::vector listSourceFormats; + std::vector listSinkFormats; + mDatabaseHandler->getListSinkConnectionFormats(sinkID, listSinkFormats); + mDatabaseHandler->getListSourceConnectionFormats(sourceID, listSourceFormats); + std::insert_iterator > inserter(listFormats, listFormats.begin()); + set_intersection(listSourceFormats.begin(), listSourceFormats.end(), listSinkFormats.begin(), listSinkFormats.end(), inserter); } am_Error_e Router::findBestWay(std::vector & listRoute, std::vector::iterator routeIterator, std::vector::iterator gatewayIterator, int choiceNumber) { - std::vector listConnectionFormats; - std::vector listPriorityConnectionFormats; - //get best connection format for the first connection, now - listPossibleConnectionFormats(routeIterator->sinkID,routeIterator->sourceID,listConnectionFormats); - - //if we get to the point that no choice makes sense, return ... - if (choiceNumber>=(int)listConnectionFormats.size()) return (E_NOT_POSSIBLE); - - //if we have not just started, we need to take care about the gateways... - if(routeIterator!=listRoute.begin()) - { - //since we have to deal with Gateways, there are restrictions what connectionFormat we can take. So we need to take the subset of connections that are restricted: - std::vector listRestrictedConnectionFormats; - listRestrictedOutputFormatsGateways(*gatewayIterator,(routeIterator--)->connectionFormat,listRestrictedConnectionFormats); - set_union(listConnectionFormats.begin(), listConnectionFormats.end(), listRestrictedConnectionFormats.begin(), listRestrictedConnectionFormats.end(), listConnectionFormats.begin()); - } - - //let the controller decide: - getConnectionFormatChoice(routeIterator->sinkID,routeIterator->sourceID,listConnectionFormats,listPriorityConnectionFormats); - - //go back one step, if we cannot find a format! - if(listPriorityConnectionFormats.empty()) - { - findBestWay(listRoute,routeIterator--,gatewayIterator--,choiceNumber++); - } - routeIterator->connectionFormat=listPriorityConnectionFormats.at(choiceNumber); - - if (routeIterator listConnectionFormats; + std::vector listPriorityConnectionFormats; + //get best connection format for the first connection, now + listPossibleConnectionFormats(routeIterator->sourceID, routeIterator->sinkID, listConnectionFormats); + + //if we get to the point that no choice makes sense, return ... + if (choiceNumber >= (int) listConnectionFormats.size()) + return (E_NOT_POSSIBLE); + + //if we have not just started, we need to take care about the gateways... + if (routeIterator != listRoute.begin()) + { + //since we have to deal with Gateways, there are restrictions what connectionFormat we can take. So we need to take the subset of connections that are restricted: + std::vector listRestrictedConnectionFormats; + std::insert_iterator > inserter(listConnectionFormats, listConnectionFormats.begin()); + std::vector::iterator tempIterator(routeIterator); + tempIterator--; + listRestrictedOutputFormatsGateways(*gatewayIterator, (tempIterator)->connectionFormat, listRestrictedConnectionFormats); + set_intersection(listConnectionFormats.begin(), listConnectionFormats.end(), listRestrictedConnectionFormats.begin(), listRestrictedConnectionFormats.end(), inserter); + gatewayIterator++; + } + + //let the controller decide: + getConnectionFormatChoice(routeIterator->sinkID, routeIterator->sourceID, listConnectionFormats, listPriorityConnectionFormats); + + //go back one step, if we cannot find a format and take the next best! + if (listPriorityConnectionFormats.empty()) + { + findBestWay(listRoute, --routeIterator, --gatewayIterator, ++choiceNumber); + } + + routeIterator->connectionFormat = listPriorityConnectionFormats.at(choiceNumber); + + //ok, we are through and found a way, if not, take the next part of the route and start with toplevel + if (routeIterator < listRoute.end()) + { + findBestWay(listRoute, ++routeIterator, gatewayIterator, 0); + } + return (E_OK); } void Router::listRestrictedOutputFormatsGateways(const am_gatewayID_t gatewayID, const am_ConnectionFormat_e sinkConnectionFormat, std::vector & listFormats) const { - listFormats.clear(); - am_Gateway_s gatewayData; - std::vector::const_iterator rowSinkIterator=gatewayData.listSinkFormats.begin(); - std::vector::const_iterator matrixIterator=gatewayData.convertionMatrix.begin(); - mDatabaseHandler->getGatewayInfoDB(gatewayID,gatewayData); - - //find the row number of the sink - rowSinkIterator = find (gatewayData.listSinkFormats.begin(), gatewayData.listSinkFormats.end(), sinkConnectionFormat); - int rowNumberSink=rowSinkIterator - gatewayData.listSinkFormats.begin(); - - //go through the convertionMatrix and find out if the conversion is possible, if yes, add connectionFormat ... - matrixIterator+rowNumberSink; - - //iterate line-wise through the matrix and add more formats - do - { - if(*matrixIterator) - { - listFormats.push_back(gatewayData.listSourceFormats.at(matrixIterator-gatewayData.convertionMatrix.begin())); - } - matrixIterator+gatewayData.listSinkFormats.size(); - } - while (matrixIterator-gatewayData.convertionMatrix.begin()<(int)gatewayData.listSourceFormats.size()); + listFormats.clear(); + am_Gateway_s gatewayData; + mDatabaseHandler->getGatewayInfoDB(gatewayID, gatewayData); + std::vector::const_iterator rowSinkIterator = gatewayData.listSinkFormats.begin(); + std::vector::const_iterator matrixIterator = gatewayData.convertionMatrix.begin(); + + //find the row number of the sink + rowSinkIterator = find(gatewayData.listSinkFormats.begin(), gatewayData.listSinkFormats.end(), sinkConnectionFormat); + int rowNumberSink = rowSinkIterator - gatewayData.listSinkFormats.begin(); + + //go through the convertionMatrix and find out if the conversion is possible, if yes, add connectionFormat ... + matrixIterator + rowNumberSink; + + //iterate line-wise through the matrix and add more formats + do + { + if (*matrixIterator) + { + listFormats.push_back(gatewayData.listSourceFormats.at(matrixIterator - gatewayData.convertionMatrix.begin())); + } + matrixIterator += gatewayData.listSinkFormats.size(); + } while (matrixIterator - gatewayData.convertionMatrix.begin() < (int) gatewayData.listSourceFormats.size()); } - Router::~Router() { } -RoutingTreeItem::RoutingTreeItem(const am_domainID_t domainID, const am_gatewayID_t gatewayID, RoutingTreeItem *parent) - :mDomainID(domainID), - mGatewayID(gatewayID), - mParentItem(parent) +RoutingTreeItem::RoutingTreeItem(const am_domainID_t domainID, const am_gatewayID_t gatewayID, RoutingTreeItem *parent) : + mDomainID(domainID), // + mGatewayID(gatewayID), // + mParentItem(parent) { - assert(mDomainID==0); - assert(mGatewayID==0); - assert(mParentItem); + assert(mDomainID!=0); } void RoutingTreeItem::appendChild(RoutingTreeItem *newChild) { - assert(newChild); - mListChildItems.push_back(newChild); + assert(newChild); + mListChildItems.push_back(newChild); } void RoutingTreeItem::returnChildItems(std::vector listChildItems) { - listChildItems=mListChildItems; + listChildItems = mListChildItems; } am_domainID_t RoutingTreeItem::returnDomainID() const { - return (mDomainID); + return (mDomainID); } am_gatewayID_t RoutingTreeItem::returnGatewayID() const { - return (mGatewayID); + return (mGatewayID); } RoutingTreeItem* RoutingTreeItem::returnParent() const { - return (mParentItem); + return (mParentItem); } RoutingTreeItem::~RoutingTreeItem() { } - -RoutingTree::RoutingTree(const am_domainID_t rootDomainID) - :mRootItem(RoutingTreeItem(rootDomainID)) +RoutingTree::RoutingTree(const am_domainID_t rootDomainID) : + mRootItem(RoutingTreeItem(rootDomainID)) { - assert(rootDomainID!=0); + assert(rootDomainID!=0); } RoutingTreeItem *RoutingTree::insertItem(const am_domainID_t domainID, const am_gatewayID_t gatewayID, RoutingTreeItem *parent) { - RoutingTreeItem *newTree = new RoutingTreeItem(domainID, gatewayID,parent); - parent->appendChild(newTree); - mListChild.push_back(newTree); - return newTree; + RoutingTreeItem *newTree = new RoutingTreeItem(domainID, gatewayID, parent); + parent->appendChild(newTree); + mListChild.push_back(newTree); + return newTree; } void RoutingTree::getRoute(RoutingTreeItem *targetItem, std::vector *listGateways) { - RoutingTreeItem *parentItem = targetItem; - while (parentItem != &mRootItem) { - listGateways->push_back(parentItem->returnGatewayID()); - parentItem = parentItem->returnParent(); - } + RoutingTreeItem *parentItem = targetItem; + while (parentItem != &mRootItem) + { + listGateways->push_back(parentItem->returnGatewayID()); + parentItem = parentItem->returnParent(); + } } am_domainID_t RoutingTree::returnRootDomainID() const { - return (mRootItem.returnDomainID()); + return (mRootItem.returnDomainID()); } RoutingTreeItem *RoutingTree::returnRootItem() { - return (&mRootItem); + return (&mRootItem); } RoutingTree::~RoutingTree() { - std::vector::iterator it=mListChild.begin(); - for(;it!=mListChild.end();++it) - { - delete *it; - } + std::vector::iterator it = mListChild.begin(); + for (; it != mListChild.end(); ++it) + { + delete *it; + } } - - - - - -- cgit v1.2.1