blob: 7eab0eb477592e28526ac3d949f5da25a3dba4e2 [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];
akmhoque157b0a42014-05-13 00:26:37 -050018 for (int i = 0; i < numOfRouter; ++i) {
akmhoque53353462014-04-22 08:43:45 -050019 adjMatrix[i] = new double[numOfRouter];
20 }
21}
22
23void
24RoutingTableCalculator::initMatrix()
25{
akmhoque157b0a42014-05-13 00:26:37 -050026 for (int i = 0; i < numOfRouter; i++) {
27 for (int j = 0; j < numOfRouter; j++) {
akmhoque53353462014-04-22 08:43:45 -050028 adjMatrix[i][j] = 0;
akmhoque157b0a42014-05-13 00:26:37 -050029 }
akmhoque53353462014-04-22 08:43:45 -050030 }
31}
32
33void
34RoutingTableCalculator::makeAdjMatrix(Nlsr& pnlsr, Map pMap)
35{
36 std::list<AdjLsa> adjLsdb = pnlsr.getLsdb().getAdjLsdb();
37 for (std::list<AdjLsa>::iterator it = adjLsdb.begin();
akmhoque157b0a42014-05-13 00:26:37 -050038 it != adjLsdb.end() ; it++) {
akmhoque31d1d4b2014-05-05 22:08:14 -050039 int row = pMap.getMappingNoByRouterName((*it).getOrigRouter());
akmhoque53353462014-04-22 08:43:45 -050040 std::list<Adjacent> adl = (*it).getAdl().getAdjList();
41 for (std::list<Adjacent>::iterator itAdl = adl.begin();
akmhoque157b0a42014-05-13 00:26:37 -050042 itAdl != adl.end() ; itAdl++) {
akmhoque31d1d4b2014-05-05 22:08:14 -050043 int col = pMap.getMappingNoByRouterName((*itAdl).getName());
akmhoque53353462014-04-22 08:43:45 -050044 double cost = (*itAdl).getLinkCost();
akmhoque157b0a42014-05-13 00:26:37 -050045 if ((row >= 0 && row < numOfRouter) && (col >= 0 && col < numOfRouter)) {
akmhoque53353462014-04-22 08:43:45 -050046 adjMatrix[row][col] = cost;
47 }
48 }
49 }
50}
51
52void
53RoutingTableCalculator::printAdjMatrix()
54{
akmhoque157b0a42014-05-13 00:26:37 -050055 for (int i = 0; i < numOfRouter; i++) {
56 for (int j = 0; j < numOfRouter; j++) {
akmhoque53353462014-04-22 08:43:45 -050057 printf("%f ", adjMatrix[i][j]);
akmhoque157b0a42014-05-13 00:26:37 -050058 }
akmhoque53353462014-04-22 08:43:45 -050059 printf("\n");
60 }
61}
62
63void
64RoutingTableCalculator::adjustAdMatrix(int source, int link, double linkCost)
65{
akmhoque157b0a42014-05-13 00:26:37 -050066 for (int i = 0; i < numOfRouter; i++) {
67 if (i == link) {
akmhoque53353462014-04-22 08:43:45 -050068 adjMatrix[source][i] = linkCost;
69 }
akmhoque157b0a42014-05-13 00:26:37 -050070 else {
akmhoque53353462014-04-22 08:43:45 -050071 adjMatrix[source][i] = 0;
72 }
73 }
74}
75
76int
77RoutingTableCalculator::getNumOfLinkfromAdjMatrix(int sRouter)
78{
79 int noLink = 0;
akmhoque157b0a42014-05-13 00:26:37 -050080 for (int i = 0; i < numOfRouter; i++) {
81 if (adjMatrix[sRouter][i] > 0) {
akmhoque53353462014-04-22 08:43:45 -050082 noLink++;
83 }
84 }
85 return noLink;
86}
87
88void
89RoutingTableCalculator::getLinksFromAdjMatrix(int* links,
90 double* linkCosts, int source)
91{
92 int j = 0;
akmhoque157b0a42014-05-13 00:26:37 -050093 for (int i = 0; i < numOfRouter; i++) {
94 if (adjMatrix[source][i] > 0) {
akmhoque53353462014-04-22 08:43:45 -050095 links[j] = i;
96 linkCosts[j] = adjMatrix[source][i];
97 j++;
98 }
99 }
100}
101
102void
103RoutingTableCalculator::freeAdjMatrix()
104{
akmhoque157b0a42014-05-13 00:26:37 -0500105 for (int i = 0; i < numOfRouter; ++i) {
akmhoque53353462014-04-22 08:43:45 -0500106 delete [] adjMatrix[i];
107 }
108 delete [] adjMatrix;
109}
110
111
112void
113RoutingTableCalculator::allocateLinks()
114{
115 links = new int[vNoLink];
116}
117
118void
119RoutingTableCalculator::allocateLinkCosts()
120{
121 linkCosts = new double[vNoLink];
122}
123
124
125void
126RoutingTableCalculator::freeLinks()
127{
128 delete [] links;
129}
130void
131RoutingTableCalculator::freeLinksCosts()
132{
133 delete [] linkCosts;
134}
135
136void
137LinkStateRoutingTableCalculator::calculatePath(Map& pMap,
138 RoutingTable& rt, Nlsr& pnlsr)
139{
140 std::cout << "LinkStateRoutingTableCalculator::calculatePath Called" <<
141 std::endl;
142 allocateAdjMatrix();
143 initMatrix();
144 makeAdjMatrix(pnlsr, pMap);
145 std::cout << pMap;
146 printAdjMatrix();
akmhoque31d1d4b2014-05-05 22:08:14 -0500147 int sourceRouter = pMap.getMappingNoByRouterName(pnlsr.getConfParameter().getRouterPrefix());
akmhoque53353462014-04-22 08:43:45 -0500148 //int noLink=getNumOfLinkfromAdjMatrix(sourceRouter);
149 allocateParent();
150 allocateDistance();
akmhoque157b0a42014-05-13 00:26:37 -0500151 if (pnlsr.getConfParameter().getMaxFacesPerPrefix() == 1) {
akmhoque53353462014-04-22 08:43:45 -0500152 // Single Path
153 doDijkstraPathCalculation(sourceRouter);
154 // print all ls path -- debugging purpose
155 printAllLsPath(sourceRouter);
156 // update routing table
157 addAllLsNextHopsToRoutingTable(pnlsr, rt, pMap, sourceRouter);
158 }
akmhoque157b0a42014-05-13 00:26:37 -0500159 else {
akmhoque53353462014-04-22 08:43:45 -0500160 // Multi Path
161 setNoLink(getNumOfLinkfromAdjMatrix(sourceRouter));
162 allocateLinks();
163 allocateLinkCosts();
164 getLinksFromAdjMatrix(links, linkCosts, sourceRouter);
akmhoque157b0a42014-05-13 00:26:37 -0500165 for (int i = 0 ; i < vNoLink; i++) {
akmhoque53353462014-04-22 08:43:45 -0500166 adjustAdMatrix(sourceRouter, links[i], linkCosts[i]);
167 printAdjMatrix();
168 doDijkstraPathCalculation(sourceRouter);
169 // print all ls path -- debugging purpose
170 printAllLsPath(sourceRouter);
171 //update routing table
172 addAllLsNextHopsToRoutingTable(pnlsr, rt, pMap, sourceRouter);
173 }
174 freeLinks();
175 freeLinksCosts();
176 }
177 freeParent();
178 freeDistance();
179 freeAdjMatrix();
180}
181
182void
183LinkStateRoutingTableCalculator::doDijkstraPathCalculation(int sourceRouter)
184{
185 int i;
186 int v, u;
187 int* Q = new int[numOfRouter];
188 int head = 0;
189 /* Initiate the Parent */
akmhoque157b0a42014-05-13 00:26:37 -0500190 for (i = 0 ; i < numOfRouter; i++) {
akmhoque53353462014-04-22 08:43:45 -0500191 m_parent[i] = EMPTY_PARENT;
192 m_distance[i] = INF_DISTANCE;
193 Q[i] = i;
194 }
akmhoque157b0a42014-05-13 00:26:37 -0500195 if (sourceRouter != NO_MAPPING_NUM) {
akmhoque53353462014-04-22 08:43:45 -0500196 m_distance[sourceRouter] = 0;
197 sortQueueByDistance(Q, m_distance, head, numOfRouter);
akmhoque157b0a42014-05-13 00:26:37 -0500198 while (head < numOfRouter) {
akmhoque53353462014-04-22 08:43:45 -0500199 u = Q[head];
akmhoque157b0a42014-05-13 00:26:37 -0500200 if (m_distance[u] == INF_DISTANCE) {
akmhoque53353462014-04-22 08:43:45 -0500201 break;
202 }
akmhoque157b0a42014-05-13 00:26:37 -0500203 for (v = 0 ; v < numOfRouter; v++) {
204 if (adjMatrix[u][v] > 0) {
205 if (isNotExplored(Q, v, head + 1, numOfRouter)) {
206 if (m_distance[u] + adjMatrix[u][v] < m_distance[v]) {
akmhoque53353462014-04-22 08:43:45 -0500207 m_distance[v] = m_distance[u] + adjMatrix[u][v] ;
208 m_parent[v] = u;
209 }
210 }
211 }
212 }
213 head++;
214 sortQueueByDistance(Q, m_distance, head, numOfRouter);
215 }
216 }
217 delete [] Q;
218}
219
220void
221LinkStateRoutingTableCalculator::addAllLsNextHopsToRoutingTable(Nlsr& pnlsr,
222 RoutingTable& rt, Map& pMap, int sourceRouter)
223{
224 std::cout <<
225 "LinkStateRoutingTableCalculator::addAllNextHopsToRoutingTable Called";
226 std::cout << std::endl;
227 int nextHopRouter = 0;
akmhoque157b0a42014-05-13 00:26:37 -0500228 for (int i = 0; i < numOfRouter ; i++) {
229 if (i != sourceRouter) {
akmhoque53353462014-04-22 08:43:45 -0500230 nextHopRouter = getLsNextHop(i, sourceRouter);
akmhoque157b0a42014-05-13 00:26:37 -0500231 if (nextHopRouter != NO_NEXT_HOP) {
akmhoque53353462014-04-22 08:43:45 -0500232 double routeCost = m_distance[i];
akmhoque31d1d4b2014-05-05 22:08:14 -0500233 ndn::Name nextHopRouterName = pMap.getRouterNameByMappingNo(nextHopRouter);
akmhoque157b0a42014-05-13 00:26:37 -0500234 std::string nextHopFace =
235 pnlsr.getAdjacencyList().getAdjacent(nextHopRouterName).getConnectingFaceUri();
akmhoque53353462014-04-22 08:43:45 -0500236 std::cout << "Dest Router: " << pMap.getRouterNameByMappingNo(i) << std::endl;
237 std::cout << "Next hop Router: " << nextHopRouterName << std::endl;
akmhoque157b0a42014-05-13 00:26:37 -0500238 std::cout << "Next hop Face: " << nextHopFace << std::endl;
akmhoque53353462014-04-22 08:43:45 -0500239 std::cout << "Route Cost: " << routeCost << std::endl;
240 std::cout << std::endl;
241 // Add next hop to routing table
akmhoque157b0a42014-05-13 00:26:37 -0500242 NextHop nh(nextHopFace, routeCost);
akmhoque53353462014-04-22 08:43:45 -0500243 rt.addNextHop(pMap.getRouterNameByMappingNo(i), nh);
244 }
245 }
246 }
247}
248
249int
250LinkStateRoutingTableCalculator::getLsNextHop(int dest, int source)
251{
252 int nextHop = NO_NEXT_HOP;
akmhoque157b0a42014-05-13 00:26:37 -0500253 while (m_parent[dest] != EMPTY_PARENT) {
akmhoque53353462014-04-22 08:43:45 -0500254 nextHop = dest;
255 dest = m_parent[dest];
256 }
akmhoque157b0a42014-05-13 00:26:37 -0500257 if (dest != source) {
akmhoque53353462014-04-22 08:43:45 -0500258 nextHop = NO_NEXT_HOP;
259 }
260 return nextHop;
261}
262
263void
264LinkStateRoutingTableCalculator::printAllLsPath(int sourceRouter)
265{
266 std::cout << "LinkStateRoutingTableCalculator::printAllLsPath Called" <<
267 std::endl;
268 std::cout << "Source Router: " << sourceRouter << std::endl;
akmhoque157b0a42014-05-13 00:26:37 -0500269 for (int i = 0; i < numOfRouter ; i++) {
270 if (i != sourceRouter) {
akmhoque53353462014-04-22 08:43:45 -0500271 printLsPath(i);
272 std::cout << std::endl;
273 }
274 }
275}
276
277void
278LinkStateRoutingTableCalculator::printLsPath(int destRouter)
279{
akmhoque157b0a42014-05-13 00:26:37 -0500280 if (m_parent[destRouter] != EMPTY_PARENT) {
akmhoque53353462014-04-22 08:43:45 -0500281 printLsPath(m_parent[destRouter]);
282 }
283 std:: cout << " " << destRouter;
284}
285
286void
287LinkStateRoutingTableCalculator::sortQueueByDistance(int* Q,
288 double* dist, int start, int element)
289{
akmhoque157b0a42014-05-13 00:26:37 -0500290 for (int i = start ; i < element ; i++) {
291 for (int j = i + 1; j < element; j++) {
292 if (dist[Q[j]] < dist[Q[i]]) {
akmhoque53353462014-04-22 08:43:45 -0500293 int tempU = Q[j];
294 Q[j] = Q[i];
295 Q[i] = tempU;
296 }
297 }
298 }
299}
300
301int
302LinkStateRoutingTableCalculator::isNotExplored(int* Q,
303 int u, int start, int element)
304{
305 int ret = 0;
akmhoque157b0a42014-05-13 00:26:37 -0500306 for (int i = start; i < element; i++) {
307 if (Q[i] == u) {
akmhoque53353462014-04-22 08:43:45 -0500308 ret = 1;
309 break;
310 }
311 }
312 return ret;
313}
314
315void
316LinkStateRoutingTableCalculator::allocateParent()
317{
318 m_parent = new int[numOfRouter];
319}
320
321void
322LinkStateRoutingTableCalculator::allocateDistance()
323{
324 m_distance = new double[numOfRouter];
325}
326
327void
328LinkStateRoutingTableCalculator::freeParent()
329{
330 delete [] m_parent;
331}
332
333void LinkStateRoutingTableCalculator::freeDistance()
334{
335 delete [] m_distance;
336}
337
338
339
340void
341HypRoutingTableCalculator::calculatePath(Map& pMap,
342 RoutingTable& rt, Nlsr& pnlsr)
343{
344 makeAdjMatrix(pnlsr, pMap);
akmhoque31d1d4b2014-05-05 22:08:14 -0500345 ndn::Name routerName = pnlsr.getConfParameter().getRouterPrefix();
akmhoque53353462014-04-22 08:43:45 -0500346 int sourceRouter = pMap.getMappingNoByRouterName(routerName);
347 int noLink = getNumOfLinkfromAdjMatrix(sourceRouter);
348 setNoLink(noLink);
349 allocateLinks();
350 allocateLinkCosts();
351 getLinksFromAdjMatrix(links, linkCosts, sourceRouter);
akmhoque157b0a42014-05-13 00:26:37 -0500352 for (int i = 0 ; i < numOfRouter ; ++i) {
akmhoque53353462014-04-22 08:43:45 -0500353 int k = 0;
akmhoque157b0a42014-05-13 00:26:37 -0500354 if (i != sourceRouter) {
akmhoque53353462014-04-22 08:43:45 -0500355 allocateLinkFaces();
356 allocateDistanceToNeighbor();
357 allocateDistFromNbrToDest();
akmhoque157b0a42014-05-13 00:26:37 -0500358 for (int j = 0; j < vNoLink; j++) {
akmhoque31d1d4b2014-05-05 22:08:14 -0500359 ndn::Name nextHopRouterName = pMap.getRouterNameByMappingNo(links[j]);
akmhoque157b0a42014-05-13 00:26:37 -0500360 std::string nextHopFaceUri =
361 pnlsr.getAdjacencyList().getAdjacent(nextHopRouterName).getConnectingFaceUri();
akmhoque53353462014-04-22 08:43:45 -0500362 double distToNbr = getHyperbolicDistance(pnlsr, pMap,
363 sourceRouter, links[j]);
364 double distToDestFromNbr = getHyperbolicDistance(pnlsr,
365 pMap, links[j], i);
akmhoque157b0a42014-05-13 00:26:37 -0500366 if (distToDestFromNbr >= 0) {
367 m_linkFaceUris[k] = nextHopFaceUri;
akmhoque53353462014-04-22 08:43:45 -0500368 m_distanceToNeighbor[k] = distToNbr;
369 m_distFromNbrToDest[k] = distToDestFromNbr;
370 k++;
371 }
372 }
373 addHypNextHopsToRoutingTable(pnlsr, pMap, rt, k, i);
374 freeLinkFaces();
375 freeDistanceToNeighbor();
376 freeDistFromNbrToDest();
377 }
378 }
379 freeLinks();
380 freeLinksCosts();
381 freeAdjMatrix();
382}
383
384void
385HypRoutingTableCalculator::addHypNextHopsToRoutingTable(Nlsr& pnlsr, Map& pMap,
386 RoutingTable& rt, int noFaces, int dest)
387{
akmhoque157b0a42014-05-13 00:26:37 -0500388 for (int i = 0 ; i < noFaces ; ++i) {
akmhoque31d1d4b2014-05-05 22:08:14 -0500389 ndn::Name destRouter = pMap.getRouterNameByMappingNo(dest);
akmhoque157b0a42014-05-13 00:26:37 -0500390 NextHop nh(m_linkFaceUris[i], m_distFromNbrToDest[i]);
akmhoque53353462014-04-22 08:43:45 -0500391 rt.addNextHop(destRouter, nh);
akmhoque157b0a42014-05-13 00:26:37 -0500392 if (m_isDryRun) {
akmhoque53353462014-04-22 08:43:45 -0500393 rt.addNextHopToDryTable(destRouter, nh);
394 }
395 }
396}
397
398double
399HypRoutingTableCalculator::getHyperbolicDistance(Nlsr& pnlsr,
400 Map& pMap, int src, int dest)
401{
402 double distance = 0.0;
akmhoque31d1d4b2014-05-05 22:08:14 -0500403 ndn::Name srcRouterKey = pMap.getRouterNameByMappingNo(src);
404 srcRouterKey.append("coordinate");
405 ndn::Name destRouterKey = pMap.getRouterNameByMappingNo(dest);
406 destRouterKey.append("coordinate");
akmhoqueb6450b12014-04-24 00:01:03 -0500407 double srcRadius = (pnlsr.getLsdb().findCoordinateLsa(
408 srcRouterKey))->getCorRadius();
409 double srcTheta = (pnlsr.getLsdb().findCoordinateLsa(
410 srcRouterKey))->getCorTheta();
411 double destRadius = (pnlsr.getLsdb().findCoordinateLsa(
412 destRouterKey))->getCorRadius();
413 double destTheta = (pnlsr.getLsdb().findCoordinateLsa(
414 destRouterKey))->getCorTheta();
akmhoque53353462014-04-22 08:43:45 -0500415 double diffTheta = fabs(srcTheta - destTheta);
akmhoque157b0a42014-05-13 00:26:37 -0500416 if (diffTheta > MATH_PI) {
akmhoque53353462014-04-22 08:43:45 -0500417 diffTheta = 2 * MATH_PI - diffTheta;
418 }
akmhoque157b0a42014-05-13 00:26:37 -0500419 if (srcRadius != -1 && destRadius != -1) {
420 if (diffTheta == 0) {
akmhoque53353462014-04-22 08:43:45 -0500421 distance = fabs(srcRadius - destRadius);
akmhoque157b0a42014-05-13 00:26:37 -0500422 }
423 else {
akmhoque53353462014-04-22 08:43:45 -0500424 distance = acosh((cosh(srcRadius) * cosh(destRadius)) -
425 (sinh(srcRadius) * sinh(destRadius) * cos(diffTheta)));
akmhoque157b0a42014-05-13 00:26:37 -0500426 }
akmhoque53353462014-04-22 08:43:45 -0500427 }
akmhoque157b0a42014-05-13 00:26:37 -0500428 else {
akmhoque53353462014-04-22 08:43:45 -0500429 distance = -1;
430 }
431 return distance;
432}
433
434void
435HypRoutingTableCalculator::allocateLinkFaces()
436{
akmhoque157b0a42014-05-13 00:26:37 -0500437 m_linkFaceUris.reserve(vNoLink);
akmhoque53353462014-04-22 08:43:45 -0500438}
439
440void
441HypRoutingTableCalculator::allocateDistanceToNeighbor()
442{
443 m_distanceToNeighbor = new double[vNoLink];
444}
445
446void
447HypRoutingTableCalculator::allocateDistFromNbrToDest()
448{
449 m_distFromNbrToDest = new double[vNoLink];
450}
451
452void
453HypRoutingTableCalculator::freeLinkFaces()
454{
akmhoque157b0a42014-05-13 00:26:37 -0500455 m_linkFaceUris.clear();
akmhoque53353462014-04-22 08:43:45 -0500456}
457
458void
459HypRoutingTableCalculator::freeDistanceToNeighbor()
460{
461 delete [] m_distanceToNeighbor;
462}
463
464void
465HypRoutingTableCalculator::freeDistFromNbrToDest()
466{
467 delete [] m_distFromNbrToDest;
468}
469
470}//namespace nlsr