adding feature in the compile script:
[profile/ivi/audiomanager.git] / AudioManagerDaemon / Router.cpp
1 /**
2  * Copyright (C) 2011, BMW AG
3  *
4  * AudioManangerDeamon
5  *
6  * \file Router.cpp
7  *
8  * \date 20.05.2011
9  * \author Christian Müller (christian.ei.mueller@bmw.de)
10  *
11  * \section License
12  * GNU Lesser General Public License, version 2.1, with special exception (GENIVI clause)
13  * Copyright (C) 2011, BMW AG – Christian Müller  Christian.ei.mueller@bmw.de
14  *
15  * This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License, version 2.1, as published by the Free Software Foundation.
16  * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License, version 2.1, for more details.
17  * You should have received a copy of the GNU Lesser General Public License, version 2.1, along with this program; if not, see <http://www.gnu.org/licenses/lgpl-2.1.html>.
18  * Note that the copyright holders assume that the GNU Lesser General Public License, version 2.1, may also be applicable to programs even in cases in which the program is not a library in the technical sense.
19  * Linking AudioManager statically or dynamically with other modules is making a combined work based on AudioManager. You may license such other modules under the GNU Lesser General Public License, version 2.1. If you do not want to license your linked modules under the GNU Lesser General Public License, version 2.1, you may use the program under the following exception.
20  * As a special exception, the copyright holders of AudioManager give you permission to combine AudioManager with software programs or libraries that are released under any license unless such a combination is not permitted by the license of such a software program or library. You may copy and distribute such a system following the terms of the GNU Lesser General Public License, version 2.1, including this special exception, for AudioManager and the licenses of the other code concerned.
21  * Note that people who make modified versions of AudioManager are not obligated to grant this special exception for their modified versions; it is their choice whether to do so. The GNU Lesser General Public License, version 2.1, gives permission to release a modified version without this exception; this exception also makes it possible to release a modified version which carries forward this exception.
22  *
23  *
24  */
25
26 #include <qstring.h>
27 #include <QMutableListIterator>
28 #include <iostream>
29 #include <stdio.h>
30
31 #include "DataBaseHandler.h"
32 #include "Router.h"
33
34 Router::Router() {
35 }
36
37 Router::~Router() {
38 }
39
40 void Router::registerDatabasehandler(DataBaseHandler* db_handler) {
41         m_dbHandler = db_handler;
42 }
43
44 bool Router::get_Route_from_Source_ID_to_Sink_ID(const bool onlyfree,
45                 const source_t Source_ID, const sink_t Sink_ID,
46                 QList<genRoute_t>* ReturnList) {
47
48         domain_t Source_Domain = m_dbHandler->get_Domain_ID_from_Source_ID(
49                         Source_ID); //first find out in which domains the source and sink are
50         domain_t Sink_Domain = m_dbHandler->get_Domain_ID_from_Sink_ID(Sink_ID);
51
52         if (Source_Domain == -1 || Sink_Domain == -1) {
53                 return false;
54         } //if source or sink does not exists, exit here
55
56         RoutingTree routingtree(Source_Domain); //Build up a Tree from the Source_Domain to every other domain.
57         QList<RoutingTreeItem*> flattree; //This list is the flat tree
58         QList<RoutingTreeItem*> matchtree; //This List holds all TreeItems which have the right Domain Sink IDs
59         QList<gateway_t> gwids; //holds all gateway ids of the route
60         genRoutingElement_t element;
61         QList<genRoutingElement_t> actualRoutingElement;//intermediate list of current routing pairs
62         genRoute_t actualRoute; //holds the actual Route
63         source_t ReturnSource = 0;
64         sink_t ReturnSink = 0;
65         source_t LastSource = 0;
66         domain_t ReturnDomain = 0;
67
68         //TODO: kind of unclean. The separation between database and router could be better.
69         m_dbHandler->get_Domain_ID_Tree(onlyfree, &routingtree, &flattree); //Build up the tree out of the database as
70
71         //we go through the returned flattree and look for our sink, after that flattree holds only treeItems that match
72         foreach (RoutingTreeItem* rTree,flattree)
73                 {
74                         if (rTree->returnDomainID() == Sink_Domain) {
75                                 matchtree.append(rTree);
76                         }
77                 }
78
79         //No we need to trace back the routes for each entry in matchtree
80         foreach (RoutingTreeItem* match, matchtree)
81                 {
82                         //getting the route for the actual item
83                         actualRoute.len = routingtree.getRoute(match, &gwids); //This gives only the Gateway IDs we need more
84
85                         //go throught the gatewayids and get more information
86                         for (int i = 0; i < gwids.length(); i++) {
87                                 m_dbHandler->get_Gateway_Source_Sink_Domain_ID_from_ID(
88                                                 gwids.value(i), &ReturnSource, &ReturnSink,
89                                                 &ReturnDomain);
90                                 //first routing pair is source to ReturnSink of course;
91                                 if (i == 0) {
92                                         element.source = Source_ID;
93                                         element.sink = ReturnSink;
94                                         element.Domain_ID = Source_Domain;
95                                 } else {
96                                         element.source = LastSource;
97                                         element.sink = ReturnSink;
98                                         element.Domain_ID = ReturnDomain;
99                                 }
100                                 actualRoutingElement.append(element);
101                                 LastSource = ReturnSource;
102                         }
103                         element.source = LastSource;
104                         element.sink = Sink_ID;
105                         element.Domain_ID = Sink_Domain;
106                         actualRoutingElement.append(element);
107
108                         actualRoute.Source_ID = Source_ID;
109                         actualRoute.Sink_ID = Sink_ID;
110                         actualRoute.route = actualRoutingElement;
111                         ReturnList->append(actualRoute);
112                 }
113
114         return true;
115         //TODO: return actual status !
116 }
117
118 RoutingTreeItem::RoutingTreeItem(const domain_t Domain_Id,
119                 const gateway_t Gateway_Id, RoutingTreeItem *parent) {
120         parentItem = parent;
121         m_domainID = Domain_Id;
122         m_gatewayID = Gateway_Id;
123 }
124
125 RoutingTreeItem::RoutingTreeItem() {
126
127 }
128
129 RoutingTreeItem::~RoutingTreeItem() {
130         qDeleteAll(childItems);
131 }
132
133 void RoutingTreeItem::appendChild(RoutingTreeItem *item) {
134         childItems.append(item);
135 }
136
137 RoutingTreeItem *RoutingTreeItem::return_Parent() {
138         return parentItem;
139 }
140
141 domain_t RoutingTreeItem::returnDomainID() {
142         return m_domainID;
143 }
144
145 gateway_t RoutingTreeItem::returnGatewayID() {
146         return m_gatewayID;
147 }
148
149 RoutingTree::RoutingTree(const domain_t Root_ID) :
150         m_rootItem(RoutingTreeItem(Root_ID)) {
151 }
152
153 RoutingTree::~RoutingTree() {
154 }
155
156 RoutingTreeItem* RoutingTree::insertItem(const domain_t Domain_ID,
157                 const gateway_t Gateway_ID, RoutingTreeItem *parentItem) {
158         RoutingTreeItem *newTree = new RoutingTreeItem(Domain_ID, Gateway_ID,
159                         parentItem);
160         parentItem->appendChild(newTree);
161         m_allChildList.append(newTree);
162         return newTree;
163 }
164
165 int RoutingTree::getRoute(RoutingTreeItem* Targetitem, QList<gateway_t>* route) {
166         int hopps = 0;
167         RoutingTreeItem *parentItem = Targetitem;
168         while (parentItem != &m_rootItem) {
169                 route->prepend(parentItem->returnGatewayID());
170                 hopps++;
171                 parentItem = parentItem->return_Parent();
172         }
173         return hopps;
174 }
175
176 int RoutingTree::returnRootDomainID() {
177         return m_rootItem.returnDomainID();
178 }
179
180 RoutingTreeItem* RoutingTree::returnRootItem() {
181         return &m_rootItem;
182 }
183
184 void Bushandler::load_Bus_plugins() {
185         RoutingSendInterface *b = NULL;
186         char BusName[40];
187         Bus newBus;
188         foreach (QObject *plugin, QPluginLoader::staticInstances())
189                 {
190                         strcpy(BusName, "");
191                         RoutingInterfaceFactory* busInterfaceFactory = qobject_cast<
192                                         RoutingInterfaceFactory *> (plugin);
193                         if (busInterfaceFactory) {
194                                 b = busInterfaceFactory->returnInstance();
195                                 b->return_BusName(BusName);
196                                 newBus.Name = QString(BusName);
197                                 newBus.sendInterface = b;
198                                 Busses.append(newBus);
199                                 QObject::connect((const QObject*) this,
200                                                 SIGNAL (signal_system_ready(void)), (const QObject*) b,
201                                                 SLOT(slot_system_ready(void)));
202                                 DLT_LOG(AudioManager,DLT_LOG_INFO, DLT_STRING("Bushandler:Found new bus interface"), DLT_STRING(newBus.Name.toAscii()));
203                         }
204                 }
205 }
206
207 void Bushandler::StartupInterfaces() {
208         foreach (Bus bus, Busses)
209                 {
210                         bus.sendInterface->startup_interface(m_receiver);
211                         DLT_LOG(AudioManager,DLT_LOG_INFO, DLT_STRING("Bushandler:Started Interface"), DLT_STRING(bus.Name.toAscii()));
212                 }
213         emit signal_system_ready();
214 }
215
216 void Bushandler::registerReceiver(RoutingReceiver * receiver) {
217         m_receiver = receiver;
218 }
219
220 RoutingSendInterface* Bushandler::getInterfaceforBus(QString bus) {
221         foreach (Bus b, Busses)
222                 {
223                         if (b.Name.compare(bus) == 0) {
224                                 return b.sendInterface;
225                         }
226                 }
227         return NULL;
228 }
229