blob: 6c6dad3a995abcfda5ab7e155d5144fe47491d78 [file] [log] [blame]
akmhoque53353462014-04-22 08:43:45 -05001#include <iostream>
2#include <cmath>
3#include "lsdb.hpp"
4#include "routing-table-calculator.hpp"
5#include "map.hpp"
6#include "lsa.hpp"
7#include "nexthop.hpp"
8#include "nlsr.hpp"
9
10namespace nlsr {
11
12using namespace std;
13
14void
15RoutingTableCalculator::allocateAdjMatrix()
16{
17 adjMatrix = new double*[numOfRouter];
18 for (int i = 0; i < numOfRouter; ++i)
19 {
20 adjMatrix[i] = new double[numOfRouter];
21 }
22}
23
24void
25RoutingTableCalculator::initMatrix()
26{
27 for (int i = 0; i < numOfRouter; i++)
28 {
29 for (int j = 0; j < numOfRouter; j++)
30 adjMatrix[i][j] = 0;
31 }
32}
33
34void
35RoutingTableCalculator::makeAdjMatrix(Nlsr& pnlsr, Map pMap)
36{
37 std::list<AdjLsa> adjLsdb = pnlsr.getLsdb().getAdjLsdb();
38 for (std::list<AdjLsa>::iterator it = adjLsdb.begin();
39 it != adjLsdb.end() ; it++)
40 {
41 string linkStartRouter = (*it).getOrigRouter();
42 int row = pMap.getMappingNoByRouterName(linkStartRouter);
43 std::list<Adjacent> adl = (*it).getAdl().getAdjList();
44 for (std::list<Adjacent>::iterator itAdl = adl.begin();
45 itAdl != adl.end() ; itAdl++)
46 {
47 string linkEndRouter = (*itAdl).getName();
48 int col = pMap.getMappingNoByRouterName(linkEndRouter);
49 double cost = (*itAdl).getLinkCost();
50 if ((row >= 0 && row < numOfRouter) && (col >= 0 && col < numOfRouter))
51 {
52 adjMatrix[row][col] = cost;
53 }
54 }
55 }
56}
57
58void
59RoutingTableCalculator::printAdjMatrix()
60{
61 for (int i = 0; i < numOfRouter; i++)
62 {
63 for (int j = 0; j < numOfRouter; j++)
64 printf("%f ", adjMatrix[i][j]);
65 printf("\n");
66 }
67}
68
69void
70RoutingTableCalculator::adjustAdMatrix(int source, int link, double linkCost)
71{
72 for (int i = 0; i < numOfRouter; i++)
73 {
74 if (i == link)
75 {
76 adjMatrix[source][i] = linkCost;
77 }
78 else
79 {
80 adjMatrix[source][i] = 0;
81 }
82 }
83}
84
85int
86RoutingTableCalculator::getNumOfLinkfromAdjMatrix(int sRouter)
87{
88 int noLink = 0;
89 for (int i = 0; i < numOfRouter; i++)
90 {
91 if (adjMatrix[sRouter][i] > 0)
92 {
93 noLink++;
94 }
95 }
96 return noLink;
97}
98
99void
100RoutingTableCalculator::getLinksFromAdjMatrix(int* links,
101 double* linkCosts, int source)
102{
103 int j = 0;
104 for (int i = 0; i < numOfRouter; i++)
105 {
106 if (adjMatrix[source][i] > 0)
107 {
108 links[j] = i;
109 linkCosts[j] = adjMatrix[source][i];
110 j++;
111 }
112 }
113}
114
115void
116RoutingTableCalculator::freeAdjMatrix()
117{
118 for (int i = 0; i < numOfRouter; ++i)
119 {
120 delete [] adjMatrix[i];
121 }
122 delete [] adjMatrix;
123}
124
125
126void
127RoutingTableCalculator::allocateLinks()
128{
129 links = new int[vNoLink];
130}
131
132void
133RoutingTableCalculator::allocateLinkCosts()
134{
135 linkCosts = new double[vNoLink];
136}
137
138
139void
140RoutingTableCalculator::freeLinks()
141{
142 delete [] links;
143}
144void
145RoutingTableCalculator::freeLinksCosts()
146{
147 delete [] linkCosts;
148}
149
150void
151LinkStateRoutingTableCalculator::calculatePath(Map& pMap,
152 RoutingTable& rt, Nlsr& pnlsr)
153{
154 std::cout << "LinkStateRoutingTableCalculator::calculatePath Called" <<
155 std::endl;
156 allocateAdjMatrix();
157 initMatrix();
158 makeAdjMatrix(pnlsr, pMap);
159 std::cout << pMap;
160 printAdjMatrix();
161 string routerName = pnlsr.getConfParameter().getRouterPrefix();
162 int sourceRouter = pMap.getMappingNoByRouterName(routerName);
163 //int noLink=getNumOfLinkfromAdjMatrix(sourceRouter);
164 allocateParent();
165 allocateDistance();
166 if (pnlsr.getConfParameter().getMaxFacesPerPrefix() == 1)
167 {
168 // Single Path
169 doDijkstraPathCalculation(sourceRouter);
170 // print all ls path -- debugging purpose
171 printAllLsPath(sourceRouter);
172 // update routing table
173 addAllLsNextHopsToRoutingTable(pnlsr, rt, pMap, sourceRouter);
174 }
175 else
176 {
177 // Multi Path
178 setNoLink(getNumOfLinkfromAdjMatrix(sourceRouter));
179 allocateLinks();
180 allocateLinkCosts();
181 getLinksFromAdjMatrix(links, linkCosts, sourceRouter);
182 for (int i = 0 ; i < vNoLink; i++)
183 {
184 adjustAdMatrix(sourceRouter, links[i], linkCosts[i]);
185 printAdjMatrix();
186 doDijkstraPathCalculation(sourceRouter);
187 // print all ls path -- debugging purpose
188 printAllLsPath(sourceRouter);
189 //update routing table
190 addAllLsNextHopsToRoutingTable(pnlsr, rt, pMap, sourceRouter);
191 }
192 freeLinks();
193 freeLinksCosts();
194 }
195 freeParent();
196 freeDistance();
197 freeAdjMatrix();
198}
199
200void
201LinkStateRoutingTableCalculator::doDijkstraPathCalculation(int sourceRouter)
202{
203 int i;
204 int v, u;
205 int* Q = new int[numOfRouter];
206 int head = 0;
207 /* Initiate the Parent */
208 for (i = 0 ; i < numOfRouter; i++)
209 {
210 m_parent[i] = EMPTY_PARENT;
211 m_distance[i] = INF_DISTANCE;
212 Q[i] = i;
213 }
214 if (sourceRouter != NO_MAPPING_NUM)
215 {
216 m_distance[sourceRouter] = 0;
217 sortQueueByDistance(Q, m_distance, head, numOfRouter);
218 while (head < numOfRouter)
219 {
220 u = Q[head];
221 if (m_distance[u] == INF_DISTANCE)
222 {
223 break;
224 }
225 for (v = 0 ; v < numOfRouter; v++)
226 {
227 if (adjMatrix[u][v] > 0)
228 {
229 if (isNotExplored(Q, v, head + 1, numOfRouter))
230 {
231 if (m_distance[u] + adjMatrix[u][v] < m_distance[v])
232 {
233 m_distance[v] = m_distance[u] + adjMatrix[u][v] ;
234 m_parent[v] = u;
235 }
236 }
237 }
238 }
239 head++;
240 sortQueueByDistance(Q, m_distance, head, numOfRouter);
241 }
242 }
243 delete [] Q;
244}
245
246void
247LinkStateRoutingTableCalculator::addAllLsNextHopsToRoutingTable(Nlsr& pnlsr,
248 RoutingTable& rt, Map& pMap, int sourceRouter)
249{
250 std::cout <<
251 "LinkStateRoutingTableCalculator::addAllNextHopsToRoutingTable Called";
252 std::cout << std::endl;
253 int nextHopRouter = 0;
254 for (int i = 0; i < numOfRouter ; i++)
255 {
256 if (i != sourceRouter)
257 {
258 nextHopRouter = getLsNextHop(i, sourceRouter);
259 if (nextHopRouter != NO_NEXT_HOP)
260 {
261 double routeCost = m_distance[i];
262 string nextHopRouterName =
263 pMap.getRouterNameByMappingNo(nextHopRouter);
264 int nxtHopFace =
265 pnlsr.getAdl().getAdjacent(nextHopRouterName).getConnectingFace();
266 std::cout << "Dest Router: " << pMap.getRouterNameByMappingNo(i) << std::endl;
267 std::cout << "Next hop Router: " << nextHopRouterName << std::endl;
268 std::cout << "Next hop Face: " << nxtHopFace << std::endl;
269 std::cout << "Route Cost: " << routeCost << std::endl;
270 std::cout << std::endl;
271 // Add next hop to routing table
272 NextHop nh(nxtHopFace, routeCost);
273 rt.addNextHop(pMap.getRouterNameByMappingNo(i), nh);
274 }
275 }
276 }
277}
278
279int
280LinkStateRoutingTableCalculator::getLsNextHop(int dest, int source)
281{
282 int nextHop = NO_NEXT_HOP;
283 while (m_parent[dest] != EMPTY_PARENT)
284 {
285 nextHop = dest;
286 dest = m_parent[dest];
287 }
288 if (dest != source)
289 {
290 nextHop = NO_NEXT_HOP;
291 }
292 return nextHop;
293}
294
295void
296LinkStateRoutingTableCalculator::printAllLsPath(int sourceRouter)
297{
298 std::cout << "LinkStateRoutingTableCalculator::printAllLsPath Called" <<
299 std::endl;
300 std::cout << "Source Router: " << sourceRouter << std::endl;
301 for (int i = 0; i < numOfRouter ; i++)
302 {
303 if (i != sourceRouter)
304 {
305 printLsPath(i);
306 std::cout << std::endl;
307 }
308 }
309}
310
311void
312LinkStateRoutingTableCalculator::printLsPath(int destRouter)
313{
314 if (m_parent[destRouter] != EMPTY_PARENT)
315 {
316 printLsPath(m_parent[destRouter]);
317 }
318 std:: cout << " " << destRouter;
319}
320
321void
322LinkStateRoutingTableCalculator::sortQueueByDistance(int* Q,
323 double* dist, int start, int element)
324{
325 for (int i = start ; i < element ; i++)
326 {
327 for (int j = i + 1; j < element; j++)
328 {
329 if (dist[Q[j]] < dist[Q[i]])
330 {
331 int tempU = Q[j];
332 Q[j] = Q[i];
333 Q[i] = tempU;
334 }
335 }
336 }
337}
338
339int
340LinkStateRoutingTableCalculator::isNotExplored(int* Q,
341 int u, int start, int element)
342{
343 int ret = 0;
344 for (int i = start; i < element; i++)
345 {
346 if (Q[i] == u)
347 {
348 ret = 1;
349 break;
350 }
351 }
352 return ret;
353}
354
355void
356LinkStateRoutingTableCalculator::allocateParent()
357{
358 m_parent = new int[numOfRouter];
359}
360
361void
362LinkStateRoutingTableCalculator::allocateDistance()
363{
364 m_distance = new double[numOfRouter];
365}
366
367void
368LinkStateRoutingTableCalculator::freeParent()
369{
370 delete [] m_parent;
371}
372
373void LinkStateRoutingTableCalculator::freeDistance()
374{
375 delete [] m_distance;
376}
377
378
379
380void
381HypRoutingTableCalculator::calculatePath(Map& pMap,
382 RoutingTable& rt, Nlsr& pnlsr)
383{
384 makeAdjMatrix(pnlsr, pMap);
385 string routerName = pnlsr.getConfParameter().getRouterPrefix();
386 int sourceRouter = pMap.getMappingNoByRouterName(routerName);
387 int noLink = getNumOfLinkfromAdjMatrix(sourceRouter);
388 setNoLink(noLink);
389 allocateLinks();
390 allocateLinkCosts();
391 getLinksFromAdjMatrix(links, linkCosts, sourceRouter);
392 for (int i = 0 ; i < numOfRouter ; ++i)
393 {
394 int k = 0;
395 if (i != sourceRouter)
396 {
397 allocateLinkFaces();
398 allocateDistanceToNeighbor();
399 allocateDistFromNbrToDest();
400 for (int j = 0; j < vNoLink; j++)
401 {
402 string nextHopRouterName = pMap.getRouterNameByMappingNo(links[j]);
403 int nextHopFace =
404 pnlsr.getAdl().getAdjacent(nextHopRouterName).getConnectingFace();
405 double distToNbr = getHyperbolicDistance(pnlsr, pMap,
406 sourceRouter, links[j]);
407 double distToDestFromNbr = getHyperbolicDistance(pnlsr,
408 pMap, links[j], i);
409 if (distToDestFromNbr >= 0)
410 {
411 m_linkFaces[k] = nextHopFace;
412 m_distanceToNeighbor[k] = distToNbr;
413 m_distFromNbrToDest[k] = distToDestFromNbr;
414 k++;
415 }
416 }
417 addHypNextHopsToRoutingTable(pnlsr, pMap, rt, k, i);
418 freeLinkFaces();
419 freeDistanceToNeighbor();
420 freeDistFromNbrToDest();
421 }
422 }
423 freeLinks();
424 freeLinksCosts();
425 freeAdjMatrix();
426}
427
428void
429HypRoutingTableCalculator::addHypNextHopsToRoutingTable(Nlsr& pnlsr, Map& pMap,
430 RoutingTable& rt, int noFaces, int dest)
431{
432 for (int i = 0 ; i < noFaces ; ++i)
433 {
434 string destRouter = pMap.getRouterNameByMappingNo(dest);
435 NextHop nh(m_linkFaces[i], m_distFromNbrToDest[i]);
436 rt.addNextHop(destRouter, nh);
437 if (m_isDryRun)
438 {
439 rt.addNextHopToDryTable(destRouter, nh);
440 }
441 }
442}
443
444double
445HypRoutingTableCalculator::getHyperbolicDistance(Nlsr& pnlsr,
446 Map& pMap, int src, int dest)
447{
448 double distance = 0.0;
449 string srcRouterKey = pMap.getRouterNameByMappingNo(src) + "/3";
450 string destRouterKey = pMap.getRouterNameByMappingNo(dest) + "/3";
451 double srcRadius = (pnlsr.getLsdb().getCorLsa(
452 srcRouterKey).first).getCorRadius();
453 double srcTheta = (pnlsr.getLsdb().getCorLsa(srcRouterKey).first).getCorTheta();
454 double destRadius = (pnlsr.getLsdb().getCorLsa(
455 destRouterKey).first).getCorRadius();
456 double destTheta = (pnlsr.getLsdb().getCorLsa(
457 destRouterKey).first).getCorTheta();
458 double diffTheta = fabs(srcTheta - destTheta);
459 if (diffTheta > MATH_PI)
460 {
461 diffTheta = 2 * MATH_PI - diffTheta;
462 }
463 if (srcRadius != -1 && destRadius != -1)
464 {
465 if (diffTheta == 0)
466 distance = fabs(srcRadius - destRadius);
467 else
468 distance = acosh((cosh(srcRadius) * cosh(destRadius)) -
469 (sinh(srcRadius) * sinh(destRadius) * cos(diffTheta)));
470 }
471 else
472 {
473 distance = -1;
474 }
475 return distance;
476}
477
478void
479HypRoutingTableCalculator::allocateLinkFaces()
480{
481 m_linkFaces = new int[vNoLink];
482}
483
484void
485HypRoutingTableCalculator::allocateDistanceToNeighbor()
486{
487 m_distanceToNeighbor = new double[vNoLink];
488}
489
490void
491HypRoutingTableCalculator::allocateDistFromNbrToDest()
492{
493 m_distFromNbrToDest = new double[vNoLink];
494}
495
496void
497HypRoutingTableCalculator::freeLinkFaces()
498{
499 delete [] m_linkFaces;
500}
501
502void
503HypRoutingTableCalculator::freeDistanceToNeighbor()
504{
505 delete [] m_distanceToNeighbor;
506}
507
508void
509HypRoutingTableCalculator::freeDistFromNbrToDest()
510{
511 delete [] m_distFromNbrToDest;
512}
513
514}//namespace nlsr