diff options
author | Aleksandar Donchev <Aleksander.Donchev@partner.bmw.de> | 2015-07-06 15:37:49 +0200 |
---|---|---|
committer | Christian Linke <christian.linke@bmw.de> | 2015-07-06 17:14:22 +0100 |
commit | f33da7d02a0f72fab903288f3c840e09f8fa5b3c (patch) | |
tree | 91ef42c2bd16b7fff3bae9003075d03f87d5169b | |
parent | 580a59d950152a3a6d9b7d6a2b29bd3a2e64fc0c (diff) | |
download | audiomanager-f33da7d02a0f72fab903288f3c840e09f8fa5b3c.tar.gz |
*Routing bug fixing and enhancment.
Signed-off-by:Christian Linke<christian.linke@bmw.de>
-rw-r--r-- | AudioManagerDaemon/include/CAmGraph.h | 5 | ||||
-rw-r--r-- | AudioManagerDaemon/include/CAmRouter.h | 323 | ||||
-rw-r--r-- | AudioManagerDaemon/src/CAmDatabaseHandlerMap.cpp | 2 | ||||
-rw-r--r-- | AudioManagerDaemon/src/CAmRouter.cpp | 1080 | ||||
-rw-r--r-- | AudioManagerDaemon/test/AmRouterMapTest/CAmRouterMapTest.cpp | 718 | ||||
-rw-r--r-- | AudioManagerDaemon/test/AmRouterMapTest/CAmRouterMapTest.h | 9 | ||||
-rw-r--r-- | AudioManagerDaemon/test/CMakeLists.txt | 5 |
7 files changed, 1063 insertions, 1079 deletions
diff --git a/AudioManagerDaemon/include/CAmGraph.h b/AudioManagerDaemon/include/CAmGraph.h index b258d9f..ff4a09c 100644 --- a/AudioManagerDaemon/include/CAmGraph.h +++ b/AudioManagerDaemon/include/CAmGraph.h @@ -323,6 +323,11 @@ namespace am return mStoreNodes; } + const CAmVertexReferenceList & getVertexList() const + { + return mPointersAdjList; + } + /** * Returns pointer to a node which data is equal to the given. * @return pointer to a node or NULL. diff --git a/AudioManagerDaemon/include/CAmRouter.h b/AudioManagerDaemon/include/CAmRouter.h index afd36b1..fe41049 100644 --- a/AudioManagerDaemon/include/CAmRouter.h +++ b/AudioManagerDaemon/include/CAmRouter.h @@ -27,6 +27,7 @@ #include <assert.h> #include <vector> +#include <functional> #include "audiomanagertypes.h" #include "CAmGraph.h" #include "IAmDatabaseHandler.h" @@ -36,22 +37,32 @@ namespace am { /** * Optimal path search between a source and a sink is implemented with a graph which contains nodes - sinks, sources, gateways, converters. - * - * If EXTENDED_ROUTING_GRAPH is defined the graph will contain nodes, which are identified by sinkID, sourceID, gatewayID, converterID and connectionFormat. - * All possible connections between all nodes (1 connection is 1 connection format) are represented in the graph (Node[id=1, connectionFormat=1] ---> Node[id=2, connectionFormat=1]). - * - * If EXTENDED_ROUTING_GRAPH is NOT defined the graph will contain nodes, which are identified by sinkID, sourceID, gatewayID, converterID. + * The nodes are identified by sinkID, sourceID, gatewayID, converterID. * A possible connection between two nodes represents the facts that the nodes can be connected with one or more connectionFormats (Node[id=1] ---> Node[id=2]). - * It is assumption that the two nodes can be connected. The controller itself decides later whether the connection is possible or not. This is default. + * It is assumption that the two nodes can be connected. The controller itself decides later whether the connection is possible or not. * */ -#undef EXTENDED_ROUTING_GRAPH /** * Trace on/off. */ -#undef TRACE_GRAPH +#if !defined(ROUTING_BUILD_CONNECTIONS) + #undef TRACE_GRAPH +#endif + +/** + * Default behavior is to do the search in one step without connections, which are identified during the search. + * Alternatively the search can be done in two steps. + */ +#if !defined(ROUTING_BUILD_CONNECTIONS) + #undef ROUTING_BUILD_CONNECTIONS +#endif +#if defined(TRACE_GRAPH) +#if !defined(ROUTING_BUILD_CONNECTIONS) +#warning "You should define ROUTING_BUILD_CONNECTIONS in order to be able to see the connections in the trace." +#endif +#endif class CAmRouter; @@ -62,10 +73,6 @@ struct am_RoutingNodeData_s { typedef enum:uint8_t {SINK, SOURCE, GATEWAY, CONVERTER} am_NodeDataType_e; am_NodeDataType_e type; //!< data type:sink, source, gateway or converter -#ifdef EXTENDED_ROUTING_GRAPH - am_CustomConnectionFormat_t inConnectionFormat; //!< input connection format for sink, source, gateway or converter - am_CustomConnectionFormat_t outConnectionFormat; //!< output connection format usually for gateways and converters -#endif union { am_Source_s *source; @@ -75,22 +82,14 @@ struct am_RoutingNodeData_s } data; //!< union pointer to sink, source, gateway or converter am_RoutingNodeData_s():type(SINK) -#ifdef EXTENDED_ROUTING_GRAPH - ,inConnectionFormat(CF_UNKNOWN) - ,outConnectionFormat(CF_UNKNOWN) -#endif {} bool operator==(const am_RoutingNodeData_s & anotherObject) const - { + { bool result = false; if(type==anotherObject.type) { -#ifdef EXTENDED_ROUTING_GRAPH - result = (inConnectionFormat==anotherObject.inConnectionFormat && outConnectionFormat==anotherObject.outConnectionFormat); -#else result = true; -#endif if(type==SINK) result &= (data.sink->sinkID==anotherObject.data.sink->sinkID); else if(type==SOURCE) @@ -101,41 +100,46 @@ struct am_RoutingNodeData_s result &= (data.converter->converterID==anotherObject.data.converter->converterID); } return result; - }; + }; #ifdef TRACE_GRAPH void trace() const { if(type==SINK) - std::cout << "[SINK:" << data.sink->sinkID << ":" << data.sink->name -#ifdef EXTENDED_ROUTING_GRAPH - << "(" << inConnectionFormat << "," << outConnectionFormat << ")" -#endif - << "]"; + std::cout << "[SINK:" << data.sink->sinkID << ":" << data.sink->name << "(" << data.sink->domainID << ")" + << "]"; else if(type==SOURCE) - std::cout << "[SOUR:" << data.source->sourceID << ":" << data.source->name -#ifdef EXTENDED_ROUTING_GRAPH - << "(" << inConnectionFormat << "," << outConnectionFormat << ")" -#endif - << "]"; + std::cout << "[SOUR:" << data.source->sourceID << ":" << data.source->name << "(" << data.source->domainID << ")" + << "]"; else if(type==GATEWAY) - std::cout << "[GATE:" << data.gateway->gatewayID << ":" << data.gateway->name -#ifdef EXTENDED_ROUTING_GRAPH - << "(" << inConnectionFormat << "," << outConnectionFormat << ")" -#endif - << "]"; + std::cout << "[GATE:" << data.gateway->gatewayID << ":" << data.gateway->name << "(" << data.gateway->controlDomainID << ")" + << "]"; else if(type==CONVERTER) - std::cout << "[CONV:" << data.converter->converterID << ":" << data.converter->name -#ifdef EXTENDED_ROUTING_GRAPH - << "(" << inConnectionFormat << "," << outConnectionFormat << ")" -#endif - << "]"; + std::cout << "[CONV:" << data.converter->converterID << ":" << data.converter->name << "(" << data.converter->domainID << ")" + << "]"; }; #endif -}; -#define NodeDataType am_RoutingNodeData_s::am_NodeDataType_e + am_domainID_t domainID() const + { + if(type==SINK) + return data.sink->domainID; + else if(type==SOURCE) + return data.source->domainID; + else if(type==GATEWAY) + return data.gateway->controlDomainID; + else if(type==CONVERTER) + return data.converter->domainID; + return 0; + }; +}; +typedef am_RoutingNodeData_s::am_NodeDataType_e CAmNodeDataType; +typedef CAmNode<am_RoutingNodeData_s> CAmRoutingNode; +typedef CAmGraph<am_RoutingNodeData_s, uint16_t> CAmRoutingGraph; +typedef CAmVertex<am_RoutingNodeData_s, uint16_t> CAmRoutingVertex; +typedef std::list<CAmRoutingVertex> CAmRoutingListVertices; +typedef std::vector<CAmRoutingListVertices*> CAmRoutingVertexReferenceList; class CAmControlSender; @@ -148,124 +152,87 @@ class CAmRouter IAmDatabaseHandler* mpDatabaseHandler; //!< pointer to database handler CAmControlSender* mpControlSender; //!< pointer the controlsender - is used to retrieve information for the optimal route bool mOnlyFreeConversionNodes; //!< bool flag whether only disconnected elements should be considered or not - CAmGraph<am_RoutingNodeData_s, uint16_t> mRoutingGraph; //!< graph object - std::vector<CAmNode<am_RoutingNodeData_s>*> mNodeListSources; //!< vector with pointers to nodes with sources, used for quick access - std::vector<CAmNode<am_RoutingNodeData_s>*> mNodeListSinks; //!< vector with pointers to nodes with sinks, used for quick access - std::vector<CAmNode<am_RoutingNodeData_s>*> mNodeListGateways; //!< vector with pointers to nodes with gateways, used for quick access - std::vector<CAmNode<am_RoutingNodeData_s>*> mNodeListConverters;//!< vector with pointers to nodes with converters, used for quick access -#ifdef EXTENDED_ROUTING_GRAPH - am_Source_s *mpRootSource; //!< pointer to source - am_Sink_s *mpRootSink; //!< pointer to sink - - /* - * Methods for getting shortest path from the graph. - */ - void getShortestPath(const am_Source_s & aSource, const am_Sink_s & aSink, std::vector<std::vector<CAmNode<am_RoutingNodeData_s>*>> & resultPath); - void getShortestPath(std::vector<std::vector<CAmNode<am_RoutingNodeData_s>*>> & resultPath); - void 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); - void getShortestPath(std::vector<am_Route_s> & routes, std::vector<std::vector<CAmNode<am_RoutingNodeData_s>*>> & nodes); + CAmRoutingGraph mRoutingGraph; //!< graph object + std::map<am_domainID_t,std::vector<CAmRoutingNode*>> mNodeListSources; //!< map with pointers to nodes with sources, used for quick access + std::map<am_domainID_t,std::vector<CAmRoutingNode*>> mNodeListSinks; //!< map with pointers to nodes with sinks, used for quick access + std::map<am_domainID_t,std::vector<CAmRoutingNode*>> mNodeListGateways; //!< map with pointers to nodes with gateways, used for quick access + std::map<am_domainID_t,std::vector<CAmRoutingNode*>> mNodeListConverters;//!< map with pointers to nodes with converters, used for quick access + + am_Error_e determineConnectionFormatsForPath(am_Route_s & routeObjects, std::vector<CAmRoutingNode*> & nodes); + am_Error_e doConnectionFormatsForPath(am_Route_s & routeObjects, + std::vector<CAmRoutingNode*> & route, + std::vector<am_RoutingElement_s>::iterator routingElementIterator, + std::vector<CAmRoutingNode*>::iterator routeIterator); + /** - * Returns a sink node with given sinkID and connection format. + * Check whether given converter or gateway has been connected. * - * @param sinkID sink id. - * @param connectionFormat connection format. - * @return pointer to node or NULL. + * @param comp converter or gateway . */ - - CAmNode<am_RoutingNodeData_s>* sinkNodeWithID(const am_sinkID_t sinkID, const am_CustomConnectionFormat_t connectionFormat); + template <class Component> bool isComponentConnected(const Component & comp) + { + return mpDatabaseHandler->isComponentConnected(comp); + } + void generateAllPaths(const CAmRoutingNode & src, + const CAmRoutingNode & dst, + const bool includeCycles, + std::function<void(const std::vector<CAmRoutingNode*> & path)> cb); + void goThroughAllPaths(const CAmRoutingNode & dst, + std::vector<CAmRoutingNode*> & visited, + std::vector<am_domainID_t> & visitedDomains, + std::function<void(const std::vector<CAmRoutingNode*> & path)> cb); + +#ifdef ROUTING_BUILD_CONNECTIONS /** - * Returns a source node with given sourceID and connection format. + * Connects all converters to its sink and sources if possible. * - * @param sourceID source id. - * @param connectionFormat connection format. - * @return pointer to node or NULL. */ - CAmNode<am_RoutingNodeData_s>* sourceNodeWithID(const am_sourceID_t sourceID, const am_CustomConnectionFormat_t connectionFormat); -#else - CAmNode<am_RoutingNodeData_s> *mpRootSource; //!< pointer to source node - CAmNode<am_RoutingNodeData_s> *mpRootSink; //!< pointer to sink node - - am_Error_e determineConnectionFormatsForPath(am_Route_s & routeObjects, std::vector<CAmNode<am_RoutingNodeData_s>*> & nodes); - am_Error_e doConnectionFormatsForPath(am_Route_s & routeObjects, - std::vector<CAmNode<am_RoutingNodeData_s>*> & route, - std::vector<am_RoutingElement_s>::iterator routingElementIterator, - std::vector<CAmNode<am_RoutingNodeData_s>*>::iterator routeIterator); - void getShortestPath(const CAmNode<am_RoutingNodeData_s> & source, - const CAmNode<am_RoutingNodeData_s> & destination, - std::vector<CAmNode<am_RoutingNodeData_s>*> & resultPath); - void getShortestPath(std::vector<CAmNode<am_RoutingNodeData_s>*> & resultPath); - void getShortestPath(CAmNode<am_RoutingNodeData_s> & aSource, CAmNode<am_RoutingNodeData_s> & aSink, - am_Route_s & resultPath, std::vector<CAmNode<am_RoutingNodeData_s>*> & resultNodesPath); - void getShortestPath(am_Route_s & resultPath, std::vector<CAmNode<am_RoutingNodeData_s>*> & resultNodesPath); - am_Error_e 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); - am_Error_e getAllPaths(std::vector<am_Route_s> & resultPath, std::vector<std::vector<CAmNode<am_RoutingNodeData_s>*>> & resultNodesPath); + void constructConverterConnections(); /** - * Returns a sink node with given sinkID. + * Connects all gateways to its sink and sources if possible. * - * @param sinkID sink id. - * @return pointer to node or NULL. */ - CAmNode<am_RoutingNodeData_s>* sinkNodeWithID(const am_sinkID_t sinkID); + void constructGatewayConnections(); /** - * Returns a source node with given sourceID. + * Connects all sources to the sinks if possible. * - * @param sourceID source id. - * @return pointer to node or NULL. */ - CAmNode<am_RoutingNodeData_s>* sourceNodeWithID(const am_sourceID_t sourceID); -#endif + void constructSourceSinkConnections(); +#else + /** + * Construct a list with all vertices + */ + void getVerticesForNode(const CAmRoutingNode & node, CAmRoutingListVertices & list); /** - * Makes connection between two nodes. - * - * @param node1. - * @param node2. - * @param vertexData associated data. - * @param weight connection weight used for finding optimal path. + * Construct a list with all vertices from given source. */ - void connectNodes(const CAmNode<am_RoutingNodeData_s> & node1, - const CAmNode<am_RoutingNodeData_s> & node2, - const am_CustomConnectionFormat_t vertexData, - const int16_t weight = 1); + void getVerticesForSource(const CAmRoutingNode & node, CAmRoutingListVertices & list); + /** - * Builds path in a domain from source to sink. - * - * @param aSource starting point. - * @param aSink ending point. + * Construct a list with all vertices from given sink. */ - bool routeInSameDomain(CAmNode<am_RoutingNodeData_s> & aSource, CAmNode<am_RoutingNodeData_s> & aSink); + void getVerticesForSink(const CAmRoutingNode & node, CAmRoutingListVertices & list); /** - * Builds path from source to sink when the source and the sink belongs to different domains. - * - * @param aSource starting point. - * @param aSink ending point. + * Construct a list with all vertices from given converter. */ - bool routeInAnotherDomain(CAmNode<am_RoutingNodeData_s> & aSource, CAmNode<am_RoutingNodeData_s> & aSink); - void clear(); + void getVerticesForConverter(const CAmRoutingNode & node, CAmRoutingListVertices & list); /** - * Fills the graph with nodes and connections. - * - * @param aSource starting point. - * @param aSink ending point. + * Construct a list with all vertices from given gateway. */ - void buildGraph(const am_Source_s & aSource, const am_Sink_s & aSink); - template <class Component> bool isComponentConnected(const Component & comp) - { - return mpDatabaseHandler->isComponentConnected(comp); - } + void getVerticesForGateway(const CAmRoutingNode & node, CAmRoutingListVertices & list); +#endif public: - CAmRouter(IAmDatabaseHandler* iDatabaseHandler, CAmControlSender* iSender); - ~CAmRouter(); + CAmRouter(IAmDatabaseHandler* iDatabaseHandler, CAmControlSender* iSender); + ~CAmRouter(); - /** + /** * Finds all possible paths between given source and sink. * * @param onlyfree only disconnected elements should be included or not. @@ -274,29 +241,77 @@ public: * @param returnList list with all possible paths * @return E_OK on success(0 or more paths) or E_NOT_POSSIBLE on failure. */ - am_Error_e getRoute(const bool onlyfree, const am_sourceID_t sourceID, const am_sinkID_t sinkID, std::vector<am_Route_s>& returnList); - am_Error_e getRoute(const bool onlyfree, const am_Source_s & aSource, const am_Sink_s & aSink, std::vector<am_Route_s> & listRoutes); - - /** - * Helper methods. - */ - static bool 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); - static bool 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); - - static void listPossibleConnectionFormats(std::vector<am_CustomConnectionFormat_t> & inListSourceFormats, - std::vector<am_CustomConnectionFormat_t> & inListSinkFormats, - std::vector<am_CustomConnectionFormat_t> & outConnectionFormats); -}; + am_Error_e getRoute(const bool onlyfree, const am_sourceID_t sourceID, const am_sinkID_t sinkID, std::vector<am_Route_s>& returnList); + am_Error_e getRoute(const bool onlyfree, const am_Source_s & aSource, const am_Sink_s & aSink, std::vector<am_Route_s> & listRoutes); + + am_Error_e getAllPaths(CAmRoutingNode & aSource, CAmRoutingNode & aSink, + std::vector<am_Route_s> & resultPath, std::vector<std::vector<CAmRoutingNode*>> & resultNodesPath, +#if !defined(ROUTING_BUILD_CONNECTIONS) + __attribute__((unused)) +#endif + const bool includeCycles = false); +#ifdef ROUTING_BUILD_CONNECTIONS + void getShortestPath(const CAmRoutingNode & source, const CAmRoutingNode & destination, std::vector<CAmRoutingNode*> & resultPath); + void getShortestPath(CAmRoutingNode & aSource, CAmRoutingNode & aSink, am_Route_s & resultPath, std::vector<CAmRoutingNode*> & resultNodesPath); +#endif + static bool 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); + static void listPossibleConnectionFormats(std::vector<am_CustomConnectionFormat_t> & inListSourceFormats, + std::vector<am_CustomConnectionFormat_t> & inListSinkFormats, + std::vector<am_CustomConnectionFormat_t> & outListFormats); + static bool 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); + static void getSourceSinkPossibleConnectionFormats(std::vector<CAmRoutingNode*>::iterator iteratorSource, + std::vector<CAmRoutingNode*>::iterator iteratorSink, + std::vector<am_CustomConnectionFormat_t> & outConnectionFormats); + + static bool shouldGoInDomain(const std::vector<am_domainID_t> & visitedDomains, const am_domainID_t nodeDomainID); + /** + * Returns a sink node with given sinkID. + * + * @param sinkID sink id. + * @return pointer to node or NULL. + */ + CAmRoutingNode* sinkNodeWithID(const am_sinkID_t sinkID); + CAmRoutingNode* sinkNodeWithID(const am_sinkID_t sinkID, const am_domainID_t domainID); + + /** + * Returns a source node with given sourceID. + * + * @param sourceID source id. + * @return pointer to node or NULL. + */ + CAmRoutingNode* sourceNodeWithID(const am_sourceID_t sourceID); + CAmRoutingNode* sourceNodeWithID(const am_sourceID_t sourceID, const am_domainID_t domainID); + + /** + * Returns a converter node for given sinkID. + * + * @param sinkID sink id. + * @param domainID domain id. + * @return pointer to node or NULL. + */ + CAmRoutingNode* converterNodeWithSinkID(const am_sinkID_t sinkID, const am_domainID_t domainID); + + /** + * Returns a gateway node for given sinkID. + * + * @param sinkID sink id. + * @return pointer to node or NULL. + */ + CAmRoutingNode* gatewayNodeWithSinkID(const am_sinkID_t sinkID); + + void load(const bool onlyFree); + void clear(); +}; } /* namespace am */ #endif /* ROUTER_H_ */ diff --git a/AudioManagerDaemon/src/CAmDatabaseHandlerMap.cpp b/AudioManagerDaemon/src/CAmDatabaseHandlerMap.cpp index 3f031ff..46163db 100644 --- a/AudioManagerDaemon/src/CAmDatabaseHandlerMap.cpp +++ b/AudioManagerDaemon/src/CAmDatabaseHandlerMap.cpp @@ -794,7 +794,7 @@ am_Error_e CAmDatabaseHandlerMap::enterConverterDB(const am_Converter_s & conver if (converterData.converterID != 0 || mFirstStaticConverter) { //check if the ID already exists - if (existGateway(converterData.converterID)) + if (existConverter(converterData.converterID)) { converterID = converterData.converterID; return (E_ALREADY_EXISTS); diff --git a/AudioManagerDaemon/src/CAmRouter.cpp b/AudioManagerDaemon/src/CAmRouter.cpp index 30bb4c3..f98bf11 100644 --- a/AudioManagerDaemon/src/CAmRouter.cpp +++ b/AudioManagerDaemon/src/CAmRouter.cpp @@ -36,21 +36,6 @@ 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, @@ -76,9 +61,7 @@ CAmRouter::CAmRouter(IAmDatabaseHandler* iDatabaseHandler, CAmControlSender* iSe mNodeListSources(), mNodeListSinks(), mNodeListGateways(), - mNodeListConverters(), - mpRootSource(0), - mpRootSink(0) + mNodeListConverters() { assert(mpDatabaseHandler); assert(mpControlSender); @@ -101,130 +84,60 @@ am_Error_e CAmRouter::getRoute(const bool onlyfree, const am_sourceID_t sourceID returnList.clear(); am_Source_s source; am_Sink_s sink; - mpDatabaseHandler->getSourceInfoDB(sourceID, source); - mpDatabaseHandler->getSinkInfoDB(sinkID, sink); - return getRoute(onlyfree, source, sink, returnList); + am_Error_e error = mpDatabaseHandler->getSourceInfoDB(sourceID, source); + if(error!=E_OK) + return error; + error = mpDatabaseHandler->getSinkInfoDB(sinkID, sink); + if(error!=E_OK) + return error; + error = getRoute(onlyfree, source, sink, returnList); + return error; } -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) -{ - 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; -} - -void CAmRouter::listPossibleConnectionFormats(std::vector<am_CustomConnectionFormat_t> & inListSourceFormats, - std::vector<am_CustomConnectionFormat_t> & inListSinkFormats, - std::vector<am_CustomConnectionFormat_t> & outListFormats) -{ - 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); -} - - -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) +am_Error_e CAmRouter::getRoute(const bool onlyfree, const am_Source_s & aSource, const am_Sink_s & aSink, std::vector<am_Route_s> & listRoutes) { - listFormats.clear(); - 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(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); + am_Error_e error; + load(onlyfree); - //iterate line-wise through the matrix and add more formats - do - { - if (*matrixIterator) - { - listFormats.push_back(listSourceFormats.at((matrixIterator - convertionMatrix.begin()) / listSinkFormats.size())); - } - std::advance(matrixIterator, listSinkFormats.size()); - } while (convertionMatrix.end() - matrixIterator > 0); + CAmRoutingNode* pRootSource = sourceNodeWithID(aSource.sourceID); + CAmRoutingNode* pRootSink = sinkNodeWithID(aSink.sinkID); - return listFormats.size(); -} + assert(pRootSource); + assert(pRootSink); -#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)); - }); -} - -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) -{ +#ifdef TRACE_GRAPH + mRoutingGraph.trace([&](const CAmRoutingNode & node, const std::vector<CAmVertex<am_RoutingNodeData_s,uint16_t>*> & list) { + std::cout << "Node " << node.getIndex() << " :"; + ((CAmRoutingNode &)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 - 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)); - } - } + std::vector<std::vector<CAmRoutingNode*>> pathNodes; + error = getAllPaths(*pRootSource, *pRootSink, listRoutes, pathNodes); + return error; } -#endif -am_Error_e CAmRouter::getRoute(const bool onlyfree, const am_Source_s & aSource, const am_Sink_s & aSink, std::vector<am_Route_s> & listRoutes) +void CAmRouter::load(const bool onlyFree) { clear(); - mOnlyFreeConversionNodes = onlyfree; - // We need to copy the sinks, sources, converters, gateways for SQLite data store. + mOnlyFreeConversionNodes = onlyFree; + #if defined (WITH_DATABASE_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; #endif - am_Error_e error = E_OK; - am_RoutingNodeData_s nodeDataSrc; - nodeDataSrc.type = NodeDataType::SOURCE; + nodeDataSrc.type = CAmNodeDataType::SOURCE; mpDatabaseHandler->enumerateSources([&](const am_Source_s & obj){ #if defined (WITH_DATABASE_STORAGE) listSources.push_back(obj); @@ -232,14 +145,10 @@ am_Error_e CAmRouter::getRoute(const bool onlyfree, const am_Source_s & aSource, #else nodeDataSrc.data.source = (am_Source_s*)&obj; #endif -#ifdef EXTENDED_ROUTING_GRAPH - appendNodes(mRoutingGraph, obj.listConnectionFormats, nodeDataSrc, mNodeListSources); -#else - mNodeListSources.push_back(&mRoutingGraph.addNode(nodeDataSrc)); -#endif + mNodeListSources[nodeDataSrc.data.source->domainID].push_back(&mRoutingGraph.addNode(nodeDataSrc)); }); am_RoutingNodeData_s nodeDataSink; - nodeDataSink.type = NodeDataType::SINK; + nodeDataSink.type = CAmNodeDataType::SINK; mpDatabaseHandler->enumerateSinks([&](const am_Sink_s & obj){ #if defined (WITH_DATABASE_STORAGE) listSinks.push_back(obj); @@ -247,14 +156,10 @@ am_Error_e CAmRouter::getRoute(const bool onlyfree, const am_Source_s & aSource, #else nodeDataSink.data.sink = (am_Sink_s*)&obj; #endif -#ifdef EXTENDED_ROUTING_GRAPH - appendNodes(mRoutingGraph, obj.listConnectionFormats, nodeDataSink, mNodeListSinks); -#else - mNodeListSinks.push_back(&mRoutingGraph.addNode(nodeDataSink)); -#endif + mNodeListSinks[nodeDataSink.data.sink->domainID].push_back(&mRoutingGraph.addNode(nodeDataSink)); }); am_RoutingNodeData_s nodeDataGateway; - nodeDataGateway.type = NodeDataType::GATEWAY; + nodeDataGateway.type = CAmNodeDataType::GATEWAY; mpDatabaseHandler->enumerateGateways([&](const am_Gateway_s & obj){ #if defined (WITH_DATABASE_STORAGE) listGateways.push_back(obj); @@ -262,14 +167,10 @@ am_Error_e CAmRouter::getRoute(const bool onlyfree, const am_Source_s & aSource, #else nodeDataGateway.data.gateway = (am_Gateway_s*)&obj; #endif -#ifdef EXTENDED_ROUTING_GRAPH - appendNodes(mRoutingGraph, obj.listSourceFormats, obj.listSinkFormats, obj.convertionMatrix, nodeDataGateway, mNodeListGateways); -#else - mNodeListGateways.push_back(&mRoutingGraph.addNode(nodeDataGateway)); -#endif + mNodeListGateways[nodeDataGateway.data.gateway->controlDomainID].push_back(&mRoutingGraph.addNode(nodeDataGateway)); }); am_RoutingNodeData_s nodeDataConverter; - nodeDataConverter.type = NodeDataType::CONVERTER; + nodeDataConverter.type = CAmNodeDataType::CONVERTER; mpDatabaseHandler->enumerateConverters([&](const am_Converter_s & obj){ #if defined (WITH_DATABASE_STORAGE) listConverters.push_back(obj); @@ -277,543 +178,356 @@ am_Error_e CAmRouter::getRoute(const bool onlyfree, const am_Source_s & aSource, #else nodeDataConverter.data.converter = (am_Converter_s*)&obj; #endif -#ifdef EXTENDED_ROUTING_GRAPH - appendNodes(mRoutingGraph, obj.listSourceFormats, obj.listSinkFormats, obj.convertionMatrix, nodeDataConverter, mNodeListConverters); -#else - mNodeListConverters.push_back(&mRoutingGraph.addNode(nodeDataConverter)); -#endif + mNodeListConverters[nodeDataConverter.data.converter->domainID].push_back(&mRoutingGraph.addNode(nodeDataConverter)); }); - 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); +#ifdef ROUTING_BUILD_CONNECTIONS + constructConverterConnections(); + constructGatewayConnections(); + constructSourceSinkConnections(); #endif - return error; } -void CAmRouter::buildGraph( const am_Source_s & aSource, const am_Sink_s & aSink) +void CAmRouter::clear() { - //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); + mRoutingGraph.clear(); + mNodeListSources.clear(); + mNodeListSinks.clear(); + mNodeListGateways.clear(); + mNodeListConverters.clear(); +} - if(aSource.domainID==aSink.domainID) - { - routeInSameDomain(*mpRootSource, *mpRootSink); - } - else +CAmRoutingNode* CAmRouter::sinkNodeWithID(const am_sinkID_t sinkID) +{ + CAmRoutingNode* result = NULL; + for(auto it = mNodeListSinks.begin(); it!=mNodeListSinks.end(); it++) { - routeInAnotherDomain(*mpRootSource, *mpRootSink); + result = sinkNodeWithID(sinkID, it->first); + if(result) + return result; } -#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 + return result; } -#ifdef EXTENDED_ROUTING_GRAPH -CAmNode<am_RoutingNodeData_s>* CAmRouter::sinkNodeWithID(const am_sinkID_t sinkID, const am_CustomConnectionFormat_t connectionFormat) +CAmRoutingNode* CAmRouter::sinkNodeWithID(const am_sinkID_t sinkID, const am_domainID_t domainID) { - 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; + CAmRoutingNode* result = NULL; + std::vector<CAmRoutingNode*> & value = mNodeListSinks[domainID]; + auto iter = std::find_if(value.begin(), value.end(), [sinkID](CAmRoutingNode* node){ + return node->getData().data.sink->sinkID==sinkID; }); - if(iter!=mNodeListSinks.end()) - return *iter; - return NULL; + if(iter!=value.end()) + result = *iter; + return result; } -CAmNode<am_RoutingNodeData_s>* CAmRouter::sourceNodeWithID(const am_sourceID_t sourceID, const am_CustomConnectionFormat_t connectionFormat) +CAmRoutingNode* CAmRouter::sourceNodeWithID(const am_sourceID_t sourceID) { - 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; + CAmRoutingNode* result = NULL; + for(auto it = mNodeListSources.begin(); it!=mNodeListSources.end(); it++) + { + result = sourceNodeWithID(sourceID, it->first); + if(result) + return result; + } + return result; } -#else -CAmNode<am_RoutingNodeData_s>* CAmRouter::sinkNodeWithID(const am_sinkID_t sinkID) + +CAmRoutingNode* CAmRouter::sourceNodeWithID(const am_sourceID_t sourceID, const am_domainID_t domainID) { - auto iter = std::find_if(mNodeListSinks.begin(), mNodeListSinks.end(), [sinkID](CAmNode<am_RoutingNodeData_s>* node){ - return node->getData().data.sink->sinkID==sinkID; + CAmRoutingNode* result = NULL; + std::vector<CAmRoutingNode*> & value = mNodeListSources[domainID]; + auto iter = std::find_if(value.begin(), value.end(), [sourceID](CAmRoutingNode* node){ + return node->getData().data.source->sourceID==sourceID; }); - if(iter!=mNodeListSinks.end()) - return *iter; - return NULL; + if(iter!=value.end()) + result = *iter; + return result; } -CAmNode<am_RoutingNodeData_s>* CAmRouter::sourceNodeWithID(const am_sourceID_t sourceID) +CAmRoutingNode* CAmRouter::converterNodeWithSinkID(const am_sinkID_t sinkID, const am_domainID_t domainID) { - auto iter = std::find_if(mNodeListSources.begin(), mNodeListSources.end(), [sourceID](CAmNode<am_RoutingNodeData_s>* node){ - return node->getData().data.source->sourceID==sourceID; + CAmRoutingNode* result = NULL; + std::vector<CAmRoutingNode*> & value = mNodeListConverters[domainID]; + auto iter = std::find_if(value.begin(), value.end(), [sinkID](CAmRoutingNode* node){ + return node->getData().data.converter->sinkID==sinkID; }); - if(iter!=mNodeListSources.end()) - return *iter; - return NULL; + if(iter!=value.end()) + result = *iter; + return result; } -#endif -void CAmRouter::connectNodes(const CAmNode<am_RoutingNodeData_s> & node1, - const CAmNode<am_RoutingNodeData_s> & node2, - const am_CustomConnectionFormat_t vertexData, - const int16_t weight) +CAmRoutingNode* CAmRouter::gatewayNodeWithSinkID(const am_sinkID_t sinkID) { - if( !mRoutingGraph.isAnyVertex(node1, node2) ) - mRoutingGraph.connectNodes(node1, node2, vertexData, weight); + for(auto it = mNodeListGateways.begin(); it!=mNodeListGateways.end(); it++) + { + std::vector<CAmRoutingNode*> & value = it->second; + auto iter = std::find_if(value.begin(), value.end(), [sinkID](CAmRoutingNode* node){ + return node->getData().data.gateway->sinkID==sinkID; + }); + if(iter!=value.end()) + return *iter; + } + return NULL; } -bool CAmRouter::routeInSameDomain(CAmNode<am_RoutingNodeData_s> & aSource, CAmNode<am_RoutingNodeData_s> & aSink) +#ifdef ROUTING_BUILD_CONNECTIONS + +void CAmRouter::constructSourceSinkConnections() { - 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( aSource.getStatus()!=GES_NOT_VISITED ) - return false; - bool result = false; - aSource.setStatus(GES_IN_PROGRESS); -#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 + std::vector<am_CustomConnectionFormat_t> intersection; + for(auto itSrc = mNodeListSources.begin(); itSrc!=mNodeListSources.end(); itSrc++) { -#endif - bool availableConverter = false; - for(auto iter = mNodeListConverters.begin(); iter!=mNodeListConverters.end(); iter++) + for(auto it = itSrc->second.begin(); it!=itSrc->second.end(); it++) { - 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( converterNode->getStatus()==GES_NOT_VISITED && converter->domainID==source->domainID && (!mOnlyFreeConversionNodes || !isComponentConnected(*converter))) + CAmRoutingNode* srcNode = *it; + am_RoutingNodeData_s & srcNodeData = srcNode->getData(); + am_Source_s * source = srcNodeData.data.source; + for(auto itSink = mNodeListSinks[itSrc->first].begin(); itSink!=mNodeListSinks[itSrc->first].end(); itSink++) { - //Get the sink connected to the converter... - converterNode->setStatus(GES_IN_PROGRESS); -#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) + CAmRoutingNode* sinkNode = *itSink; + am_RoutingNodeData_s & sinkNodeData = sinkNode->getData(); + am_Sink_s * sink = sinkNodeData.data.sink; + + intersection.clear(); + //Check whether the hidden sink formats match the source formats... + listPossibleConnectionFormats(source->listConnectionFormats, sink->listConnectionFormats, intersection); + if(intersection.size()>0)//OK match source -> sink { - 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 + mRoutingGraph.connectNodes(*srcNode, *sinkNode, CF_UNKNOWN, 1); } - converterNode->setStatus(GES_NOT_VISITED); } } - if(!availableConverter) - { - aSource.setStatus(GES_NOT_VISITED); - 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; } - aSource.setStatus(GES_NOT_VISITED); - return result; } -bool CAmRouter::routeInAnotherDomain(CAmNode<am_RoutingNodeData_s> & aSource, CAmNode<am_RoutingNodeData_s> & aSink) +void CAmRouter::constructGatewayConnections() { - 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( aSource.getStatus()!=GES_NOT_VISITED ) - return false; - aSource.setStatus(GES_IN_PROGRESS); -#ifndef EXTENDED_ROUTING_GRAPH - std::vector<am_CustomConnectionFormat_t> sourceFormats, sinkFormats, intersection; -#endif - bool result = false; + std::vector<am_CustomConnectionFormat_t> sourceFormats, sinkFormats; 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( - gatewayNode->getStatus()==GES_NOT_VISITED && - gateway->domainSinkID==source->domainID && - (!mOnlyFreeConversionNodes || !isComponentConnected(*gateway)) ) + for(auto it = iter->second.begin(); it!=iter->second.end(); it++) { - //Get the sink connected to the gateway... - gatewayNode->setStatus(GES_IN_PROGRESS); -#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) + CAmRoutingNode* gatewayNode = *it; + am_RoutingNodeData_s & gatewayNodeData = gatewayNode->getData(); + am_Gateway_s * gateway = gatewayNodeData.data.gateway; + //Get only gateways with end point in current source domain + if(!mOnlyFreeConversionNodes || !isComponentConnected(*gateway)) { - 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 + //Get the sink connected to the gateway... + CAmRoutingNode *gatewaySinkNode = this->sinkNodeWithID(gateway->sinkID, gateway->domainSinkID); + if(gatewaySinkNode) { - //the gateway is not suitable, lets try to find paths within this domains - bool alternResult = this->routeInSameDomain(aSource, *gatewaySinkNode); - if(alternResult) + am_RoutingNodeData_s & gatewaySinkData = gatewaySinkNode->getData(); + //Check whether the hidden sink formats match the source formats... + sourceFormats.clear(); + sinkFormats.clear(); + if(getAllowedFormatsFromConvMatrix(gateway->convertionMatrix, gateway->listSourceFormats, gateway->listSinkFormats, sourceFormats, sinkFormats)) { - CAmNode<am_RoutingNodeData_s> *gatewaySourceNode = this->sourceNodeWithID(gateway->sourceID, gatewayNodeData.outConnectionFormat); + CAmRoutingNode *gatewaySourceNode = this->sourceNodeWithID(gateway->sourceID, gateway->domainSourceID); 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); - } + //Connections hidden_sink->gateway->hidden_source + mRoutingGraph.connectNodes(*gatewaySinkNode, *gatewayNode, CF_UNKNOWN, 1); + mRoutingGraph.connectNodes(*gatewayNode, *gatewaySourceNode, CF_UNKNOWN, 1); } } } -#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 - aSource.setStatus(GES_NOT_VISITED); + } + } + } +} + +void CAmRouter::constructConverterConnections() +{ + std::vector<am_CustomConnectionFormat_t> sourceFormats, sinkFormats; - bool alternResult = this->routeInSameDomain(aSource, *gatewaySinkNode); - if(alternResult) + for(auto iter = mNodeListConverters.begin(); iter!=mNodeListConverters.end(); iter++) + { + for(auto it = iter->second.begin(); it!=iter->second.end(); it++) + { + CAmRoutingNode* converterNode = *it; + am_RoutingNodeData_s & converterNodeData = converterNode->getData(); + am_Converter_s * converter = converterNodeData.data.converter; + //Get only converters with end point in current source domain + if(!mOnlyFreeConversionNodes || !isComponentConnected(*converter)) + { + //Get the sink connected to the converter... + CAmRoutingNode *converterSinkNode = this->sinkNodeWithID(converter->sinkID, converter->domainID); + if(converterSinkNode) + { + am_RoutingNodeData_s & converterSinkData = converterSinkNode->getData(); + //Check whether the hidden sink formats match the source formats... + sourceFormats.clear(); + sinkFormats.clear(); + if(getAllowedFormatsFromConvMatrix(converter->convertionMatrix, converter->listSourceFormats, converter->listSinkFormats, sourceFormats, sinkFormats)) { - if(CAmRouter::getAllowedFormatsFromConvMatrix(gateway->convertionMatrix, gateway->listSourceFormats, gateway->listSinkFormats, sourceFormats, sinkFormats)) + CAmRoutingNode *converterSourceNode = this->sourceNodeWithID(converter->sourceID, converter->domainID); + if(converterSourceNode) { - 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); + //Connections hidden_sink->converter->hidden_source + mRoutingGraph.connectNodes(*converterSinkNode, *converterNode, CF_UNKNOWN, 1); + mRoutingGraph.connectNodes(*converterNode, *converterSourceNode, CF_UNKNOWN, 1); } } } -#endif } - gatewayNode->setStatus(GES_NOT_VISITED); } } - aSource.setStatus(GES_NOT_VISITED); - return result; } +#else -#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) +void CAmRouter::getVerticesForSource(const CAmRoutingNode & node, CAmRoutingListVertices & list) { - 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) + am_RoutingNodeData_s & srcNodeData = ((CAmRoutingNode*)&node)->getData(); + std::vector<am_CustomConnectionFormat_t> intersection; + am_Source_s * source = srcNodeData.data.source; + std::vector<CAmRoutingNode*> & sinks = mNodeListSinks[source->domainID]; + for(auto itSink = sinks.begin(); itSink!=sinks.end(); itSink++) { - if(pos==GRAPH_PATH_START) + CAmRoutingNode* sinkNode = *itSink; + am_RoutingNodeData_s & sinkNodeData = sinkNode->getData(); + am_Sink_s * sink = sinkNodeData.data.sink; + + intersection.clear(); + //Check whether the hidden sink formats match the source formats... + listPossibleConnectionFormats(source->listConnectionFormats, sink->listConnectionFormats, intersection); + if(intersection.size()>0)//OK match source -> sink { - resultNodesPath.emplace_back(); - pathNodes=&resultNodesPath.back(); - resultPath.emplace_back(); - path= &resultPath.back(); - path->sinkID = aSink.sinkID; - path->sourceID = aSource.sourceID; + list.emplace_back(sinkNode, CF_UNKNOWN, 1); } - pathNodes->insert(pathNodes->begin(), (CAmNode<am_RoutingNodeData_s>*)&object); + } +} - am_RoutingNodeData_s & routingData = object.getData(); +void CAmRouter::getVerticesForSink(const CAmRoutingNode & node, CAmRoutingListVertices & list) +{ + am_RoutingNodeData_s & sinkNodeData = ((CAmRoutingNode*)&node)->getData(); + std::vector<am_CustomConnectionFormat_t> intersection; + am_Sink_s * sink = sinkNodeData.data.sink; - if(routingData.type==am_RoutingNodeData_s::am_NodeDataType_e::SINK) + CAmRoutingNode *converterNode = converterNodeWithSinkID(sink->sinkID, sink->domainID); + if(converterNode) + { + std::vector<am_CustomConnectionFormat_t> sourceFormats, sinkFormats; + am_RoutingNodeData_s & converterData = converterNode->getData(); + am_Converter_s * converter = converterData.data.converter; + if(!mOnlyFreeConversionNodes || !isComponentConnected(*converter)) { - 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; - + if(getAllowedFormatsFromConvMatrix(converter->convertionMatrix, converter->listSourceFormats, converter->listSinkFormats, sourceFormats, sinkFormats)) + list.emplace_back(converterNode, CF_UNKNOWN, 1); } - else if(routingData.type==am_RoutingNodeData_s::am_NodeDataType_e::SOURCE) + } + else + { + std::vector<am_CustomConnectionFormat_t> sourceFormats, sinkFormats; + CAmRoutingNode *gatewayNode = gatewayNodeWithSinkID(sink->sinkID); + if(gatewayNode) { - element->domainID = routingData.data.source->domainID; - element->sourceID = routingData.data.source->sourceID; - element->connectionFormat = routingData.inConnectionFormat; + std::vector<am_CustomConnectionFormat_t> sourceFormats, sinkFormats; + am_RoutingNodeData_s & gatewayData = gatewayNode->getData(); + am_Gateway_s * gateway = gatewayData.data.gateway; + if(!mOnlyFreeConversionNodes || !isComponentConnected(*gateway)) + { + if(getAllowedFormatsFromConvMatrix(gateway->convertionMatrix, gateway->listSourceFormats, gateway->listSinkFormats, sourceFormats, sinkFormats)) + list.emplace_back(gatewayNode, CF_UNKNOWN, 1); + } } - }; + } +} - 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()) +void CAmRouter::getVerticesForConverter(const CAmRoutingNode & node, CAmRoutingListVertices & list) +{ + std::vector<am_CustomConnectionFormat_t> sourceFormats, sinkFormats; + am_RoutingNodeData_s & converterNodeData = ((CAmRoutingNode*)&node)->getData(); + am_Converter_s * converter = converterNodeData.data.converter; + //Get only converters with end point in current source domain + if(getAllowedFormatsFromConvMatrix(converter->convertionMatrix, converter->listSourceFormats, converter->listSinkFormats, sourceFormats, sinkFormats)) { - for(auto it1=aSource.listConnectionFormats.begin(); it1!=aSource.listConnectionFormats.end(); it1++) + CAmRoutingNode *converterSourceNode = this->sourceNodeWithID(converter->sourceID, converter->domainID); + if(converterSourceNode) { - am::CAmNode<am::am_RoutingNodeData_s>* pRootNodeSource = sourceNodeWithID(aSource.sourceID, *it1); - if(pRootNodeSource) - { - mRoutingGraph.getShortestPath(*pRootNodeSource, listTargets, cb); - } + list.emplace_back(converterSourceNode, CF_UNKNOWN, 1); } } } -void CAmRouter::getShortestPath(std::vector<am_Route_s> & routes, std::vector<std::vector<CAmNode<am_RoutingNodeData_s>*>> & nodes) +void CAmRouter::getVerticesForGateway(const CAmRoutingNode & node, CAmRoutingListVertices & list) { - getShortestPath(*mpRootSource, *mpRootSink, routes, nodes); + am_RoutingNodeData_s & gatewayNodeData = ((CAmRoutingNode*)&node)->getData(); + std::vector<am_CustomConnectionFormat_t> sourceFormats, sinkFormats; + am_Gateway_s * gateway = gatewayNodeData.data.gateway; + if(getAllowedFormatsFromConvMatrix(gateway->convertionMatrix, gateway->listSourceFormats, gateway->listSinkFormats, sourceFormats, sinkFormats)) + { + CAmRoutingNode *gatewaySourceNode = this->sourceNodeWithID(gateway->sourceID, gateway->domainSourceID); + if(gatewaySourceNode) + { + //Connections hidden_sink->gateway->hidden_source + list.emplace_back(gatewaySourceNode, CF_UNKNOWN, 1); + } + } } -void CAmRouter::getShortestPath(const am_Source_s & aSource, const am_Sink_s & aSink, - std::vector<std::vector<CAmNode<am_RoutingNodeData_s>*>> & resultPath) +void CAmRouter::getVerticesForNode( + const CAmRoutingNode & node, + CAmRoutingListVertices & list + ) { - std::vector<CAmNode<am_RoutingNodeData_s>*> listTargets; - for(auto it2=aSink.listConnectionFormats.begin(); it2!=aSink.listConnectionFormats.end(); it2++) + am_RoutingNodeData_s & nodeData = ((CAmRoutingNode*)&node)->getData(); + if(nodeData.type==CAmNodeDataType::SOURCE) { - am::CAmNode<am::am_RoutingNodeData_s>* pRootNodeSink = sinkNodeWithID(aSink.sinkID, *it2); - if(pRootNodeSink) - listTargets.push_back(pRootNodeSink); + getVerticesForSource(node, list); } - if(listTargets.size()) + else if(nodeData.type==CAmNodeDataType::SINK) { - 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); - } - } + getVerticesForSink(node, list); + } + else if(nodeData.type==CAmNodeDataType::CONVERTER) + { + getVerticesForConverter(node, list); + } + else if(nodeData.type==CAmNodeDataType::GATEWAY) + { + getVerticesForGateway(node, list); } } -#else -am_Error_e CAmRouter::determineConnectionFormatsForPath(am_Route_s & routeObjects, std::vector<CAmNode<am_RoutingNodeData_s>*> & nodes) +#endif + +am_Error_e CAmRouter::determineConnectionFormatsForPath(am_Route_s & routeObjects, std::vector<CAmRoutingNode*> & nodes) { std::vector<am_RoutingElement_s>::iterator routingElementIterator = routeObjects.route.begin(); - std::vector<CAmNode<am_RoutingNodeData_s>*>::iterator nodeIterator = nodes.begin(); + std::vector<CAmRoutingNode*>::iterator nodeIterator = nodes.begin(); if( routingElementIterator!= routeObjects.route.end() && nodeIterator!=nodes.end() ) return doConnectionFormatsForPath(routeObjects, nodes, routingElementIterator, nodeIterator); return E_OK; } am_Error_e CAmRouter::doConnectionFormatsForPath(am_Route_s & routeObjects, - std::vector<CAmNode<am_RoutingNodeData_s>*> & nodes, + std::vector<CAmRoutingNode*> & nodes, std::vector<am_RoutingElement_s>::iterator routingElementIterator, - std::vector<CAmNode<am_RoutingNodeData_s>*>::iterator nodeIterator) + std::vector<CAmRoutingNode*>::iterator nodeIterator) { 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<CAmRoutingNode*>::iterator currentNodeIterator = nodeIterator; std::vector<am_RoutingElement_s>::iterator currentRoutingElementIterator = routingElementIterator; if (currentRoutingElementIterator!=routeObjects.route.begin()) { std::vector<am_CustomConnectionFormat_t> listConnectionFormats; std::vector<am_RoutingElement_s>::iterator tempIterator = (currentRoutingElementIterator-1); - CAmNode<am_RoutingNodeData_s> * currentNode = *currentNodeIterator; + CAmRoutingNode * currentNode = *currentNodeIterator; getSourceSinkPossibleConnectionFormats(currentNodeIterator+1, currentNodeIterator+2, listConnectionFormats); - if(currentNode->getData().type==am_RoutingNodeData_s::am_NodeDataType_e::GATEWAY) + if(currentNode->getData().type==CAmNodeDataType::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) + else if(currentNode->getData().type==CAmNodeDataType::CONVERTER) { am_Converter_s *converter = currentNode->getData().data.converter; getMergeConnectionFormats(converter, tempIterator->connectionFormat, listConnectionFormats, listMergeConnectionFormats); @@ -822,18 +536,18 @@ am_Error_e CAmRouter::doConnectionFormatsForPath(am_Route_s & routeObjects, } else { - CAmNode<am_RoutingNodeData_s> * currentNode = *currentNodeIterator; - assert(currentNode->getData().type==am_RoutingNodeData_s::am_NodeDataType_e::SOURCE); + CAmRoutingNode * currentNode = *currentNodeIterator; + assert(currentNode->getData().type==CAmNodeDataType::SOURCE); currentNodeIterator++; assert(currentNodeIterator!=nodes.end()); - CAmNode<am_RoutingNodeData_s> * nodeSink = *currentNodeIterator; - assert(nodeSink->getData().type==am_RoutingNodeData_s::am_NodeDataType_e::SINK); + CAmRoutingNode * nodeSink = *currentNodeIterator; + assert(nodeSink->getData().type==CAmNodeDataType::SINK); am_Source_s *source = currentNode->getData().data.source; am_Sink_s *sink = nodeSink->getData().data.sink; - CAmRouter::listPossibleConnectionFormats(source->listConnectionFormats, sink->listConnectionFormats, listMergeConnectionFormats); + listPossibleConnectionFormats(source->listConnectionFormats, sink->listConnectionFormats, listMergeConnectionFormats); currentNodeIterator+=1; //now we are on the next converter/gateway } @@ -868,20 +582,17 @@ am_Error_e CAmRouter::doConnectionFormatsForPath(am_Route_s & routeObjects, 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); -} +#ifdef ROUTING_BUILD_CONNECTIONS -void CAmRouter::getShortestPath(std::vector<CAmNode<am_RoutingNodeData_s>*> & resultPath) +void CAmRouter::getShortestPath(const CAmRoutingNode & source, + const CAmRoutingNode & destination, + std::vector<CAmRoutingNode*> & resultPath) { - getShortestPath(*mpRootSource, *mpRootSink, resultPath); + mRoutingGraph.getShortestPath(source, destination, 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) +void CAmRouter::getShortestPath(CAmRoutingNode & aSource, CAmRoutingNode & aSink, + am_Route_s & resultPath, std::vector<CAmRoutingNode*> & resultNodesPath) { am_RoutingElement_s * element; am_RoutingNodeData_s & sinkNodeData = aSink.getData(); @@ -889,11 +600,11 @@ void CAmRouter::getShortestPath(CAmNode<am_RoutingNodeData_s> & aSource, CAmNode 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) + std::function<void(const am_GraphPathPosition_e, CAmRoutingNode &)> cb = [&](const am_GraphPathPosition_e, CAmRoutingNode & object) { - resultNodesPath.insert(resultNodesPath.begin(), (CAmNode<am_RoutingNodeData_s>*)&object); + resultNodesPath.insert(resultNodesPath.begin(), (CAmRoutingNode*)&object); am_RoutingNodeData_s & routingData = object.getData(); - if(routingData.type==am_RoutingNodeData_s::am_NodeDataType_e::SINK) + if(routingData.type==CAmNodeDataType::SINK) { auto iter = resultPath.route.emplace(resultPath.route.begin()); element = &(*iter); @@ -901,7 +612,7 @@ void CAmRouter::getShortestPath(CAmNode<am_RoutingNodeData_s> & aSource, CAmNode element->sinkID = routingData.data.sink->sinkID; element->connectionFormat = CF_UNKNOWN; } - else if(routingData.type==am_RoutingNodeData_s::am_NodeDataType_e::SOURCE) + else if(routingData.type==CAmNodeDataType::SOURCE) { element->domainID = routingData.data.source->domainID; element->sourceID = routingData.data.source->sourceID; @@ -911,16 +622,25 @@ void CAmRouter::getShortestPath(CAmNode<am_RoutingNodeData_s> & aSource, CAmNode mRoutingGraph.getShortestPath(aSource, aSink, cb); } -void CAmRouter::getShortestPath(am_Route_s & resultPath, std::vector<CAmNode<am_RoutingNodeData_s>*> & resultNodesPath) -{ - getShortestPath(*mpRootSource, *mpRootSink, resultPath, resultNodesPath); -} +#endif -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) +am_Error_e CAmRouter::getAllPaths(CAmRoutingNode & aSource, + CAmRoutingNode & aSink, + std::vector<am_Route_s> & resultPath, + std::vector<std::vector<CAmRoutingNode*>> & resultNodesPath, + const bool includeCycles) { +#ifndef ROUTING_BUILD_CONNECTIONS + bool cycles = false; +#else + bool cycles = includeCycles; +#endif + if(((CAmRoutingNode*)&aSource)->getData().type!=CAmNodeDataType::SOURCE || + ((CAmRoutingNode*)&aSink)->getData().type!=CAmNodeDataType::SINK) + return E_NOT_POSSIBLE; + uint8_t errorsCount = 0, successCount = 0; - mRoutingGraph.getAllPaths(aSource, aSink, [&](const std::vector<CAmNode<am_RoutingNodeData_s>*> & path) { + generateAllPaths(aSource, aSink, cycles, [&](const std::vector<CAmRoutingNode*> & path) { resultNodesPath.push_back(path); resultPath.emplace_back(); am_Route_s & nextRoute = resultPath.back(); @@ -930,7 +650,7 @@ am_Error_e CAmRouter::getAllPaths(CAmNode<am_RoutingNodeData_s> & aSource, CAmNo 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) + if(routingData.type==CAmNodeDataType::SOURCE) { auto iter = nextRoute.route.emplace(nextRoute.route.end()); element = &(*iter); @@ -938,14 +658,15 @@ am_Error_e CAmRouter::getAllPaths(CAmNode<am_RoutingNodeData_s> & aSource, CAmNo element->sourceID = routingData.data.source->sourceID; element->connectionFormat = CF_UNKNOWN; } - else if(routingData.type==am_RoutingNodeData_s::am_NodeDataType_e::SINK) + else if(routingData.type==CAmNodeDataType::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); + + am_Error_e err = determineConnectionFormatsForPath(nextRoute, (std::vector<CAmRoutingNode*> &)path); if(err!=E_OK) { errorsCount++; @@ -984,22 +705,179 @@ am_Error_e CAmRouter::getAllPaths(CAmNode<am_RoutingNodeData_s> & aSource, CAmNo return E_OK; } -am_Error_e CAmRouter::getAllPaths(std::vector<am_Route_s> & resultPath, std::vector<std::vector<CAmNode<am_RoutingNodeData_s>*>> & resultNodesPath) +bool CAmRouter::shouldGoInDomain(const std::vector<am_domainID_t> & visitedDomains, const am_domainID_t nodeDomainID) +{ + if(visitedDomains.size()) + { + if(visitedDomains.back()==nodeDomainID) + return true; + + for(auto it=visitedDomains.begin();it!=visitedDomains.end()-1; it++) + { + if(nodeDomainID==*it) + return false; + } + } + return true; +} + +void CAmRouter::generateAllPaths(const CAmRoutingNode & src, + const CAmRoutingNode & dst, + const bool includeCycles, + std::function<void(const std::vector<CAmRoutingNode*> & path)> cb) { - return getAllPaths(*mpRootSource, *mpRootSink, resultPath, resultNodesPath); + if(!includeCycles) + { + std::vector<CAmRoutingNode*> visited; + std::vector<am_domainID_t> visitedDomains; + visited.push_back((CAmRoutingNode*)&src); + visitedDomains.push_back(((CAmRoutingNode*)&src)->getData().domainID()); + ((CAmRoutingNode*)&src)->setStatus(GES_VISITED); + goThroughAllPaths(dst, visited, visitedDomains, cb); + } + else + mRoutingGraph.getAllPaths(src, dst, cb); } +void CAmRouter::goThroughAllPaths(const CAmRoutingNode & dst, + std::vector<CAmRoutingNode*> & visited, + std::vector<am_domainID_t> & visitedDomains, + std::function<void(const std::vector<CAmRoutingNode*> & path)> cb) +{ +#ifndef ROUTING_BUILD_CONNECTIONS + CAmRoutingListVertices vertices; + getVerticesForNode(*visited.back(), vertices); + const CAmRoutingListVertices * nodes = &vertices; +#else + const CAmRoutingListVertices * nodes = mRoutingGraph.getVertexList()[visited.back()->getIndex()]; #endif + CAmRoutingListVertices::const_iterator vItr(nodes->begin()); + for (; vItr != nodes->end(); ++vItr) + { + const CAmRoutingVertex & vertex = (*vItr); + if(vertex.getNode()->getStatus()!=GES_NOT_VISITED || !shouldGoInDomain(visitedDomains, vertex.getNode()->getData().domainID())) + continue; + if (vertex.getNode()==&dst) + { + vertex.getNode()->setStatus(GES_IN_PROGRESS); + visited.push_back(vertex.getNode()); + visitedDomains.push_back(vertex.getNode()->getData().domainID()); + //notify observer + cb(visited); + //remove last node from the list + auto last = visited.end()-1; + visited.erase(last); + visitedDomains.erase(visitedDomains.end()-1); + vertex.getNode()->setStatus(GES_NOT_VISITED); + break; + } + } + vItr = nodes->begin(); + //bfs like loop + for (; vItr != nodes->end(); ++vItr) + { + const CAmRoutingVertex & vertex = (*vItr); + if(vertex.getNode()->getStatus()!=GES_NOT_VISITED + ||vertex.getNode()==&dst || + !shouldGoInDomain(visitedDomains, vertex.getNode()->getData().domainID())) + continue; + vertex.getNode()->setStatus(GES_IN_PROGRESS); + visited.push_back(vertex.getNode()); + visitedDomains.push_back(vertex.getNode()->getData().domainID()); + goThroughAllPaths(dst, visited, visitedDomains, cb); + //remove last node from the list + auto last = visited.end()-1; + visited.erase(last); + visitedDomains.erase(visitedDomains.end()-1); + vertex.getNode()->setStatus(GES_NOT_VISITED); + } +} -void CAmRouter::clear() +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) { - mRoutingGraph.clear(); - mNodeListSources.clear(); - mNodeListSinks.clear(); - mNodeListGateways.clear(); - mNodeListConverters.clear(); - mpRootSource=NULL; - mpRootSink=NULL; + 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; +} + +void CAmRouter::listPossibleConnectionFormats(std::vector<am_CustomConnectionFormat_t> & inListSourceFormats, + std::vector<am_CustomConnectionFormat_t> & inListSinkFormats, + std::vector<am_CustomConnectionFormat_t> & outListFormats) +{ + 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); +} + + +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(); + 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(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); + + //iterate line-wise through the matrix and add more formats + do + { + if (*matrixIterator) + { + listFormats.push_back(listSourceFormats.at((matrixIterator - convertionMatrix.begin()) / listSinkFormats.size())); + } + std::advance(matrixIterator, listSinkFormats.size()); + } while (convertionMatrix.end() - matrixIterator > 0); + + return listFormats.size(); +} + + +void CAmRouter::getSourceSinkPossibleConnectionFormats(std::vector<CAmRoutingNode*>::iterator iteratorSource, + std::vector<CAmRoutingNode*>::iterator iteratorSink, + std::vector<am_CustomConnectionFormat_t> & outConnectionFormats) +{ + CAmRoutingNode * nodeSink = *iteratorSink; + assert(nodeSink->getData().type==CAmNodeDataType::SINK); + + CAmRoutingNode * nodeSource = *iteratorSource; + assert(nodeSource->getData().type==CAmNodeDataType::SOURCE); + + am_Source_s *source = nodeSource->getData().data.source; + am_Sink_s *sink = nodeSink->getData().data.sink; + listPossibleConnectionFormats(source->listConnectionFormats, sink->listConnectionFormats, outConnectionFormats); } diff --git a/AudioManagerDaemon/test/AmRouterMapTest/CAmRouterMapTest.cpp b/AudioManagerDaemon/test/AmRouterMapTest/CAmRouterMapTest.cpp index 03efae5..647dad5 100644 --- a/AudioManagerDaemon/test/AmRouterMapTest/CAmRouterMapTest.cpp +++ b/AudioManagerDaemon/test/AmRouterMapTest/CAmRouterMapTest.cpp @@ -20,34 +20,38 @@ * */ +#include <ctime> +#include <chrono> #include "CAmRouterMapTest.h" #include <string.h> #include "CAmDltWrapper.h" + + using namespace am; using namespace testing; CAmRouterMapTest::CAmRouterMapTest() : - plistRoutingPluginDirs(), // - plistCommandPluginDirs(), // - pSocketHandler(), // - pControlSender(), // - pDatabaseHandler(), - pRouter(&pDatabaseHandler, &pControlSender), // - pRoutingSender(plistRoutingPluginDirs), // - pCommandSender(plistCommandPluginDirs), // - pMockInterface(), // - pMockControlInterface(), // - pRoutingInterfaceBackdoor(), // - pCommandInterfaceBackdoor(), // - pControlInterfaceBackdoor(), // - pControlReceiver(&pDatabaseHandler, &pRoutingSender, &pCommandSender,&pSocketHandler, &pRouter), // - pObserver(&pCommandSender, &pRoutingSender, &pSocketHandler) + plistRoutingPluginDirs(), // + plistCommandPluginDirs(), // + pSocketHandler(), // + pControlSender(), // + pDatabaseHandler(), + pRouter(&pDatabaseHandler, &pControlSender), // + pRoutingSender(plistRoutingPluginDirs), // + pCommandSender(plistCommandPluginDirs), // + pMockInterface(), // + pMockControlInterface(), // + pRoutingInterfaceBackdoor(), // + pCommandInterfaceBackdoor(), // + pControlInterfaceBackdoor(), // + pControlReceiver(&pDatabaseHandler, &pRoutingSender, &pCommandSender,&pSocketHandler, &pRouter), // + pObserver(&pCommandSender, &pRoutingSender, &pSocketHandler) { - pDatabaseHandler.registerObserver(&pObserver); - pCommandInterfaceBackdoor.injectInterface(&pCommandSender, &pMockInterface); - pControlInterfaceBackdoor.replaceController(&pControlSender, &pMockControlInterface); + pDatabaseHandler.registerObserver(&pObserver); + pCommandInterfaceBackdoor.injectInterface(&pCommandSender, &pMockInterface); + pControlInterfaceBackdoor.replaceController(&pControlSender, &pMockControlInterface); } CAmRouterMapTest::~CAmRouterMapTest() @@ -57,7 +61,7 @@ CAmRouterMapTest::~CAmRouterMapTest() void CAmRouterMapTest::SetUp() { - logInfo("Routing Test started "); + logInfo("Routing Test started "); } void CAmRouterMapTest::TearDown() @@ -65,7 +69,7 @@ void CAmRouterMapTest::TearDown() } ACTION(returnConnectionFormat){ -arg4=arg3; + arg4=arg3; } void CAmRouterMapTest::enterDomainDB(const std::string & domainName, am_domainID_t & domainID) @@ -103,48 +107,114 @@ void CAmRouterMapTest::enterSinkDB(const std::string & sinkName, const am_domain } void CAmRouterMapTest::enterGatewayDB(const std::string & gwName, - const am_domainID_t domainSourceID, - const am_domainID_t domainSinkID, - const std::vector<am_CustomConnectionFormat_t> & sourceConnectionFormats, - const std::vector<am_CustomConnectionFormat_t> & sinkConnectionFormats, - const std::vector<bool> & matrix, - const am_sourceID_t & sourceID, - const am_sinkID_t & sinkID, - am_gatewayID_t & gatewayID) + const am_domainID_t domainSourceID, + const am_domainID_t domainSinkID, + const std::vector<am_CustomConnectionFormat_t> & sourceConnectionFormats, + const std::vector<am_CustomConnectionFormat_t> & sinkConnectionFormats, + const std::vector<bool> & matrix, + const am_sourceID_t & sourceID, + const am_sinkID_t & sinkID, + am_gatewayID_t & gatewayID) { - am_Gateway_s gateway; - gateway.controlDomainID = domainSourceID; - gateway.gatewayID = 0; - gateway.sinkID = sinkID; - gateway.sourceID = sourceID; - gateway.domainSourceID = domainSourceID; - gateway.domainSinkID = domainSinkID; - gateway.listSinkFormats = sinkConnectionFormats; - gateway.listSourceFormats = sourceConnectionFormats; - gateway.convertionMatrix = matrix; - gateway.name = gwName; - ASSERT_EQ(E_OK, pDatabaseHandler.enterGatewayDB(gateway,gatewayID)); + am_Gateway_s gateway; + gateway.controlDomainID = domainSourceID; + gateway.gatewayID = 0; + gateway.sinkID = sinkID; + gateway.sourceID = sourceID; + gateway.domainSourceID = domainSourceID; + gateway.domainSinkID = domainSinkID; + gateway.listSinkFormats = sinkConnectionFormats; + gateway.listSourceFormats = sourceConnectionFormats; + gateway.convertionMatrix = matrix; + gateway.name = gwName; + ASSERT_EQ(E_OK, pDatabaseHandler.enterGatewayDB(gateway,gatewayID)); } void CAmRouterMapTest::enterConverterDB(const std::string & gwName, - const am_domainID_t domainID, - const std::vector<am_CustomConnectionFormat_t> & sourceConnectionFormats, - const std::vector<am_CustomConnectionFormat_t> & sinkConnectionFormats, - const std::vector<bool> & matrix, - const am_sourceID_t & sourceID, - const am_sinkID_t & sinkID, - am_converterID_t & converterID) + const am_domainID_t domainID, + const std::vector<am_CustomConnectionFormat_t> & sourceConnectionFormats, + const std::vector<am_CustomConnectionFormat_t> & sinkConnectionFormats, + const std::vector<bool> & matrix, + const am_sourceID_t & sourceID, + const am_sinkID_t & sinkID, + am_converterID_t & converterID) +{ + am_Converter_s converter; + converter.converterID = 0; + converter.sinkID = sinkID; + converter.sourceID = sourceID; + converter.domainID = domainID; + converter.listSinkFormats = sinkConnectionFormats; + converter.listSourceFormats = sourceConnectionFormats; + converter.convertionMatrix = matrix; + converter.name = gwName; + ASSERT_EQ(E_OK, pDatabaseHandler.enterConverterDB(converter,converterID)); +} + +void CAmRouterMapTest::getRoute(const bool onlyfree, const am_Source_s & aSource, const am_Sink_s & aSink, std::vector<am_Route_s> & listRoutes) +{ + std::ios_base::fmtflags oldflags = std::cout.flags(); + std::streamsize oldprecision = std::cout.precision(); + auto t_start = std::chrono::high_resolution_clock::now(); + ASSERT_EQ(E_OK, pRouter.getRoute(onlyfree, aSource, aSink, listRoutes)); + auto t_end = std::chrono::high_resolution_clock::now(); + std::cout << std::fixed << std::setprecision(2); + std::cout << "getRoute did find " << listRoutes.size() <<" routes from " << aSource.sourceID << " to " << aSink.sinkID; + std::cout << " in " << std::chrono::duration<double, std::milli>(t_end-t_start).count() << " ms\n"; + std::cout.flags (oldflags); + std::cout.precision (oldprecision); +} + +void CAmRouterMapTest::getRoute(const bool onlyfree, const am_sourceID_t sourceID, const am_sinkID_t sinkID, std::vector<am_Route_s>& returnList) +{ + std::ios_base::fmtflags oldflags = std::cout.flags(); + std::streamsize oldprecision = std::cout.precision(); + auto t_start = std::chrono::high_resolution_clock::now(); + ASSERT_EQ(E_OK, pRouter.getRoute(onlyfree, sourceID, sinkID, returnList)); + auto t_end = std::chrono::high_resolution_clock::now(); + std::cout << std::fixed << std::setprecision(2); + std::cout << "getRoute by id did find " << returnList.size() <<" routes from " << sourceID << " to " << sinkID; + std::cout << " in " << std::chrono::duration<double, std::milli>(t_end-t_start).count() << " ms\n"; + std::cout.flags (oldflags); + std::cout.precision (oldprecision); +} + +void CAmRouterMapTest::getAllPaths(CAmRoutingNode & aSource, + CAmRoutingNode & aSink, + std::vector<am_Route_s> & resultPath, + std::vector<std::vector<CAmRoutingNode*>> & resultNodesPath, + const bool includeCycles) +{ + std::ios_base::fmtflags oldflags = std::cout.flags(); + std::streamsize oldprecision = std::cout.precision(); + auto t_start = std::chrono::high_resolution_clock::now(); + ASSERT_EQ(E_OK, pRouter.getAllPaths(aSource, aSink, resultPath, resultNodesPath, includeCycles)); + auto t_end = std::chrono::high_resolution_clock::now(); + std::cout << std::fixed << std::setprecision(2); + std::cout << "getAllPaths did find " << resultPath.size() + << " routes from " << aSource.getData().data.source->sourceID + << " to " << aSink.getData().data.sink->sinkID; + std::cout << " in " << std::chrono::duration<double, std::milli>(t_end-t_start).count() << " ms\n"; + std::cout.flags (oldflags); + std::cout.precision (oldprecision); +} + +TEST_F(CAmRouterMapTest,checkInsertedDomain) { - am_Converter_s converter; - converter.converterID = 0; - converter.sinkID = sinkID; - converter.sourceID = sourceID; - converter.domainID = domainID; - converter.listSinkFormats = sinkConnectionFormats; - converter.listSourceFormats = sourceConnectionFormats; - converter.convertionMatrix = matrix; - converter.name = gwName; - ASSERT_EQ(E_OK, pDatabaseHandler.enterConverterDB(converter,converterID)); + std::vector<am_domainID_t> domains; + ASSERT_TRUE(CAmRouter::shouldGoInDomain(domains, 22)); + domains.push_back(22); + ASSERT_TRUE(CAmRouter::shouldGoInDomain(domains, 22)); + domains.push_back(22); + ASSERT_TRUE(CAmRouter::shouldGoInDomain(domains, 22)); + ASSERT_TRUE(CAmRouter::shouldGoInDomain(domains, 50)); + domains.push_back(30); + ASSERT_TRUE(CAmRouter::shouldGoInDomain(domains, 30)); + ASSERT_FALSE(CAmRouter::shouldGoInDomain(domains, 22)); + domains.push_back(30); + ASSERT_TRUE(CAmRouter::shouldGoInDomain(domains, 30)); + ASSERT_FALSE(CAmRouter::shouldGoInDomain(domains, 22)); + ASSERT_TRUE(CAmRouter::shouldGoInDomain(domains, 60)); } //test that checks just sinks and source in a domain but connectionformats do not match @@ -208,7 +278,7 @@ TEST_F(CAmRouterMapTest,simpleRoute2withDomainNoMatchFormats) pDatabaseHandler.getSinkInfoDB(sinkID, sinkDb); pDatabaseHandler.getSourceInfoDB(sourceID, sourceDb); listRoutes.clear(); - ASSERT_EQ(E_OK, pRouter.getRoute(true, sourceDb, sinkDb, listRoutes)); + getRoute(true, sourceDb, sinkDb, listRoutes); ASSERT_EQ(static_cast<uint>(0), listRoutes.size()); } @@ -273,7 +343,7 @@ TEST_F(CAmRouterMapTest,simpleRoute2withDomain) pDatabaseHandler.getSinkInfoDB(sinkID, sinkDb); pDatabaseHandler.getSourceInfoDB(sourceID, sourceDb); listRoutes.clear(); - ASSERT_EQ(E_OK, pRouter.getRoute(true, sourceDb, sinkDb, listRoutes)); + getRoute(true, sourceDb, sinkDb, listRoutes); ASSERT_EQ(static_cast<uint>(1), listRoutes.size()); ASSERT_TRUE(pCF.compareRoute(compareRoute,listRoutes[0])); } @@ -383,7 +453,7 @@ TEST_F(CAmRouterMapTest,simpleRoute2DomainsOnlyFree) pDatabaseHandler.getSinkInfoDB(sinkID, sinkDb); pDatabaseHandler.getSourceInfoDB(sourceID, sourceDb); - ASSERT_EQ(E_OK, pRouter.getRoute(true,sourceID,sinkID,listRoutes)); + getRoute(true,sourceID,sinkID,listRoutes); ASSERT_EQ(static_cast<uint>(1), listRoutes.size()); ASSERT_TRUE(pCF.compareRoute(compareRoute,listRoutes[0])); } @@ -508,11 +578,11 @@ TEST_F(CAmRouterMapTest,simpleRoute2DomainsOnlyFreeNotFree) pDatabaseHandler.getSinkInfoDB(sinkID, sinkDb); pDatabaseHandler.getSourceInfoDB(sourceID, sourceDb); listRoutes.clear(); - ASSERT_EQ(E_OK, pRouter.getRoute(true, sourceDb, sinkDb, listRoutes)); + getRoute(true, sourceDb, sinkDb, listRoutes); ASSERT_EQ(static_cast<uint>(0), listRoutes.size()); listRoutes.clear(); - ASSERT_EQ(E_OK, pRouter.getRoute(false, sourceDb, sinkDb, listRoutes)); + getRoute(false, sourceDb, sinkDb, listRoutes); ASSERT_EQ(static_cast<uint>(1), listRoutes.size()); ASSERT_TRUE(pCF.compareRoute(compareRoute,listRoutes[0])); } @@ -650,7 +720,7 @@ TEST_F(CAmRouterMapTest,simpleRoute2DomainsCircularGWOnlyFree) pDatabaseHandler.getSinkInfoDB(sinkID, sinkDb); pDatabaseHandler.getSourceInfoDB(sourceID, sourceDb); listRoutes.clear(); - ASSERT_EQ(E_OK, pRouter.getRoute(true, sourceDb, sinkDb, listRoutes)); + getRoute(true, sourceDb, sinkDb, listRoutes); ASSERT_EQ(static_cast<uint>(1), listRoutes.size()); ASSERT_TRUE(pCF.compareRoute(compareRoute,listRoutes[0])); } @@ -813,7 +883,7 @@ TEST_F(CAmRouterMapTest,simpleRoute3DomainsListConnectionFormats_2) am::am_Sink_s sinkDb; pDatabaseHandler.getSinkInfoDB(sinkID, sinkDb); pDatabaseHandler.getSourceInfoDB(sourceID, sourceDb); - ASSERT_EQ(E_OK, pRouter.getRoute(false, sourceDb, sinkDb, listRoutes)); + getRoute(false, sourceDb, sinkDb, listRoutes); ASSERT_EQ(static_cast<uint>(1), listRoutes.size()); ASSERT_TRUE(pCF.compareRoute(compareRoute,listRoutes[0])); } @@ -971,7 +1041,7 @@ TEST_F(CAmRouterMapTest,simpleRoute3DomainsListConnectionFormats_1) am::am_Sink_s sinkDb; pDatabaseHandler.getSinkInfoDB(sinkID, sinkDb); pDatabaseHandler.getSourceInfoDB(sourceID, sourceDb); - ASSERT_EQ(E_OK, pRouter.getRoute(false, sourceDb, sinkDb, listRoutes)); + getRoute(false, sourceDb, sinkDb, listRoutes); ASSERT_EQ(static_cast<uint>(1), listRoutes.size()); ASSERT_TRUE(pCF.compareRoute(compareRoute,listRoutes[0])); } @@ -1124,7 +1194,7 @@ TEST_F(CAmRouterMapTest,simpleRoute3DomainsListConnectionFormats) am::am_Sink_s sinkDb; pDatabaseHandler.getSinkInfoDB(sinkID, sinkDb); pDatabaseHandler.getSourceInfoDB(sourceID, sourceDb); - ASSERT_EQ(E_OK, pRouter.getRoute(false, sourceDb, sinkDb, listRoutes)); + getRoute(false, sourceDb, sinkDb, listRoutes); ASSERT_EQ(static_cast<uint>(1), listRoutes.size()); ASSERT_TRUE(pCF.compareRoute(compareRoute,listRoutes[0])); } @@ -1362,7 +1432,7 @@ TEST_F(CAmRouterMapTest,simpleRoute4Domains2Routes) am::am_Sink_s sinkDb; pDatabaseHandler.getSinkInfoDB(sinkID, sinkDb); pDatabaseHandler.getSourceInfoDB(sourceID, sourceDb); - ASSERT_EQ(E_OK, pRouter.getRoute(false, sourceDb, sinkDb, listRoutes)); + getRoute(false, sourceDb, sinkDb, listRoutes); ASSERT_EQ(static_cast<uint>(2), listRoutes.size()); bool containsRoute1 = std::find_if(listRoutes.begin(), listRoutes.end(), [&](const am_Route_s & ref) { @@ -1521,7 +1591,7 @@ TEST_F(CAmRouterMapTest,simpleRoute3DomainsNoConnection) pDatabaseHandler.getSinkInfoDB(sinkID, sinkDb); pDatabaseHandler.getSourceInfoDB(sourceID, sourceDb); listRoutes.clear(); - ASSERT_EQ(E_OK, pRouter.getRoute(false, sourceDb, sinkDb, listRoutes)); + getRoute(false, sourceDb, sinkDb, listRoutes); ASSERT_EQ(static_cast<uint>(0), listRoutes.size()); } //test that checks just 2 domains, one sink one source with only one connection format each @@ -1628,7 +1698,7 @@ TEST_F(CAmRouterMapTest,simpleRoute2Domains) am::am_Sink_s sinkDb; pDatabaseHandler.getSinkInfoDB(sinkID, sinkDb); pDatabaseHandler.getSourceInfoDB(sourceID, sourceDb); - ASSERT_EQ(E_OK, pRouter.getRoute(false, sourceDb, sinkDb, listRoutes)); + getRoute(false, sourceDb, sinkDb, listRoutes); ASSERT_EQ(static_cast<uint>(1), listRoutes.size()); ASSERT_TRUE(pCF.compareRoute(compareRoute,listRoutes[0])); } @@ -1716,7 +1786,7 @@ TEST_F(CAmRouterMapTest,simpleRoute2DomainsNoMatchConnectionFormats) am::am_Sink_s sinkDb; pDatabaseHandler.getSinkInfoDB(sinkID, sinkDb); pDatabaseHandler.getSourceInfoDB(sourceID, sourceDb); - ASSERT_EQ(E_OK, pRouter.getRoute(false, sourceDb, sinkDb, listRoutes)); + getRoute(false, sourceDb, sinkDb, listRoutes); ASSERT_EQ(static_cast<uint>(0), listRoutes.size()); } @@ -1865,7 +1935,7 @@ TEST_F(CAmRouterMapTest,simpleRoute3Domains) pDatabaseHandler.getSinkInfoDB(sinkID, sinkDb); pDatabaseHandler.getSourceInfoDB(sourceID, sourceDb); listRoutes.clear(); - ASSERT_EQ(E_OK, pRouter.getRoute(false, sourceDb, sinkDb, listRoutes)); + getRoute(false, sourceDb, sinkDb, listRoutes); ASSERT_EQ(static_cast<uint>(1), listRoutes.size()); ASSERT_TRUE(pCF.compareRoute(compareRoute,listRoutes[0])); } @@ -2055,7 +2125,7 @@ TEST_F(CAmRouterMapTest,simpleRoute4Domains) pDatabaseHandler.getSinkInfoDB(sinkID, sinkDb); pDatabaseHandler.getSourceInfoDB(sourceID, sourceDb); listRoutes.clear(); - ASSERT_EQ(E_OK, pRouter.getRoute(false, sourceDb, sinkDb, listRoutes)); + getRoute(false, sourceDb, sinkDb, listRoutes); ASSERT_EQ(static_cast<uint>(1), listRoutes.size()); ASSERT_TRUE(pCF.compareRoute(compareRoute,listRoutes[0])); } @@ -2171,7 +2241,7 @@ TEST_F(CAmRouterMapTest,route1Domain1Source1Sink) compareRoute.sinkID = sinkID; compareRoute.sourceID = sourceID; - ASSERT_EQ(E_OK, pRouter.getRoute(false, source, sink, listRoutes)); + getRoute(false, source, sink, listRoutes); ASSERT_EQ(static_cast<uint>(1), listRoutes.size()); ASSERT_TRUE(pCF.compareRoute(compareRoute,listRoutes[0])); } @@ -2244,7 +2314,7 @@ TEST_F(CAmRouterMapTest,route1Domain1Source1Converter1Sink) compareRoute.sinkID = sinkID1; compareRoute.sourceID = sourceID; - ASSERT_EQ(E_OK, pRouter.getRoute(false, source, sink, listRoutes)); + getRoute(false, source, sink, listRoutes); ASSERT_EQ(static_cast<uint>(1), listRoutes.size()); ASSERT_TRUE(pCF.compareRoute(compareRoute,listRoutes[0])); } @@ -2345,7 +2415,7 @@ TEST_F(CAmRouterMapTest,route1Domain1Source3Converters1Sink) compareRoute1.sinkID = sinkID; compareRoute1.sourceID = sourceID; - ASSERT_EQ(E_OK, pRouter.getRoute(false, source, sink, listRoutes)); + getRoute(false, source, sink, listRoutes); ASSERT_EQ(static_cast<uint>(2), listRoutes.size()); ASSERT_TRUE(pCF.compareRoute(compareRoute1,listRoutes[0])||pCF.compareRoute(compareRoute1,listRoutes[1])); @@ -2396,7 +2466,7 @@ TEST_F(CAmRouterMapTest,route2Domains1Source1Sink) pDatabaseHandler.getSourceInfoDB(sourceID, source); std::vector<am_Route_s> listRoutes; - ASSERT_EQ(E_OK, pRouter.getRoute(false, source, sink, listRoutes)); + getRoute(false, source, sink, listRoutes); ASSERT_EQ(static_cast<uint>(1), listRoutes.size()); am_Route_s compareRoute1; @@ -2458,7 +2528,7 @@ TEST_F(CAmRouterMapTest,route3Domains1Source1Sink) std::vector<am_Route_s> listRoutes; - ASSERT_EQ(E_OK, pRouter.getRoute(false, source, sink, listRoutes)); + getRoute(false, source, sink, listRoutes); ASSERT_EQ(static_cast<uint>(1), listRoutes.size()); am_Route_s compareRoute1; @@ -2470,142 +2540,6 @@ TEST_F(CAmRouterMapTest,route3Domains1Source1Sink) ASSERT_TRUE(pCF.compareRoute(compareRoute1,listRoutes[0])); } - -TEST_F(CAmRouterMapTest,route3Domains1Source3Gateways3Convertres1Sink) -{ - EXPECT_CALL(pMockControlInterface,getConnectionFormatChoice(_,_,_,_,_)).WillRepeatedly(DoAll(returnConnectionFormat(), Return(E_OK))); - - am_domainID_t domainID1, domainID2, domainID3; - enterDomainDB("domain1", domainID1); - enterDomainDB("domain2", domainID2); - enterDomainDB("domain3", domainID3); - - std::vector<am_CustomConnectionFormat_t> cfStereo; - cfStereo.push_back(CF_GENIVI_STEREO); - std::vector<am_CustomConnectionFormat_t> cfAnalog; - cfAnalog.push_back(CF_GENIVI_ANALOG); - std::vector<am_CustomConnectionFormat_t> cfMono; - cfMono.push_back(CF_GENIVI_MONO); - std::vector<am_CustomConnectionFormat_t> cfAuto; - cfAuto.push_back(CF_GENIVI_AUTO); - - am_sourceID_t sourceID; - enterSourceDB("source1", domainID1, cfStereo, sourceID); - - am_sinkID_t gwSinkID1; - enterSinkDB("gwSink1", domainID1, cfStereo, gwSinkID1); - - am_sourceID_t gwSourceID1; - enterSourceDB("gwSource1", domainID2, cfMono, gwSourceID1); - std::vector<bool> matrix; - matrix.push_back(true); - am_gatewayID_t gatewayID; - enterGatewayDB("gateway1", domainID2, domainID1, cfMono, cfStereo, matrix, gwSourceID1, gwSinkID1, gatewayID); - - - am_sourceID_t gwSourceID21; - enterSourceDB("gwSource21", domainID3, cfAuto, gwSourceID21); - am_sinkID_t gwSinkID21; - enterSinkDB("gwSink21", domainID1, cfMono, gwSinkID21); - am_gatewayID_t gatewayID21; - enterGatewayDB("gateway21", domainID3, domainID2, cfAuto, cfMono, matrix, gwSourceID21, gwSinkID21, gatewayID21); - - am_sourceID_t gwSourceID22; - enterSourceDB("gwSource22", domainID3, cfAuto, gwSourceID22); - am_sinkID_t gwSinkID22; - enterSinkDB("gwSink22", domainID2, cfMono, gwSinkID22); - am_gatewayID_t gatewayID22; - enterGatewayDB("gateway22", domainID3, domainID2, cfAuto, cfMono, matrix, gwSourceID22, gwSinkID22, gatewayID22); - - am_sourceID_t gwSourceID3; - enterSourceDB("gwSource3", domainID3, cfAnalog, gwSourceID3); - am_sinkID_t gwSinkID3; - enterSinkDB("gwSink3", domainID3, cfAuto, gwSinkID3); - am_converterID_t converterID1; - enterConverterDB("converter1", domainID3, cfAnalog, cfAuto, matrix, gwSourceID3, gwSinkID3, converterID1); - - am_sourceID_t gwSourceID4; - enterSourceDB("gwSource4", domainID3, cfStereo, gwSourceID4); - am_sinkID_t gwSinkID4; - enterSinkDB("gwSink4", domainID3, cfAnalog, gwSinkID4); - am_converterID_t converterID2; - enterConverterDB("converter2", domainID3, cfStereo, cfAnalog, matrix, gwSourceID4, gwSinkID4, converterID2); - - am_sourceID_t gwSourceID5; - enterSourceDB("gwSource5", domainID3, cfStereo, gwSourceID5); - am_sinkID_t gwSinkID5; - enterSinkDB("gwSink5", domainID3, cfAnalog, gwSinkID5); - am_converterID_t converterID3; - enterConverterDB("converter3", domainID3, cfStereo, cfAnalog, matrix, gwSourceID5, gwSinkID5, converterID3); - - am_sinkID_t sinkID; - enterSinkDB("sink1", domainID3, cfStereo, sinkID); - - am::am_Source_s source; - am::am_Sink_s sink; - - pDatabaseHandler.getSinkInfoDB(sinkID, sink); - pDatabaseHandler.getSourceInfoDB(sourceID, source); - - std::vector<am_Route_s> listRoutes; - - ASSERT_EQ(E_OK, pRouter.getRoute(false, source, sink, listRoutes)); - ASSERT_EQ(static_cast<uint>(4), listRoutes.size()); - - am_Route_s compareRoute1; - compareRoute1.sinkID = sinkID; - compareRoute1.sourceID = sourceID; - compareRoute1.route.push_back({sourceID, gwSinkID1, domainID1, CF_GENIVI_STEREO}); - compareRoute1.route.push_back({gwSourceID1, gwSinkID21, domainID1, CF_GENIVI_MONO}); - compareRoute1.route.push_back({gwSourceID21, gwSinkID3, domainID3, CF_GENIVI_AUTO}); - compareRoute1.route.push_back({gwSourceID3, gwSinkID4, domainID3, CF_GENIVI_ANALOG}); - compareRoute1.route.push_back({gwSourceID4, sinkID, domainID3, CF_GENIVI_STEREO}); - - am_Route_s compareRoute2; - compareRoute2.sinkID = sinkID; - compareRoute2.sourceID = sourceID; - compareRoute2.route.push_back({sourceID, gwSinkID1, domainID1, CF_GENIVI_STEREO}); - compareRoute2.route.push_back({gwSourceID1, gwSinkID21, domainID1, CF_GENIVI_MONO}); - compareRoute2.route.push_back({gwSourceID21, gwSinkID3, domainID3, CF_GENIVI_AUTO}); - compareRoute2.route.push_back({gwSourceID3, gwSinkID5, domainID3, CF_GENIVI_ANALOG}); - compareRoute2.route.push_back({gwSourceID5, sinkID, domainID3, CF_GENIVI_STEREO}); - - am_Route_s compareRoute3; - compareRoute3.sinkID = sinkID; - compareRoute3.sourceID = sourceID; - compareRoute3.route.push_back({sourceID, gwSinkID1, domainID1, CF_GENIVI_STEREO}); - compareRoute3.route.push_back({gwSourceID1, gwSinkID22, domainID2, CF_GENIVI_MONO}); - compareRoute3.route.push_back({gwSourceID22, gwSinkID3, domainID3, CF_GENIVI_AUTO}); - compareRoute3.route.push_back({gwSourceID3, gwSinkID4, domainID3, CF_GENIVI_ANALOG}); - compareRoute3.route.push_back({gwSourceID4, sinkID, domainID3, CF_GENIVI_STEREO}); - - am_Route_s compareRoute4; - compareRoute4.sinkID = sinkID; - compareRoute4.sourceID = sourceID; - compareRoute4.route.push_back({sourceID, gwSinkID1, domainID1, CF_GENIVI_STEREO}); - compareRoute4.route.push_back({gwSourceID1, gwSinkID22, domainID2, CF_GENIVI_MONO}); - compareRoute4.route.push_back({gwSourceID22, gwSinkID3, domainID3, CF_GENIVI_AUTO}); - compareRoute4.route.push_back({gwSourceID3, gwSinkID5, domainID3, CF_GENIVI_ANALOG}); - compareRoute4.route.push_back({gwSourceID5, sinkID, domainID3, CF_GENIVI_STEREO}); - - ASSERT_TRUE(pCF.compareRoute(compareRoute1,listRoutes[0])|| - pCF.compareRoute(compareRoute1,listRoutes[1])|| - pCF.compareRoute(compareRoute1,listRoutes[2])|| - pCF.compareRoute(compareRoute1,listRoutes[3])); - ASSERT_TRUE(pCF.compareRoute(compareRoute2,listRoutes[0])|| - pCF.compareRoute(compareRoute2,listRoutes[1])|| - pCF.compareRoute(compareRoute2,listRoutes[2])|| - pCF.compareRoute(compareRoute2,listRoutes[3])); - ASSERT_TRUE(pCF.compareRoute(compareRoute3,listRoutes[0])|| - pCF.compareRoute(compareRoute3,listRoutes[1])|| - pCF.compareRoute(compareRoute3,listRoutes[2])|| - pCF.compareRoute(compareRoute3,listRoutes[3])); - ASSERT_TRUE(pCF.compareRoute(compareRoute4,listRoutes[0])|| - pCF.compareRoute(compareRoute4,listRoutes[1])|| - pCF.compareRoute(compareRoute4,listRoutes[2])|| - pCF.compareRoute(compareRoute4,listRoutes[3])); -} - TEST_F(CAmRouterMapTest,routeSource1Sink2PathThroughConv1Gate1) { EXPECT_CALL(pMockControlInterface,getConnectionFormatChoice(_,_,_,_,_)).WillRepeatedly(DoAll(returnConnectionFormat(), Return(E_OK))); @@ -2661,7 +2595,7 @@ TEST_F(CAmRouterMapTest,routeSource1Sink2PathThroughConv1Gate1) std::vector<am_Route_s> listRoutes; - ASSERT_EQ(E_OK, pRouter.getRoute(false, source, sink1, listRoutes)); + getRoute(false, source, sink1, listRoutes); ASSERT_EQ(static_cast<uint>(1), listRoutes.size()); am_Route_s compareRoute1; @@ -2673,7 +2607,7 @@ TEST_F(CAmRouterMapTest,routeSource1Sink2PathThroughConv1Gate1) ASSERT_TRUE(pCF.compareRoute(compareRoute1,listRoutes[0])); listRoutes.clear(); - ASSERT_EQ(E_OK, pRouter.getRoute(false, source, sink2, listRoutes)); + getRoute(false, source, sink2, listRoutes); ASSERT_EQ(static_cast<uint>(0), listRoutes.size()); } @@ -2713,26 +2647,32 @@ TEST_F(CAmRouterMapTest, routeSource1Sink1PathThroughDomain2) am_gatewayID_t gatewayID2; enterGatewayDB("gateway2", domainID1, domainID2, cfAuto, cfAnalog, matrix, gwSourceID12, gwSinkID21, gatewayID2); - am_sinkID_t sinkID; - enterSinkDB("sink1", domainID1, cfAuto, sinkID); + am_sinkID_t sink1ID; + enterSinkDB("sink1", domainID1, cfAuto, sink1ID); + am_sinkID_t sink2ID; + enterSinkDB("sink2", domainID2, cfAnalog, sink2ID); - am::am_Source_s source; - am::am_Sink_s sink; + std::vector<am_Route_s> listRoutes; - pDatabaseHandler.getSinkInfoDB(sinkID, sink); + am::am_Source_s source; + am::am_Sink_s sink1; + pDatabaseHandler.getSinkInfoDB(sink1ID, sink1); pDatabaseHandler.getSourceInfoDB(sourceID, source); - std::vector<am_Route_s> listRoutes; + getRoute(false, source, sink1, listRoutes); + ASSERT_EQ(static_cast<uint>(0), listRoutes.size()); - ASSERT_EQ(E_OK, pRouter.getRoute(false, source, sink, listRoutes)); + am::am_Sink_s sink2; + pDatabaseHandler.getSinkInfoDB(sink2ID, sink2); + + getRoute(false, source, sink2, listRoutes); ASSERT_EQ(static_cast<uint>(1), listRoutes.size()); am_Route_s compareRoute1; - compareRoute1.sinkID = sinkID; + compareRoute1.sinkID = sink2ID; compareRoute1.sourceID = sourceID; compareRoute1.route.push_back({sourceID, gwSinkID11, domainID1, CF_GENIVI_STEREO}); - compareRoute1.route.push_back({gwSourceID11, gwSinkID21, domainID2, CF_GENIVI_ANALOG}); - compareRoute1.route.push_back({gwSourceID12, sinkID, domainID1, CF_GENIVI_AUTO}); + compareRoute1.route.push_back({gwSourceID11, sink2ID, domainID2, CF_GENIVI_ANALOG}); ASSERT_TRUE(pCF.compareRoute(compareRoute1,listRoutes[0])); } @@ -2782,31 +2722,36 @@ TEST_F(CAmRouterMapTest, routeSource1Sink1PathThroughGate1Conv2Gate2) am_converterID_t converterID2; enterConverterDB("converter2", domainID2, cfStereo, cfAnalog, matrix, coSourceID21, coSinkID21, converterID2); - am_gatewayID_t gatewayID2; enterGatewayDB("gateway2", domainID1, domainID2, cfAuto, cfStereo, matrix, gwSourceID12, gwSinkID21, gatewayID2); - am_sinkID_t sinkID; - enterSinkDB("sink1", domainID1, cfAuto, sinkID); + am_sinkID_t sink1ID; + enterSinkDB("sink1", domainID1, cfAuto, sink1ID); + am_sinkID_t sink2ID; + enterSinkDB("sink2", domainID2, cfStereo, sink2ID); am::am_Source_s source; am::am_Sink_s sink; - pDatabaseHandler.getSinkInfoDB(sinkID, sink); + pDatabaseHandler.getSinkInfoDB(sink1ID, sink); pDatabaseHandler.getSourceInfoDB(sourceID, source); std::vector<am_Route_s> listRoutes; - ASSERT_EQ(E_OK, pRouter.getRoute(false, source, sink, listRoutes)); - ASSERT_EQ(static_cast<uint>(1), listRoutes.size()); + getRoute(false, source, sink, listRoutes); + ASSERT_EQ(static_cast<uint>(0), listRoutes.size()); + + am::am_Sink_s sink1; + pDatabaseHandler.getSinkInfoDB(sink2ID, sink1); + getRoute(false, source, sink1, listRoutes); + ASSERT_EQ(static_cast<uint>(1), listRoutes.size()); am_Route_s compareRoute1; - compareRoute1.sinkID = sinkID; + compareRoute1.sinkID = sink2ID; compareRoute1.sourceID = sourceID; compareRoute1.route.push_back({sourceID, gwSinkID11, domainID1, CF_GENIVI_STEREO}); compareRoute1.route.push_back({gwSourceID21, coSinkID21, domainID2, CF_GENIVI_ANALOG}); - compareRoute1.route.push_back({coSourceID21, gwSinkID21, domainID2, CF_GENIVI_STEREO}); - compareRoute1.route.push_back({gwSourceID12, sinkID, domainID1, CF_GENIVI_AUTO}); + compareRoute1.route.push_back({coSourceID21, sink2ID, domainID2, CF_GENIVI_STEREO}); ASSERT_TRUE(pCF.compareRoute(compareRoute1,listRoutes[0])); } @@ -2888,40 +2833,38 @@ TEST_F(CAmRouterMapTest, routeSource1Sink1PathThroughConv1Gate1Conv2Gate2) am::am_Source_s source; am::am_Sink_s sink; - pDatabaseHandler.getSinkInfoDB(sinkID, sink); pDatabaseHandler.getSourceInfoDB(sourceID, source); std::vector<am_Route_s> listRoutes; - ASSERT_EQ(E_OK, pRouter.getRoute(false, source, sink, listRoutes)); + getRoute(false, source, sink, listRoutes); + ASSERT_EQ(static_cast<uint>(0), listRoutes.size()); + am::am_Sink_s sink2; + pDatabaseHandler.getSinkInfoDB(coSinkID21, sink2); + pRouter.getRoute(false, source, sink2, listRoutes); ASSERT_EQ(static_cast<uint>(2), listRoutes.size()); am_Route_s compareRoute1; - compareRoute1.sinkID = sinkID; + compareRoute1.sinkID = coSinkID21; compareRoute1.sourceID = sourceID; compareRoute1.route.push_back({sourceID, coSinkID11, domainID1, CF_GENIVI_STEREO}); compareRoute1.route.push_back({coSourceID11, gwSinkID11, domainID1, 5}); compareRoute1.route.push_back({gwSourceID21, coSinkID21, domainID2, CF_GENIVI_ANALOG}); - compareRoute1.route.push_back({coSourceID21, gwSinkID21, domainID2, CF_GENIVI_STEREO}); - compareRoute1.route.push_back({gwSourceID12, sinkID, domainID1, CF_GENIVI_AUTO}); am_Route_s compareRoute2; - compareRoute2.sinkID = sinkID; + compareRoute2.sinkID = coSinkID21; compareRoute2.sourceID = sourceID; compareRoute2.route.push_back({sourceID, coSinkID12, domainID1, CF_GENIVI_STEREO}); compareRoute2.route.push_back({coSourceID12, coSinkID13, domainID1, 6}); compareRoute2.route.push_back({coSourceID13, gwSinkID11, domainID1, 5}); compareRoute2.route.push_back({gwSourceID21, coSinkID21, domainID2, CF_GENIVI_ANALOG}); - compareRoute2.route.push_back({coSourceID21, gwSinkID21, domainID2, CF_GENIVI_STEREO}); - compareRoute2.route.push_back({gwSourceID12, sinkID, domainID1, CF_GENIVI_AUTO}); ASSERT_TRUE(pCF.compareRoute(compareRoute1,listRoutes[1])||pCF.compareRoute(compareRoute1,listRoutes[0])); ASSERT_TRUE(pCF.compareRoute(compareRoute2,listRoutes[0])||pCF.compareRoute(compareRoute2,listRoutes[1])); } - TEST_F(CAmRouterMapTest,route3Domains1Source1SinkGwCycles) { EXPECT_CALL(pMockControlInterface,getConnectionFormatChoice(_,_,_,_,_)).WillRepeatedly(DoAll(returnConnectionFormat(), Return(E_OK))); @@ -2941,99 +2884,83 @@ TEST_F(CAmRouterMapTest,route3Domains1Source1SinkGwCycles) am_sourceID_t source1ID; enterSourceDB("source1", domain1ID, cfStereo, source1ID); - am_sinkID_t gw1SinkID; enterSinkDB("gw1Sink", domain1ID, cfStereo, gw1SinkID); - - am_sourceID_t gw1SourceID; - enterSourceDB("gw1Source", domain2ID, cfMono, gw1SourceID); - am_sinkID_t gw2SinkID; enterSinkDB("gw2Sink", domain1ID, cfStereo, gw2SinkID); + am_sourceID_t gw3SourceID; + enterSourceDB("gw3Source", domain1ID, cfAnalog, gw3SourceID); + am_sourceID_t gw4SourceID; + enterSourceDB("gw4Source", domain1ID, cfAnalog, gw4SourceID); + am_sinkID_t gw5SinkID; + enterSinkDB("gw5Sink", domain1ID, cfAnalog, gw5SinkID); + am_sourceID_t gw1SourceID; + enterSourceDB("gw1Source", domain2ID, cfMono, gw1SourceID); am_sourceID_t gw2SourceID; enterSourceDB("gw2Source", domain2ID, cfMono, gw2SourceID); - - std::vector<bool> matrixT; - matrixT.push_back(true); - std::vector<bool> matrixF; - matrixF.push_back(false); - - am_gatewayID_t gateway1ID; - enterGatewayDB("gateway1", domain2ID, domain1ID, cfMono, cfStereo, matrixT, gw1SourceID, gw1SinkID, gateway1ID); - - am_gatewayID_t gateway2ID; - enterGatewayDB("gateway2", domain2ID, domain1ID, cfMono, cfStereo, matrixT, gw2SourceID, gw2SinkID, gateway2ID); - - am_sinkID_t gw3SinkID; enterSinkDB("gw3Sink", domain2ID, cfMono, gw3SinkID); - - am_sourceID_t gw3SourceID; - enterSourceDB("gw3Source", domain1ID, cfAnalog, gw3SourceID); - - am_gatewayID_t gateway3ID; - enterGatewayDB("gateway3", domain1ID, domain2ID, cfAnalog, cfMono, matrixT, gw3SourceID, gw3SinkID, gateway3ID); - am_sinkID_t gw4SinkID; - enterSinkDB("gw4Sink", domain1ID, cfMono, gw4SinkID); - - am_sourceID_t gw4SourceID; - enterSourceDB("gw4Source", domain1ID, cfAnalog, gw4SourceID); - - am_gatewayID_t gateway4ID; - enterGatewayDB("gateway4", domain1ID, domain2ID, cfAnalog, cfMono, matrixT, gw4SourceID, gw4SinkID, gateway4ID); - - - am_sourceID_t gw5SourceID; - enterSourceDB("gw5Source", domain3ID, cfStereo, gw5SourceID); - - am_sinkID_t gw5SinkID; - enterSinkDB("gw5Sink", domain1ID, cfAnalog, gw5SinkID); + enterSinkDB("gw4Sink", domain2ID, cfMono, gw4SinkID); + am_sourceID_t gw5SourceID; + enterSourceDB("gw5Source", domain3ID, cfStereo, gw5SourceID); am_sinkID_t sink1ID; enterSinkDB("sink1", domain3ID, cfStereo, sink1ID); - am_gatewayID_t gateway5ID; - enterGatewayDB("gateway5", domain3ID, domain1ID, cfStereo, cfAnalog, matrixT, gw5SourceID, gw5SinkID, gateway5ID); + std::vector<bool> matrixT; + matrixT.push_back(true); + std::vector<bool> matrixF; + matrixF.push_back(false); - am::am_Source_s source; - am::am_Sink_s sink; + am_gatewayID_t gateway1ID; + enterGatewayDB("gateway1", domain2ID, domain1ID, cfMono, cfStereo, matrixT, gw1SourceID, gw1SinkID, gateway1ID); + am_gatewayID_t gateway2ID; + enterGatewayDB("gateway2", domain2ID, domain1ID, cfMono, cfStereo, matrixT, gw2SourceID, gw2SinkID, gateway2ID); + am_gatewayID_t gateway3ID; + enterGatewayDB("gateway3", domain1ID, domain2ID, cfAnalog, cfMono, matrixT, gw3SourceID, gw3SinkID, gateway3ID); + am_gatewayID_t gateway4ID; + enterGatewayDB("gateway4", domain1ID, domain2ID, cfAnalog, cfMono, matrixT, gw4SourceID, gw4SinkID, gateway4ID); + am_gatewayID_t gateway5ID; + enterGatewayDB("gateway5", domain3ID, domain1ID, cfStereo, cfAnalog, matrixT, gw5SourceID, gw5SinkID, gateway5ID); - pDatabaseHandler.getSinkInfoDB(sink1ID, sink); - pDatabaseHandler.getSourceInfoDB(source1ID, source); + pRouter.load(false); - std::vector<am_Route_s> listRoutes; + CAmRoutingNode* sourceNode = pRouter.sourceNodeWithID(source1ID); + CAmRoutingNode* sinkNode = pRouter.sinkNodeWithID(sink1ID); - ASSERT_EQ(E_OK, pRouter.getRoute(false, source, sink, listRoutes)); - ASSERT_EQ(static_cast<uint>(9), listRoutes.size()); + ASSERT_TRUE(sourceNode); + ASSERT_TRUE(sinkNode); -#define DO_ASSERT() \ - {\ - bool didMatch = false; \ - for(auto it = listRoutes.begin(); it!=listRoutes.end(); it++) \ - didMatch|=pCF.compareRoute(compareRoute1,*it); \ - ASSERT_TRUE(didMatch); \ - } + std::vector<am_Route_s> listRoutes; + std::vector<std::vector<CAmRoutingNode*>> resultNodesPath; am_Route_s compareRoute1; compareRoute1.sinkID = sink1ID; compareRoute1.sourceID = source1ID; - compareRoute1.route.push_back({source1ID, gw5SinkID, domain1ID, CF_GENIVI_STEREO}); - compareRoute1.route.push_back({gw5SourceID, sink1ID, domain3ID, CF_GENIVI_STEREO}); - DO_ASSERT() + +#define DO_ASSERT() \ + {\ + bool didMatch = false; \ + for(auto it = listRoutes.begin(); it!=listRoutes.end(); it++) \ + didMatch|=pCF.compareRoute(compareRoute1,*it); \ + ASSERT_TRUE(didMatch); \ + } + +#ifdef ROUTING_BUILD_CONNECTIONS + getAllPaths(*sourceNode, *sinkNode, listRoutes, resultNodesPath, true); + ASSERT_EQ(static_cast<uint>(9), listRoutes.size()); compareRoute1.route.clear(); compareRoute1.route.push_back({source1ID, gw2SinkID, domain1ID, CF_GENIVI_STEREO}); - compareRoute1.route.push_back({gw2SourceID, gw4SinkID, domain1ID, CF_GENIVI_STEREO}); + compareRoute1.route.push_back({gw2SourceID, gw4SinkID, domain2ID, CF_GENIVI_STEREO}); compareRoute1.route.push_back({gw4SourceID, gw5SinkID, domain1ID, CF_GENIVI_STEREO}); compareRoute1.route.push_back({gw5SourceID, sink1ID, domain3ID, CF_GENIVI_STEREO}); DO_ASSERT() compareRoute1.route.clear(); - compareRoute1.route.push_back({source1ID, gw2SinkID, domain1ID, CF_GENIVI_STEREO}); - compareRoute1.route.push_back({gw2SourceID, gw4SinkID, domain1ID, CF_GENIVI_STEREO}); - compareRoute1.route.push_back({gw4SourceID, gw1SinkID, domain1ID, CF_GENIVI_STEREO}); + compareRoute1.route.push_back({source1ID, gw1SinkID, domain1ID, CF_GENIVI_STEREO}); compareRoute1.route.push_back({gw1SourceID, gw3SinkID, domain2ID, CF_GENIVI_STEREO}); compareRoute1.route.push_back({gw3SourceID, gw5SinkID, domain1ID, CF_GENIVI_STEREO}); compareRoute1.route.push_back({gw5SourceID, sink1ID, domain3ID, CF_GENIVI_STEREO}); @@ -3047,56 +2974,205 @@ TEST_F(CAmRouterMapTest,route3Domains1Source1SinkGwCycles) DO_ASSERT() compareRoute1.route.clear(); - compareRoute1.route.push_back({source1ID, gw2SinkID, domain1ID, CF_GENIVI_STEREO}); - compareRoute1.route.push_back({gw2SourceID, gw3SinkID, domain2ID, CF_GENIVI_STEREO}); - compareRoute1.route.push_back({gw3SourceID, gw1SinkID, domain1ID, CF_GENIVI_STEREO}); - compareRoute1.route.push_back({gw1SourceID, gw4SinkID, domain1ID, CF_GENIVI_STEREO}); + compareRoute1.route.push_back({source1ID, gw1SinkID, domain1ID, CF_GENIVI_STEREO}); + compareRoute1.route.push_back({gw1SourceID, gw4SinkID, domain2ID, CF_GENIVI_STEREO}); compareRoute1.route.push_back({gw4SourceID, gw5SinkID, domain1ID, CF_GENIVI_STEREO}); compareRoute1.route.push_back({gw5SourceID, sink1ID, domain3ID, CF_GENIVI_STEREO}); DO_ASSERT() compareRoute1.route.clear(); - compareRoute1.route.push_back({source1ID, gw1SinkID, domain1ID, CF_GENIVI_STEREO}); + compareRoute1.route.push_back({source1ID, gw2SinkID, domain1ID, CF_GENIVI_STEREO}); + compareRoute1.route.push_back({gw2SourceID, gw4SinkID, domain2ID, CF_GENIVI_STEREO}); + compareRoute1.route.push_back({gw4SourceID, gw1SinkID, domain1ID, CF_GENIVI_STEREO}); compareRoute1.route.push_back({gw1SourceID, gw3SinkID, domain2ID, CF_GENIVI_STEREO}); compareRoute1.route.push_back({gw3SourceID, gw5SinkID, domain1ID, CF_GENIVI_STEREO}); compareRoute1.route.push_back({gw5SourceID, sink1ID, domain3ID, CF_GENIVI_STEREO}); DO_ASSERT() compareRoute1.route.clear(); - compareRoute1.route.push_back({source1ID, gw1SinkID, domain1ID, CF_GENIVI_STEREO}); - compareRoute1.route.push_back({gw1SourceID, gw3SinkID, domain2ID, CF_GENIVI_STEREO}); - compareRoute1.route.push_back({gw3SourceID, gw2SinkID, domain1ID, CF_GENIVI_STEREO}); - compareRoute1.route.push_back({gw2SourceID, gw4SinkID, domain1ID, CF_GENIVI_STEREO}); + compareRoute1.route.push_back({source1ID, gw2SinkID, domain1ID, CF_GENIVI_STEREO}); + compareRoute1.route.push_back({gw2SourceID, gw3SinkID, domain2ID, CF_GENIVI_STEREO}); + compareRoute1.route.push_back({gw3SourceID, gw1SinkID, domain1ID, CF_GENIVI_STEREO}); + compareRoute1.route.push_back({gw1SourceID, gw4SinkID, domain2ID, CF_GENIVI_STEREO}); compareRoute1.route.push_back({gw4SourceID, gw5SinkID, domain1ID, CF_GENIVI_STEREO}); compareRoute1.route.push_back({gw5SourceID, sink1ID, domain3ID, CF_GENIVI_STEREO}); DO_ASSERT() compareRoute1.route.clear(); compareRoute1.route.push_back({source1ID, gw1SinkID, domain1ID, CF_GENIVI_STEREO}); - compareRoute1.route.push_back({gw1SourceID, gw4SinkID, domain1ID, CF_GENIVI_STEREO}); + compareRoute1.route.push_back({gw1SourceID, gw3SinkID, domain2ID, CF_GENIVI_STEREO}); + compareRoute1.route.push_back({gw3SourceID, gw2SinkID, domain1ID, CF_GENIVI_STEREO}); + compareRoute1.route.push_back({gw2SourceID, gw4SinkID, domain2ID, CF_GENIVI_STEREO}); compareRoute1.route.push_back({gw4SourceID, gw5SinkID, domain1ID, CF_GENIVI_STEREO}); compareRoute1.route.push_back({gw5SourceID, sink1ID, domain3ID, CF_GENIVI_STEREO}); DO_ASSERT() compareRoute1.route.clear(); compareRoute1.route.push_back({source1ID, gw1SinkID, domain1ID, CF_GENIVI_STEREO}); - compareRoute1.route.push_back({gw1SourceID, gw4SinkID, domain1ID, CF_GENIVI_STEREO}); + compareRoute1.route.push_back({gw1SourceID, gw4SinkID, domain2ID, CF_GENIVI_STEREO}); compareRoute1.route.push_back({gw4SourceID, gw2SinkID, domain1ID, CF_GENIVI_STEREO}); compareRoute1.route.push_back({gw2SourceID, gw3SinkID, domain2ID, CF_GENIVI_STEREO}); compareRoute1.route.push_back({gw3SourceID, gw5SinkID, domain1ID, CF_GENIVI_STEREO}); compareRoute1.route.push_back({gw5SourceID, sink1ID, domain3ID, CF_GENIVI_STEREO}); DO_ASSERT() + + compareRoute1.route.clear(); + compareRoute1.route.push_back({source1ID, gw5SinkID, domain1ID, CF_GENIVI_STEREO}); + compareRoute1.route.push_back({gw5SourceID, sink1ID, domain3ID, CF_GENIVI_STEREO}); + DO_ASSERT() +#else + compareRoute1.route.clear(); + compareRoute1.route.push_back({source1ID, gw5SinkID, domain1ID, CF_GENIVI_STEREO}); + compareRoute1.route.push_back({gw5SourceID, sink1ID, domain3ID, CF_GENIVI_STEREO}); +#endif + + listRoutes.clear(); + resultNodesPath.clear(); + getAllPaths(*sourceNode, *sinkNode, listRoutes, resultNodesPath, false); + ASSERT_EQ(static_cast<uint>(1), listRoutes.size()); + DO_ASSERT() +} + +TEST_F(CAmRouterMapTest,route3Domains1Source3Gateways3Convertres1Sink) +{ + EXPECT_CALL(pMockControlInterface,getConnectionFormatChoice(_,_,_,_,_)).WillRepeatedly(DoAll(returnConnectionFormat(), Return(E_OK))); + + am_domainID_t domainID1, domainID2, domainID3; + enterDomainDB("domain1", domainID1); + enterDomainDB("domain2", domainID2); + enterDomainDB("domain3", domainID3); + + std::vector<am_CustomConnectionFormat_t> cfStereo; + cfStereo.push_back(CF_GENIVI_STEREO); + std::vector<am_CustomConnectionFormat_t> cfAnalog; + cfAnalog.push_back(CF_GENIVI_ANALOG); + std::vector<am_CustomConnectionFormat_t> cfMono; + cfMono.push_back(CF_GENIVI_MONO); + std::vector<am_CustomConnectionFormat_t> cfAuto; + cfAuto.push_back(CF_GENIVI_AUTO); + + am_sourceID_t sourceID; + enterSourceDB("source1", domainID1, cfStereo, sourceID); + am_sinkID_t gwSinkID1; + enterSinkDB("gwSink1", domainID1, cfStereo, gwSinkID1); + am_sinkID_t gwSinkID21; + enterSinkDB("gwSink21", domainID1, cfStereo, gwSinkID21); + + am_sourceID_t gwSourceID1; + enterSourceDB("gwSource1", domainID2, cfMono, gwSourceID1); + am_sinkID_t gwSinkID22; + enterSinkDB("gwSink22", domainID2, cfMono, gwSinkID22); + + am_sourceID_t gwSourceID21; + enterSourceDB("gwSource21", domainID3, cfAuto, gwSourceID21); + + am_sourceID_t gwSourceID22; + enterSourceDB("gwSource22", domainID3, cfAuto, gwSourceID22); + am_sourceID_t gwSourceID5; + enterSourceDB("gwSource5", domainID3, cfStereo, gwSourceID5); + am_sinkID_t gwSinkID5; + enterSinkDB("gwSink5", domainID3, cfAnalog, gwSinkID5); + am_sourceID_t gwSourceID3; + enterSourceDB("gwSource3", domainID3, cfAnalog, gwSourceID3); + am_sinkID_t gwSinkID3; + enterSinkDB("gwSink3", domainID3, cfAuto, gwSinkID3); + am_sourceID_t gwSourceID4; + enterSourceDB("gwSource4", domainID3, cfStereo, gwSourceID4); + am_sinkID_t gwSinkID4; + enterSinkDB("gwSink4", domainID3, cfAnalog, gwSinkID4); + am_sinkID_t sinkID; + enterSinkDB("sink1", domainID3, cfStereo, sinkID); + + std::vector<bool> matrix; + matrix.push_back(true); + am_gatewayID_t gatewayID; + enterGatewayDB("gateway1", domainID2, domainID1, cfMono, cfStereo, matrix, gwSourceID1, gwSinkID1, gatewayID); + am_gatewayID_t gatewayID22; + enterGatewayDB("gateway22", domainID3, domainID2, cfAuto, cfMono, matrix, gwSourceID22, gwSinkID22, gatewayID22); + am_gatewayID_t gatewayID21; + enterGatewayDB("gateway21", domainID3, domainID1, cfAuto, cfStereo, matrix, gwSourceID21, gwSinkID21, gatewayID21); + am_converterID_t converterID1; + enterConverterDB("converter1", domainID3, cfAnalog, cfAuto, matrix, gwSourceID3, gwSinkID3, converterID1); + am_converterID_t converterID2; + enterConverterDB("converter2", domainID3, cfStereo, cfAnalog, matrix, gwSourceID4, gwSinkID4, converterID2); + am_converterID_t converterID3; + enterConverterDB("converter3", domainID3, cfStereo, cfAnalog, matrix, gwSourceID5, gwSinkID5, converterID3); + + am::am_Source_s source; + am::am_Sink_s sink; + + pDatabaseHandler.getSinkInfoDB(sinkID, sink); + pDatabaseHandler.getSourceInfoDB(sourceID, source); + + std::vector<am_Route_s> listRoutes; + + getRoute(false, source, sink, listRoutes); + ASSERT_EQ(static_cast<uint>(4), listRoutes.size()); + + am_Route_s compareRoute1; + compareRoute1.sinkID = sinkID; + compareRoute1.sourceID = sourceID; + compareRoute1.route.push_back({sourceID, gwSinkID1, domainID1, CF_GENIVI_STEREO}); + compareRoute1.route.push_back({gwSourceID1, gwSinkID22, domainID2, CF_GENIVI_MONO}); + compareRoute1.route.push_back({gwSourceID22, gwSinkID3, domainID3, CF_GENIVI_AUTO}); + compareRoute1.route.push_back({gwSourceID3, gwSinkID4, domainID3, CF_GENIVI_ANALOG}); + compareRoute1.route.push_back({gwSourceID4, sinkID, domainID3, CF_GENIVI_STEREO}); + + am_Route_s compareRoute2; + compareRoute2.sinkID = sinkID; + compareRoute2.sourceID = sourceID; + compareRoute2.route.push_back({sourceID, gwSinkID1, domainID1, CF_GENIVI_STEREO}); + compareRoute2.route.push_back({gwSourceID1, gwSinkID22, domainID2, CF_GENIVI_MONO}); + compareRoute2.route.push_back({gwSourceID22, gwSinkID3, domainID3, CF_GENIVI_AUTO}); + compareRoute2.route.push_back({gwSourceID3, gwSinkID5, domainID3, CF_GENIVI_ANALOG}); + compareRoute2.route.push_back({gwSourceID5, sinkID, domainID3, CF_GENIVI_STEREO}); + + am_Route_s compareRoute3; + compareRoute3.sinkID = sinkID; + compareRoute3.sourceID = sourceID; + compareRoute3.route.push_back({sourceID, gwSinkID21, domainID1, CF_GENIVI_STEREO}); + compareRoute3.route.push_back({gwSourceID21, gwSinkID3, domainID3, CF_GENIVI_AUTO}); + compareRoute3.route.push_back({gwSourceID3, gwSinkID4, domainID3, CF_GENIVI_ANALOG}); + compareRoute3.route.push_back({gwSourceID4, sinkID, domainID3, CF_GENIVI_STEREO}); + + am_Route_s compareRoute4; + compareRoute4.sinkID = sinkID; + compareRoute4.sourceID = sourceID; + compareRoute4.route.push_back({sourceID, gwSinkID21, domainID1, CF_GENIVI_STEREO}); + compareRoute4.route.push_back({gwSourceID21, gwSinkID3, domainID3, CF_GENIVI_AUTO}); + compareRoute4.route.push_back({gwSourceID3, gwSinkID5, domainID3, CF_GENIVI_ANALOG}); + compareRoute4.route.push_back({gwSourceID5, sinkID, domainID3, CF_GENIVI_STEREO}); + + ASSERT_TRUE(pCF.compareRoute(compareRoute1,listRoutes[0])|| + pCF.compareRoute(compareRoute1,listRoutes[1])|| + pCF.compareRoute(compareRoute1,listRoutes[2])|| + pCF.compareRoute(compareRoute1,listRoutes[3])); + + ASSERT_TRUE(pCF.compareRoute(compareRoute2,listRoutes[0])|| + pCF.compareRoute(compareRoute2,listRoutes[1])|| + pCF.compareRoute(compareRoute2,listRoutes[2])|| + pCF.compareRoute(compareRoute2,listRoutes[3])); + + ASSERT_TRUE(pCF.compareRoute(compareRoute3,listRoutes[0])|| + pCF.compareRoute(compareRoute3,listRoutes[1])|| + pCF.compareRoute(compareRoute3,listRoutes[2])|| + pCF.compareRoute(compareRoute3,listRoutes[3])); + + ASSERT_TRUE(pCF.compareRoute(compareRoute4,listRoutes[0])|| + pCF.compareRoute(compareRoute4,listRoutes[1])|| + pCF.compareRoute(compareRoute4,listRoutes[2])|| + pCF.compareRoute(compareRoute4,listRoutes[3])); } int main(int argc, char **argv) { #ifdef WITH_DLT - CAmDltWrapper::instance()->registerApp("routing", "CAmRouterMapTest"); + CAmDltWrapper::instance()->registerApp("routing", "CAmRouterMapTest"); #else - CAmDltWrapper::instance(true)->registerApp("routing", "CAmRouterMapTest"); + CAmDltWrapper::instance(true)->registerApp("routing", "CAmRouterMapTest"); #endif - logInfo("Routing Test started "); - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); + logInfo("Routing Test started "); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); } diff --git a/AudioManagerDaemon/test/AmRouterMapTest/CAmRouterMapTest.h b/AudioManagerDaemon/test/AmRouterMapTest/CAmRouterMapTest.h index dca14c8..65ff97b 100644 --- a/AudioManagerDaemon/test/AmRouterMapTest/CAmRouterMapTest.h +++ b/AudioManagerDaemon/test/AmRouterMapTest/CAmRouterMapTest.h @@ -27,7 +27,6 @@ #include "gtest/gtest.h" #include "gmock/gmock.h" - #include <algorithm> #include <string> #include <vector> @@ -95,7 +94,13 @@ public: const am_sourceID_t & sourceID, const am_sinkID_t & sinkID, am_converterID_t & converterID); - + void getRoute(const bool onlyfree, const am_sourceID_t sourceID, const am_sinkID_t sinkID, std::vector<am_Route_s>& returnList); + void getRoute(const bool onlyfree, const am_Source_s & aSource, const am_Sink_s & aSink, std::vector<am_Route_s> & listRoutes); + void getAllPaths(CAmRoutingNode & aSource, + CAmRoutingNode & aSink, + std::vector<am_Route_s> & resultPath, + std::vector<std::vector<CAmRoutingNode*>> & resultNodesPath, + const bool includeCycles); }; } diff --git a/AudioManagerDaemon/test/CMakeLists.txt b/AudioManagerDaemon/test/CMakeLists.txt index dceb22c..149b221 100644 --- a/AudioManagerDaemon/test/CMakeLists.txt +++ b/AudioManagerDaemon/test/CMakeLists.txt @@ -20,6 +20,11 @@ cmake_minimum_required(VERSION 2.8.8) set(EXECUTABLE_OUTPUT_PATH ${TEST_EXECUTABLE_OUTPUT_PATH}) + +if(USE_BUILD_LIBS) + execute_process(COMMAND mkdir -p "${EXECUTABLE_OUTPUT_PATH}") +endif(USE_BUILD_LIBS) + add_subdirectory (AmControlInterfaceTest) add_subdirectory (AmDatabaseHandlerTest) add_subdirectory (AmMapHandlerTest) |