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